int main(int argc, char *argv[]) { int argchar; char* infn = NULL; char* outfn = NULL; char* colname = NULL; char* progname = argv[0]; anbool descending = FALSE; while ((argchar = getopt(argc, argv, OPTIONS)) != -1) switch (argchar) { case 'd': descending = TRUE; break; case '?': case 'h': printHelp(progname); return 0; default: return -1; } if (optind != argc-3) { printHelp(progname); exit(-1); } colname = argv[optind ]; infn = argv[optind+1]; outfn = argv[optind+2]; fits_use_error_system(); return tabsort(infn, outfn, colname, descending); }
int main(int argc, char** args) { pthread_t thread1; pthread_t thread2; pthread_attr_t attr; char* job1 = "job1.axy"; char* job2 = "job2.axy"; fits_use_error_system(); log_init(LOG_VERB); log_set_thread_specific(); logverb("Hello world!\n"); be = engine_new(); engine_parse_config_file(be, "astrometry.cfg"); pthread_mutex_init(&read_job_mutex, NULL); pthread_attr_init(&attr); pthread_create(&thread1, &attr, threadfunc, job1); pthread_create(&thread2, &attr, threadfunc, job2); pthread_join(thread1, NULL); pthread_join(thread2, NULL); pthread_mutex_destroy(&read_job_mutex); engine_free(be); return 0; }
int main(int argc, char *argv[]) { blind_t my_bp; blind_t* bp = &my_bp; solver_t* sp = &(bp->solver); log_init(LOG_MSG); fits_use_error_system(); if (argc == 2 && strcmp(argv[1], "-s") == 0) { log_set_level(LOG_NONE); fprintf(stderr, "premptive silence\n"); } // Read input settings until "run" is encountered; repeat. for (;;) { tic(); blind_init(bp); // must be in this order because init_parameters handily zeros out sp solver_set_default_values(sp); if (read_parameters(bp)) { solver_cleanup(sp); blind_cleanup(bp); break; } if (!blind_parameters_are_sane(bp, sp)) { exit(-1); } if (blind_is_run_obsolete(bp, sp)) { goto clean; } blind_log_run_parameters(bp); blind_run(bp); toc(); if (bp->hit_total_timelimit) break; if (bp->hit_total_cpulimit) break; clean: solver_cleanup(sp); blind_cleanup(bp); } return 0; }
int main(int argc, char** args) { int argchar; char* infn = NULL; char* outfn = NULL; char* progname = args[0]; char* fluxcol = NULL; char* backcol = NULL; anbool ascending = TRUE; int loglvl = LOG_MSG; while ((argchar = getopt (argc, args, OPTIONS)) != -1) switch (argchar) { case 'f': fluxcol = optarg; break; case 'b': backcol = optarg; break; case 'd': ascending = FALSE; break; case 'v': loglvl++; break; case '?': case 'h': printHelp(progname); return 0; default: return -1; } log_init(loglvl); if (optind != argc-2) { printHelp(progname); exit(-1); } infn = args[optind]; outfn = args[optind+1]; fits_use_error_system(); if (resort_xylist(infn, outfn, fluxcol, backcol, ascending)) { ERROR("Failed to re-sorting xylist by FLUX and BACKGROUND"); exit(-1); } return 0; }
int main(int argc, char *argv[]) { int argchar; char* infn = NULL; char* outfn = NULL; char* wcsfn = NULL; char* progname = argv[0]; anbool copydata = FALSE; int loglvl = LOG_MSG; while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case 'v': loglvl++; break; case 'i': infn = optarg; break; case 'o': outfn = optarg; break; case 'w': wcsfn = optarg; break; case 'd': copydata = TRUE; break; case '?': case 'h': printHelp(progname); return 0; default: return -1; } if (!infn || !outfn || !wcsfn) { printHelp(progname); exit(-1); } log_init(loglvl); fits_use_error_system(); if (new_wcs(infn, wcsfn, outfn, copydata)) { ERROR("new_wcs() failed"); exit(-1); } return 0; }
int main(int argc, char *argv[]) { char* progname = argv[0]; int argchar; char* infn; sl* methods = NULL; dl* scales = NULL; int i; int loglvl = LOG_MSG; while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case '?': case 'h': printHelp(progname); return 0; case 'v': loglvl++; break; default: return -1; } if (optind != (argc - 1)) { printHelp(progname); exit(-1); } infn = argv[optind]; log_init(loglvl); fits_use_error_system(); if (fits_guess_scale(infn, &methods, &scales)) exit(-1); for (i=0; i<sl_size(methods); i++) { printf("scale %s %g\n", sl_get(methods, i), dl_get(scales, i)); } sl_free2(methods); dl_free(scales); return 0; }
int main(int argc, char** args) { int c; char* xylsfn = NULL; char* wcsfn = NULL; char* rdlsfn = NULL; char* plotfn = NULL; xylist_t* xyls = NULL; rdlist_t* rdls = NULL; sip_t sip; int i; int W, H; double pixeljitter = 1.0; int loglvl = LOG_MSG; double wcsscale; fits_use_error_system(); while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 'p': plotfn = optarg; break; case 'j': pixeljitter = atof(optarg); break; case 'h': print_help(args[0]); exit(0); case 'r': rdlsfn = optarg; break; case 'x': xylsfn = optarg; break; case 'w': wcsfn = optarg; break; case 'v': loglvl++; break; } } if (optind != argc) { print_help(args[0]); exit(-1); } if (!xylsfn || !wcsfn || !rdlsfn) { print_help(args[0]); exit(-1); } log_init(loglvl); // read WCS. logmsg("Trying to parse SIP header from %s...\n", wcsfn); if (!sip_read_header_file(wcsfn, &sip)) { logmsg("Failed to parse SIP header from %s.\n", wcsfn); } // image W, H W = sip.wcstan.imagew; H = sip.wcstan.imageh; if ((W == 0.0) || (H == 0.0)) { logmsg("WCS file %s didn't contain IMAGEW and IMAGEH headers.\n", wcsfn); // FIXME - use bounds of xylist? exit(-1); } wcsscale = sip_pixel_scale(&sip); logmsg("WCS scale: %g arcsec/pixel\n", wcsscale); // read XYLS. xyls = xylist_open(xylsfn); if (!xyls) { logmsg("Failed to read an xylist from file %s.\n", xylsfn); exit(-1); } // read RDLS. rdls = rdlist_open(rdlsfn); if (!rdls) { logmsg("Failed to read an rdlist from file %s.\n", rdlsfn); exit(-1); } { // (x,y) positions of field stars. double* fieldpix; int Nfield; double* indexpix; starxy_t* xy; rd_t* rd; int Nindex; xy = xylist_read_field(xyls, NULL); if (!xy) { logmsg("Failed to read xyls entries.\n"); exit(-1); } Nfield = starxy_n(xy); fieldpix = starxy_to_xy_array(xy, NULL); logmsg("Found %i field objects\n", Nfield); // Project RDLS into pixel space. rd = rdlist_read_field(rdls, NULL); if (!rd) { logmsg("Failed to read rdls entries.\n"); exit(-1); } Nindex = rd_n(rd); logmsg("Found %i indx objects\n", Nindex); indexpix = malloc(2 * Nindex * sizeof(double)); for (i=0; i<Nindex; i++) { anbool ok; double ra = rd_getra(rd, i); double dec = rd_getdec(rd, i); ok = sip_radec2pixelxy(&sip, ra, dec, indexpix + i*2, indexpix + i*2 + 1); assert(ok); } logmsg("CRPIX is (%g,%g)\n", sip.wcstan.crpix[0], sip.wcstan.crpix[1]); { double* fieldsigma2s = malloc(Nfield * sizeof(double)); int besti; int* theta; double logodds; double Q2, R2; double qc[2]; double gamma; // HACK -- quad radius-squared Q2 = square(100.0); qc[0] = sip.wcstan.crpix[0]; qc[1] = sip.wcstan.crpix[1]; // HACK -- variance growth rate wrt radius. gamma = 1.0; for (i=0; i<Nfield; i++) { R2 = distsq(qc, fieldpix + 2*i, 2); fieldsigma2s[i] = square(pixeljitter) * (1.0 + gamma * R2/Q2); } logodds = verify_star_lists(indexpix, Nindex, fieldpix, fieldsigma2s, Nfield, W*H, 0.25, log(1e-100), log(1e100), &besti, NULL, &theta, NULL); logmsg("Logodds: %g\n", logodds); if (TRUE) { for (i=0; i<Nfield; i++) { if (theta[i] < 0) continue; printf("%g %g %g %g\n", fieldpix[2*i+0], fieldpix[2*i+1], rd_getra(rd, theta[i]), rd_getdec(rd, theta[i])); } } if (plotfn) { plot_args_t pargs; plotimage_t* img; cairo_t* cairo; plotstuff_init(&pargs); pargs.outformat = PLOTSTUFF_FORMAT_PNG; pargs.outfn = plotfn; img = plotstuff_get_config(&pargs, "image"); img->format = PLOTSTUFF_FORMAT_JPG; plot_image_set_filename(img, "1.jpg"); plot_image_setsize(&pargs, img); plotstuff_run_command(&pargs, "image"); cairo = pargs.cairo; // red circles around every field star. cairo_set_color(cairo, "red"); for (i=0; i<Nfield; i++) { cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE, fieldpix[2*i+0], fieldpix[2*i+1], 2.0 * sqrt(fieldsigma2s[i])); cairo_stroke(cairo); } // green crosshairs at every index star. cairo_set_color(cairo, "green"); for (i=0; i<Nindex; i++) { cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR, indexpix[2*i+0], indexpix[2*i+1], 3); cairo_stroke(cairo); } // thick white circles for corresponding field stars. cairo_set_line_width(cairo, 2); for (i=0; i<Nfield; i++) { if (theta[i] < 0) continue; cairo_set_color(cairo, "white"); cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE, fieldpix[2*i+0], fieldpix[2*i+1], 2.0 * sqrt(fieldsigma2s[i])); cairo_stroke(cairo); // thick cyan crosshairs for corresponding index stars. cairo_set_color(cairo, "cyan"); cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR, indexpix[2*theta[i]+0], indexpix[2*theta[i]+1], 3); cairo_stroke(cairo); } plotstuff_output(&pargs); } free(theta); free(fieldsigma2s); } free(fieldpix); free(indexpix); } if (xylist_close(xyls)) { logmsg("Failed to close XYLS file.\n"); } return 0; }
int main(int argc, char *argv[]) { int argchar; char* progname = argv[0]; sl* infns = sl_new(16); char* outfnpat = NULL; char* racol = "RA"; char* deccol = "DEC"; char* tempdir = "/tmp"; anbool gzip = FALSE; sl* cols = sl_new(16); int loglvl = LOG_MSG; int nside = 1; double margin = 0.0; int NHP; double md; char* backref = NULL; fitstable_t* intable; fitstable_t** outtables; char** myargs; int nmyargs; int i; while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case 'b': backref = optarg; break; case 't': tempdir = optarg; break; case 'c': sl_append(cols, optarg); break; case 'g': gzip = TRUE; break; case 'o': outfnpat = optarg; break; case 'r': racol = optarg; break; case 'd': deccol = optarg; break; case 'n': nside = atoi(optarg); break; case 'm': margin = atof(optarg); break; case 'v': loglvl++; break; case '?': fprintf(stderr, "Unknown option `-%c'.\n", optopt); case 'h': printHelp(progname); return 0; default: return -1; } if (sl_size(cols) == 0) { sl_free2(cols); cols = NULL; } nmyargs = argc - optind; myargs = argv + optind; for (i=0; i<nmyargs; i++) sl_append(infns, myargs[i]); if (!sl_size(infns)) { printHelp(progname); printf("Need input filenames!\n"); exit(-1); } log_init(loglvl); fits_use_error_system(); NHP = 12 * nside * nside; logmsg("%i output healpixes\n", NHP); outtables = calloc(NHP, sizeof(fitstable_t*)); assert(outtables); md = deg2dist(margin); /** About the mincaps/maxcaps: These have a center and radius-squared, describing the region inside a small circle on the sphere. The "mincaps" describe the regions that are definitely owned by a single healpix -- ie, more than MARGIN distance from any edge. That is, the mincap is the small circle centered at (0.5, 0.5) in the healpix and with radius = the distance to the closest healpix boundary, MINUS the margin distance. Below, we first check whether a new star is within the "mincap" of any healpix. If so, we stick it in that healpix and continue. Otherwise, we check all the "maxcaps" -- these are the healpixes it could *possibly* be in. We then refine with healpix_within_range_of_xyz. The maxcap distance is the distance to the furthest boundary point, PLUS the margin distance. */ cap_t* mincaps = malloc(NHP * sizeof(cap_t)); cap_t* maxcaps = malloc(NHP * sizeof(cap_t)); for (i=0; i<NHP; i++) { // center double r2; double xyz[3]; double* cxyz; double step = 1e-3; double v; double r2b, r2a; cxyz = mincaps[i].xyz; healpix_to_xyzarr(i, nside, 0.5, 0.5, mincaps[i].xyz); memcpy(maxcaps[i].xyz, cxyz, 3 * sizeof(double)); logverb("Center of HP %i: (%.3f, %.3f, %.3f)\n", i, cxyz[0], cxyz[1], cxyz[2]); // radius-squared: // max is the easy one: max of the four corners (I assume) r2 = 0.0; healpix_to_xyzarr(i, nside, 0.0, 0.0, xyz); logverb(" HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3)); r2 = MAX(r2, distsq(xyz, cxyz, 3)); healpix_to_xyzarr(i, nside, 1.0, 0.0, xyz); logverb(" HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3)); r2 = MAX(r2, distsq(xyz, cxyz, 3)); healpix_to_xyzarr(i, nside, 0.0, 1.0, xyz); logverb(" HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3)); r2 = MAX(r2, distsq(xyz, cxyz, 3)); healpix_to_xyzarr(i, nside, 1.0, 1.0, xyz); logverb(" HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3)); r2 = MAX(r2, distsq(xyz, cxyz, 3)); logverb(" max distsq: %.3f\n", r2); logverb(" margin dist: %.3f\n", md); maxcaps[i].r2 = square(sqrt(r2) + md); logverb(" max cap distsq: %.3f\n", maxcaps[i].r2); r2a = r2; r2 = 1.0; r2b = 0.0; for (v=0; v<=1.0; v+=step) { healpix_to_xyzarr(i, nside, 0.0, v, xyz); r2 = MIN(r2, distsq(xyz, cxyz, 3)); r2b = MAX(r2b, distsq(xyz, cxyz, 3)); healpix_to_xyzarr(i, nside, 1.0, v, xyz); r2 = MIN(r2, distsq(xyz, cxyz, 3)); r2b = MAX(r2b, distsq(xyz, cxyz, 3)); healpix_to_xyzarr(i, nside, v, 0.0, xyz); r2 = MIN(r2, distsq(xyz, cxyz, 3)); r2b = MAX(r2b, distsq(xyz, cxyz, 3)); healpix_to_xyzarr(i, nside, v, 1.0, xyz); r2 = MIN(r2, distsq(xyz, cxyz, 3)); r2b = MAX(r2b, distsq(xyz, cxyz, 3)); } mincaps[i].r2 = square(MAX(0, sqrt(r2) - md)); logverb("\nhealpix %i: min rad %g\n", i, sqrt(r2)); logverb("healpix %i: max rad %g\n", i, sqrt(r2a)); logverb("healpix %i: max rad(b) %g\n", i, sqrt(r2b)); assert(r2a >= r2b); } if (backref) { fitstable_t* tab = fitstable_open_for_writing(backref); int maxlen = 0; char* buf; for (i=0; i<sl_size(infns); i++) { char* infn = sl_get(infns, i); maxlen = MAX(maxlen, strlen(infn)); } fitstable_add_write_column_array(tab, fitscolumn_char_type(), maxlen, "filename", NULL); fitstable_add_write_column(tab, fitscolumn_i16_type(), "index", NULL); if (fitstable_write_primary_header(tab) || fitstable_write_header(tab)) { ERROR("Failed to write header of backref table \"%s\"", backref); exit(-1); } buf = malloc(maxlen+1); assert(buf); for (i=0; i<sl_size(infns); i++) { char* infn = sl_get(infns, i); int16_t ind; memset(buf, 0, maxlen); strcpy(buf, infn); ind = i; if (fitstable_write_row(tab, buf, &ind)) { ERROR("Failed to write row %i of backref table: %s = %i", i, buf, ind); exit(-1); } } if (fitstable_fix_header(tab) || fitstable_close(tab)) { ERROR("Failed to fix header & close backref table"); exit(-1); } logmsg("Wrote backref table %s\n", backref); free(buf); } for (i=0; i<sl_size(infns); i++) { char* infn = sl_get(infns, i); char* originfn = infn; int r, NR; tfits_type any, dubl; il* hps = NULL; bread_t* rowbuf; int R; char* tempfn = NULL; char* padrowdata = NULL; int ii; logmsg("Reading input \"%s\"...\n", infn); if (gzip) { char* cmd; int rtn; tempfn = create_temp_file("hpsplit", tempdir); asprintf_safe(&cmd, "gunzip -cd %s > %s", infn, tempfn); logmsg("Running: \"%s\"\n", cmd); rtn = run_command_get_outputs(cmd, NULL, NULL); if (rtn) { ERROR("Failed to run command: \"%s\"", cmd); exit(-1); } free(cmd); infn = tempfn; } intable = fitstable_open(infn); if (!intable) { ERROR("Couldn't read catalog %s", infn); exit(-1); } NR = fitstable_nrows(intable); logmsg("Got %i rows\n", NR); any = fitscolumn_any_type(); dubl = fitscolumn_double_type(); fitstable_add_read_column_struct(intable, dubl, 1, 0, any, racol, TRUE); fitstable_add_read_column_struct(intable, dubl, 1, sizeof(double), any, deccol, TRUE); fitstable_use_buffered_reading(intable, 2*sizeof(double), 1000); R = fitstable_row_size(intable); rowbuf = buffered_read_new(R, 1000, NR, refill_rowbuffer, intable); if (fitstable_read_extension(intable, 1)) { ERROR("Failed to find RA and DEC columns (called \"%s\" and \"%s\" in the FITS file)", racol, deccol); exit(-1); } for (r=0; r<NR; r++) { int hp = -1; double ra, dec; int j; double* rd; void* rowdata; void* rdata; if (r && ((r % 100000) == 0)) { logmsg("Reading row %i of %i\n", r, NR); } //printf("reading RA,Dec for row %i\n", r); rd = fitstable_next_struct(intable); ra = rd[0]; dec = rd[1]; logverb("row %i: ra,dec %g,%g\n", r, ra, dec); if (margin == 0) { hp = radecdegtohealpix(ra, dec, nside); logverb(" --> healpix %i\n", hp); } else { double xyz[3]; anbool gotit = FALSE; double d2; if (!hps) hps = il_new(4); radecdeg2xyzarr(ra, dec, xyz); for (j=0; j<NHP; j++) { d2 = distsq(xyz, mincaps[j].xyz, 3); if (d2 <= mincaps[j].r2) { logverb(" -> in mincap %i (dist %g vs %g)\n", j, sqrt(d2), sqrt(mincaps[j].r2)); il_append(hps, j); gotit = TRUE; break; } } if (!gotit) { for (j=0; j<NHP; j++) { d2 = distsq(xyz, maxcaps[j].xyz, 3); if (d2 <= maxcaps[j].r2) { logverb(" -> in maxcap %i (dist %g vs %g)\n", j, sqrt(d2), sqrt(maxcaps[j].r2)); if (healpix_within_range_of_xyz(j, nside, xyz, margin)) { logverb(" -> and within range.\n"); il_append(hps, j); } } } } //hps = healpix_rangesearch_radec(ra, dec, margin, nside, hps); logverb(" --> healpixes: ["); for (j=0; j<il_size(hps); j++) logverb(" %i", il_get(hps, j)); logverb(" ]\n"); } //printf("Reading rowdata for row %i\n", r); rowdata = buffered_read(rowbuf); assert(rowdata); j=0; while (1) { if (hps) { if (j >= il_size(hps)) break; hp = il_get(hps, j); j++; } assert(hp < NHP); assert(hp >= 0); if (!outtables[hp]) { char* outfn; fitstable_t* out; // MEMLEAK the output filename. You'll live. asprintf_safe(&outfn, outfnpat, hp); logmsg("Opening output file \"%s\"...\n", outfn); out = fitstable_open_for_writing(outfn); if (!out) { ERROR("Failed to open output table \"%s\"", outfn); exit(-1); } // Set the output table structure. if (cols) { fitstable_add_fits_columns_as_struct3(intable, out, cols, 0); } else fitstable_add_fits_columns_as_struct2(intable, out); if (backref) { tfits_type i16type; tfits_type i32type; // R = fitstable_row_size(intable); int off = R; i16type = fitscolumn_i16_type(); i32type = fitscolumn_i32_type(); fitstable_add_read_column_struct(out, i16type, 1, off, i16type, "backref_file", TRUE); off += sizeof(int16_t); fitstable_add_read_column_struct(out, i32type, 1, off, i32type, "backref_index", TRUE); } //printf("Output table:\n"); //fitstable_print_columns(out); if (fitstable_write_primary_header(out) || fitstable_write_header(out)) { ERROR("Failed to write output file headers for \"%s\"", outfn); exit(-1); } outtables[hp] = out; } if (backref) { int16_t brfile; int32_t brind; if (!padrowdata) { padrowdata = malloc(R + sizeof(int16_t) + sizeof(int32_t)); assert(padrowdata); } // convert to FITS endian brfile = htons(i); brind = htonl(r); // add backref data to rowdata memcpy(padrowdata, rowdata, R); memcpy(padrowdata + R, &brfile, sizeof(int16_t)); memcpy(padrowdata + R + sizeof(int16_t), &brind, sizeof(int32_t)); rdata = padrowdata; } else { rdata = rowdata; } if (cols) { if (fitstable_write_struct_noflip(outtables[hp], rdata)) { ERROR("Failed to copy a row of data from input table \"%s\" to output healpix %i", infn, hp); } } else { if (fitstable_write_row_data(outtables[hp], rdata)) { ERROR("Failed to copy a row of data from input table \"%s\" to output healpix %i", infn, hp); } } if (!hps) break; } if (hps) il_remove_all(hps); } buffered_read_free(rowbuf); // wack... buffered_read_free() just frees its internal buffer, // not the "rowbuf" struct itself. // who wrote this crazy code? Oh, me of 5 years ago. Jerk. free(rowbuf); fitstable_close(intable); il_free(hps); if (tempfn) { logverb("Removing temp file %s\n", tempfn); if (unlink(tempfn)) { SYSERROR("Failed to unlink() temp file \"%s\"", tempfn); } tempfn = NULL; } // fix headers so that the files are valid at this point. for (ii=0; ii<NHP; ii++) { if (!outtables[ii]) continue; off_t offset = ftello(outtables[ii]->fid); if (fitstable_fix_header(outtables[ii])) { ERROR("Failed to fix header for healpix %i after reading input file \"%s\"", ii, originfn); exit(-1); } fseeko(outtables[ii]->fid, offset, SEEK_SET); } if (padrowdata) { free(padrowdata); padrowdata = NULL; } } for (i=0; i<NHP; i++) { if (!outtables[i]) continue; if (fitstable_fix_header(outtables[i]) || fitstable_fix_primary_header(outtables[i]) || fitstable_close(outtables[i])) { ERROR("Failed to close output table for healpix %i", i); exit(-1); } } free(outtables); sl_free2(infns); sl_free2(cols); free(mincaps); free(maxcaps); return 0; }
int main(int argc, char *args[]) { int argchar; char* progname = args[0]; plot_args_t pargs; plotxy_t* xy; plotimage_t* img; int loglvl = LOG_MSG; // log errors to stderr, not stdout. errors_log_to(stderr); plotstuff_init(&pargs); pargs.fout = stdout; pargs.outformat = PLOTSTUFF_FORMAT_PNG; xy = plotstuff_get_config(&pargs, "xy"); img = plotstuff_get_config(&pargs, "image"); assert(xy); assert(img); plotstuff_set_color(&pargs, "white"); plotstuff_set_bgcolor(&pargs, "black"); img->format = PLOTSTUFF_FORMAT_PPM; while ((argchar = getopt(argc, args, OPTIONS)) != -1) switch (argchar) { case 'v': loglvl++; break; case 'C': plotstuff_set_color(&pargs, optarg); break; case 'b': plotstuff_set_bgcolor(&pargs, "optarg"); break; case 'o': pargs.outfn = optarg; break; case 'X': plot_xy_set_xcol(xy, optarg); break; case 'Y': plot_xy_set_ycol(xy, optarg); break; case 'P': pargs.outformat = PLOTSTUFF_FORMAT_PPM; break; case 'J': pargs.outformat = PLOTSTUFF_FORMAT_PDF; break; case 'p': img->format = PLOTSTUFF_FORMAT_PNG; break; case 'I': plot_image_set_filename(img, optarg); break; case 'S': xy->scale = atof(optarg); break; case 'i': plot_xy_set_filename(xy, optarg); break; case 'x': xy->xoff = atof(optarg); break; case 'y': xy->yoff = atof(optarg); break; case 'W': pargs.W = atoi(optarg); break; case 'H': pargs.H = atoi(optarg); break; case 'n': xy->firstobj = atoi(optarg); break; case 'N': xy->nobjs = atoi(optarg); break; case 'e': xy->ext = atoi(optarg); break; case 'r': pargs.markersize = atof(optarg); break; case 'w': pargs.lw = atof(optarg); break; case 's': plotstuff_set_marker(&pargs, optarg); break; case 'h': printHelp(progname); exit(0); case '?': default: printHelp(progname); exit(-1); } if (optind != argc) { printHelp(progname); exit(-1); } if (!xy->fn) { printHelp(progname); exit(-1); } log_init(loglvl); log_to(stderr); fits_use_error_system(); if (img->fn) { if (plot_image_setsize(&pargs, img)) { ERROR("Failed to set plot size from image"); exit(-1); } plotstuff_run_command(&pargs, "image"); } else { if (pargs.W == 0 || pargs.H == 0) { if (plot_xy_setsize(&pargs, xy)) { ERROR("Failed to set plot size from xylist"); exit(-1); } } } plotstuff_run_command(&pargs, "xy"); plotstuff_output(&pargs); plotstuff_free(&pargs); return 0; }
int main(int argc, char *argv[]) { int argchar; char* infn = NULL; char* outfn = NULL; anbool tostdout = FALSE; FILE* fin = NULL; FILE* fout = NULL; il* exts; int i; char* progname = argv[0]; anbool inblocks = FALSE; anbool inmegs = FALSE; int allexts = 0; int Next = -1; anbool dataonly = FALSE; anbool headeronly = FALSE; anqfits_t* anq = NULL; int loglvl = LOG_MSG; exts = il_new(16); while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case 'v': loglvl++; break; case 'D': dataonly = TRUE; break; case 'H': headeronly = TRUE; break; case 'a': allexts = 1; break; case 'b': inblocks = TRUE; break; case 'M': inmegs = TRUE; break; case 'e': il_append(exts, atoi(optarg)); break; case 'i': infn = optarg; break; case 'o': outfn = optarg; break; case '?': case 'h': printHelp(progname); return 0; default: return -1; } if (headeronly && dataonly) { fprintf(stderr, "Can't write data blocks only AND header blocks only!\n"); exit(-1); } if (inblocks && inmegs) { fprintf(stderr, "Can't write sizes in FITS blocks and megabytes.\n"); exit(-1); } fits_use_error_system(); log_init(loglvl); log_to(stderr); errors_log_to(stderr); if (infn) { anq = anqfits_open(infn); if (!anq) { ERROR("Failed to open input file \"%s\"", infn); exit(-1); } Next = anqfits_n_ext(anq); fprintf(stderr, "File %s contains %i FITS extensions.\n", infn, Next); } if (infn && !outfn) { for (i=0; i<Next; i++) { off_t hdrstart, hdrlen, datastart, datalen; hdrstart = anqfits_header_start(anq, i); hdrlen = anqfits_header_size(anq, i); datastart = anqfits_data_start(anq, i); datalen = anqfits_data_size(anq, i); if (inblocks) { off_t block = (off_t)FITS_BLOCK_SIZE; fprintf(stderr, "Extension %i : header start %zu , length %zu ; data start %zu , length %zu blocks.\n", i, (size_t)(hdrstart / block), (size_t)(hdrlen / block), (size_t)(datastart / block), (size_t)(datalen / block)); } else if (inmegs) { off_t meg = 1024*1024; fprintf(stderr, "Extension %i : header start %zu , length %zu ; data start %zu , length %zu megabytes.\n", i, (size_t)(hdrstart/meg), (size_t)(hdrlen/meg), (size_t)(datastart/meg), (size_t)(datalen/meg)); } else { fprintf(stderr, "Extension %i : header start %zu , length %zu ; data start %zu , length %zu .\n", i, (size_t)hdrstart, (size_t)hdrlen, (size_t)datastart, (size_t)datalen); } } anqfits_close(anq); exit(0); } if (!infn || !outfn || !(il_size(exts) || allexts)) { printHelp(progname); exit(-1); } if (!strcmp(outfn, "-")) { tostdout = TRUE; if (allexts) { fprintf(stderr, "Specify all extensions (-a) and outputting to stdout (-o -) doesn't make much sense...\n"); exit(-1); } } if (infn) { fin = fopen(infn, "rb"); if (!fin) { fprintf(stderr, "Failed to open input file %s: %s\n", infn, strerror(errno)); exit(-1); } } if (tostdout) fout = stdout; else { if (allexts) for (i=0; i<Next; i++) il_append(exts, i); else { // open the (single) output file. fout = fopen(outfn, "wb"); if (!fout) { fprintf(stderr, "Failed to open output file %s: %s\n", outfn, strerror(errno)); exit(-1); } } } for (i=0; i<il_size(exts); i++) { off_t hdrstart, hdrlen, datastart, datalen; int ext = il_get(exts, i); if (allexts) { char fn[256]; snprintf(fn, sizeof(fn), outfn, ext); fout = fopen(fn, "wb"); if (!fout) { fprintf(stderr, "Failed to open output file %s: %s\n", fn, strerror(errno)); exit(-1); } } hdrstart = anqfits_header_start(anq, ext); hdrlen = anqfits_header_size(anq, ext); datastart = anqfits_data_start(anq, ext); datalen = anqfits_data_size(anq, ext); if (inblocks) { off_t block = (off_t)FITS_BLOCK_SIZE; fprintf(stderr, "Writing extension %i : header start %zu , length %zu ; data start %zu , length %zu blocks.\n", ext, (size_t)(hdrstart / block), (size_t)(hdrlen / block), (size_t)(datastart / block), (size_t)(datalen / block)); } else if (inmegs) { off_t meg = 1024*1024; fprintf(stderr, "Writing extension %i : header start %zu , length %zu ; data start %zu , length %zu megabytes.\n", ext, (size_t)(hdrstart/meg), (size_t)(hdrlen/meg), (size_t)(datastart/meg), (size_t)(datalen/meg)); } else { fprintf(stderr, "Writing extension %i : header start %zu , length %zu ; data start %zu , length %zu .\n", ext, (size_t)hdrstart, (size_t)hdrlen, (size_t)datastart, (size_t)datalen); } if (hdrlen && !dataonly) { if (pipe_file_offset(fin, hdrstart, hdrlen, fout)) { fprintf(stderr, "Failed to write header for extension %i: %s\n", ext, strerror(errno)); exit(-1); } } if (datalen && !headeronly) { if (pipe_file_offset(fin, datastart, datalen, fout)) { fprintf(stderr, "Failed to write data for extension %i: %s\n", ext, strerror(errno)); exit(-1); } } if (allexts) if (fclose(fout)) { fprintf(stderr, "Failed to close output file: %s\n", strerror(errno)); exit(-1); } } fclose(fin); if (!allexts && !tostdout) fclose(fout); il_free(exts); anqfits_close(anq); return 0; }
int main(int argc, char** args) { int c; char* xylsfn = NULL; char* rdlsfn = NULL; char* corrfn = NULL; char* outfn = NULL; char* xcol = NULL; char* ycol = NULL; char* rcol = NULL; char* dcol = NULL; xylist_t* xyls = NULL; rdlist_t* rdls = NULL; rd_t rd; starxy_t xy; int fieldnum = 1; int N; double* fieldxy = NULL; double* xyz = NULL; sip_t wcs; int rtn = -1; int loglvl = LOG_MSG; int siporder = 0; int W=0, H=0; anbool crpix_center = FALSE; int i; int doshift = 1; fits_use_error_system(); while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 'h': print_help(args[0]); exit(0); case 'W': W = atoi(optarg); break; case 'H': H = atoi(optarg); break; case 'C': crpix_center = TRUE; break; case 's': siporder = atoi(optarg); break; case 'c': corrfn = optarg; break; case 'r': rdlsfn = optarg; break; case 'R': rcol = optarg; break; case 'D': dcol = optarg; break; case 'x': xylsfn = optarg; break; case 'X': xcol = optarg; break; case 'Y': ycol = optarg; break; case 'o': outfn = optarg; break; case 'v': loglvl++; break; } } if (optind != argc) { print_help(args[0]); exit(-1); } if (! ((xylsfn && rdlsfn) || corrfn) || !outfn) { print_help(args[0]); exit(-1); } log_init(loglvl); if (corrfn) { xylsfn = corrfn; rdlsfn = corrfn; if (!xcol) xcol = "FIELD_X"; if (!ycol) ycol = "FIELD_Y"; if (!rcol) rcol = "INDEX_RA"; if (!dcol) dcol = "INDEX_DEC"; } // read XYLS. xyls = xylist_open(xylsfn); if (!xyls) { ERROR("Failed to read an xylist from file %s", xylsfn); goto bailout; } xylist_set_include_flux(xyls, FALSE); xylist_set_include_background(xyls, FALSE); if (xcol) xylist_set_xname(xyls, xcol); if (ycol) xylist_set_yname(xyls, ycol); // read RDLS. rdls = rdlist_open(rdlsfn); if (!rdls) { ERROR("Failed to read an RA,Dec list from file %s", rdlsfn); goto bailout; } if (rcol) rdlist_set_raname(rdls, rcol); if (dcol) rdlist_set_decname(rdls, dcol); if (!xylist_read_field_num(xyls, fieldnum, &xy)) { ERROR("Failed to read xyls file %s, field %i", xylsfn, fieldnum); goto bailout; } if (!rdlist_read_field_num(rdls, fieldnum, &rd)) { ERROR("Failed to read rdls field %i", fieldnum); goto bailout; } N = starxy_n(&xy); if (rd_n(&rd) != N) { ERROR("X,Y list and RA,Dec list must have the same number of entries, " "but found %i vs %i", N, rd_n(&rd)); goto bailout; } logverb("Read %i points from %s and %s\n", N, rdlsfn, xylsfn); xyz = (double*)malloc(sizeof(double) * 3 * N); if (!xyz) { ERROR("Failed to allocate %i xyz coords", N); goto bailout; } radecdeg2xyzarrmany(rd.ra, rd.dec, xyz, N); fieldxy = starxy_to_xy_array(&xy, NULL); if (!fieldxy) { ERROR("Failed to allocate %i xy coords", N); goto bailout; } logverb("Fitting WCS\n"); if (siporder == 0) { if (fit_tan_wcs(xyz, fieldxy, N, &(wcs.wcstan), NULL)) { ERROR("Failed to fit for TAN WCS"); goto bailout; } } else { if (W == 0) { for (i=0; i<N; i++) { W = MAX(W, (int)ceil(fieldxy[2*i + 0])); } } if (H == 0) { for (i=0; i<N; i++) { H = MAX(H, (int)ceil(fieldxy[2*i + 1])); } } logverb("Image size = %i x %i pix\n", W, H); fit_sip_wcs_2(xyz, fieldxy, NULL, N, siporder, siporder+1, W, H, crpix_center, NULL, doshift, &wcs); } if (siporder <= 1) { if (tan_write_to_file(&(wcs.wcstan), outfn)) { ERROR("Failed to write TAN WCS header to file \"%s\"", outfn); goto bailout; } } else { if (sip_write_to_file(&wcs, outfn)) { ERROR("Failed to write SIP WCS header to file \"%s\"", outfn); goto bailout; } } logverb("Wrote WCS to %s\n", outfn); starxy_free_data(&xy); rd_free_data(&rd); rtn = 0; bailout: if (rdls) rdlist_close(rdls); if (xyls) xylist_close(xyls); if (fieldxy) free(fieldxy); if (xyz) free(xyz); return rtn; }
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 main(int argc, char** args) { int c; char* inwcsfn = NULL; char* outwcsfn = NULL; char* infitsfn = NULL; char* outfitsfn = NULL; int inwcsext = 0; int inimgext = 0; int outwcsext = 0; int Lorder = 0; int zinf; while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 'h': print_help(args[0]); exit(0); case 'w': inwcsfn = optarg; break; case 'e': inwcsext = atoi(optarg); break; case 'E': inimgext = atoi(optarg); break; case 'x': outwcsext = atoi(optarg); break; case 'L': Lorder = atoi(optarg); break; case 'z': zinf = 1; break; } } log_init(LOG_MSG); fits_use_error_system(); if (optind != argc - 3) { print_help(args[0]); exit(-1); } infitsfn = args[optind+0]; outwcsfn = args[optind+1]; outfitsfn = args[optind+2]; if (!inwcsfn) inwcsfn = infitsfn; if (resample_wcs_files(infitsfn, inimgext, inwcsfn, inwcsext, outwcsfn, outwcsext, outfitsfn, Lorder, zinf)) { ERROR("Failed to resample image"); exit(-1); } return 0; }
int main(int argc, char** args) { int argchar; char* progname = args[0]; char* outfn = NULL; char* outwcsfn = NULL; int outwcsext = 0; anwcs_t* outwcs; sl* inimgfns = sl_new(16); sl* inwcsfns = sl_new(16); sl* inwtfns = sl_new(16); il* inimgexts = il_new(16); il* inwcsexts = il_new(16); il* inwtexts = il_new(16); int i; int loglvl = LOG_MSG; int order = 3; coadd_t* coadd; lanczos_args_t largs; double sigma = 0.0; anbool nearest = FALSE; anbool divweight = FALSE; int plane = 0; while ((argchar = getopt(argc, args, OPTIONS)) != -1) switch (argchar) { case '?': case 'h': printHelp(progname); exit(0); case 'D': divweight = TRUE; break; case 'p': plane = atoi(optarg); break; case 'N': nearest = TRUE; break; case 's': sigma = atof(optarg); break; case 'v': loglvl++; break; case 'e': outwcsext = atoi(optarg); break; case 'w': outwcsfn = optarg; break; case 'o': outfn = optarg; break; case 'O': order = atoi(optarg); break; } log_init(loglvl); fits_use_error_system(); args += optind; argc -= optind; if (argc == 0 || argc % 6) { printHelp(progname); exit(-1); } for (i=0; i<argc/6; i++) { sl_append(inimgfns, args[6*i+0]); il_append(inimgexts, atoi(args[6*i+1])); sl_append(inwtfns, args[6*i+2]); il_append(inwtexts, atoi(args[6*i+3])); sl_append(inwcsfns, args[6*i+4]); il_append(inwcsexts, atoi(args[6*i+5])); } logmsg("Reading output WCS file %s\n", outwcsfn); outwcs = anwcs_open(outwcsfn, outwcsext); if (!outwcs) { ERROR("Failed to read WCS from file: %s ext %i\n", outwcsfn, outwcsext); exit(-1); } logmsg("Output image will be %i x %i\n", (int)anwcs_imagew(outwcs), (int)anwcs_imageh(outwcs)); coadd = coadd_new(anwcs_imagew(outwcs), anwcs_imageh(outwcs)); coadd->wcs = outwcs; if (nearest) { coadd->resample_func = nearest_resample_f; coadd->resample_token = NULL; } else { coadd->resample_func = lanczos_resample_f; largs.order = order; coadd->resample_token = &largs; } for (i=0; i<sl_size(inimgfns); i++) { anqfits_t* anq; anqfits_t* wanq; float* img; float* wt = NULL; anwcs_t* inwcs; char* fn; int ext; float overallwt = 1.0; int W, H; fn = sl_get(inimgfns, i); ext = il_get(inimgexts, i); logmsg("Reading input image \"%s\" ext %i\n", fn, ext); anq = anqfits_open(fn); if (!anq) { ERROR("Failed to open file \"%s\"\n", fn); exit(-1); } img = anqfits_readpix(anq, ext, 0, 0, 0, 0, plane, PTYPE_FLOAT, NULL, &W, &H); if (!img) { ERROR("Failed to read image from ext %i of %s\n", ext, fn); exit(-1); } anqfits_close(anq); logmsg("Read image: %i x %i.\n", W, H); if (sigma > 0.0) { int k0, nk; float* kernel; logmsg("Smoothing by Gaussian with sigma=%g\n", sigma); kernel = convolve_get_gaussian_kernel_f(sigma, 4, &k0, &nk); convolve_separable_f(img, W, H, kernel, k0, nk, img, NULL); free(kernel); } fn = sl_get(inwcsfns, i); ext = il_get(inwcsexts, i); logmsg("Reading input WCS file \"%s\" ext %i\n", fn, ext); inwcs = anwcs_open(fn, ext); if (!inwcs) { ERROR("Failed to read WCS from file \"%s\" ext %i\n", fn, ext); exit(-1); } if (anwcs_pixel_scale(inwcs) == 0) { ERROR("Pixel scale from the WCS file is zero. Usually this means the image has no valid WCS header.\n"); exit(-1); } if (anwcs_imagew(inwcs) != W || anwcs_imageh(inwcs) != H) { ERROR("Size mismatch between image and WCS!"); exit(-1); } fn = sl_get(inwtfns, i); ext = il_get(inwtexts, i); if (streq(fn, "none")) { logmsg("Not using weight image.\n"); wt = NULL; } else if (file_exists(fn)) { logmsg("Reading input weight image \"%s\" ext %i\n", fn, ext); wanq = anqfits_open(fn); if (!wanq) { ERROR("Failed to open file \"%s\"\n", fn); exit(-1); } int wtW, wtH; wt = anqfits_readpix(anq, ext, 0, 0, 0, 0, 0, PTYPE_FLOAT, NULL, &wtW, &wtH); if (!wt) { ERROR("Failed to read image from ext %i of %s\n", ext, fn); exit(-1); } anqfits_close(wanq); logmsg("Read image: %i x %i.\n", wtW, wtH); if (wtW != W || wtH != H) { ERROR("Size mismatch between image and weight!"); exit(-1); } } else { char* endp; overallwt = strtod(fn, &endp); if (endp == fn) { ERROR("Weight: \"%s\" is neither a file nor a double.\n", fn); exit(-1); } logmsg("Parsed weight value \"%g\"\n", overallwt); } if (divweight && wt) { int j; logmsg("Dividing image by weight image...\n"); for (j=0; j<(W*H); j++) img[j] /= wt[j]; } coadd_add_image(coadd, img, wt, overallwt, inwcs); anwcs_free(inwcs); free(img); if (wt) free(wt); } // logmsg("Writing output: %s\n", outfn); coadd_divide_by_weight(coadd, 0.0); /* if (fits_write_float_image_hdr(coadd->img, coadd->W, coadd->H, outfn)) { ERROR("Failed to write output image %s", outfn); exit(-1); } */ /* if (fits_write_float_image(coadd->img, coadd->W, coadd->H, outfn)) { ERROR("Failed to write output image %s", outfn); exit(-1); } */ { qfitsdumper qoutimg; qfits_header* hdr; hdr = anqfits_get_header2(outwcsfn, outwcsext); if (!hdr) { ERROR("Failed to read WCS file \"%s\" ext %i\n", outwcsfn, outwcsext); exit(-1); } fits_header_mod_int(hdr, "NAXIS", 2, NULL); fits_header_set_int(hdr, "NAXIS1", coadd->W, "image width"); fits_header_set_int(hdr, "NAXIS2", coadd->H, "image height"); fits_header_modf(hdr, "BITPIX", "-32", "32-bit floats"); memset(&qoutimg, 0, sizeof(qoutimg)); qoutimg.filename = outfn; qoutimg.npix = coadd->W * coadd->H; qoutimg.fbuf = coadd->img; qoutimg.ptype = PTYPE_FLOAT; qoutimg.out_ptype = BPP_IEEE_FLOAT; if (fits_write_header_and_image(NULL, &qoutimg, coadd->W)) { ERROR("Failed to write FITS image to file \"%s\"", outfn); exit(-1); } qfits_header_destroy(hdr); } coadd_free(coadd); sl_free2(inimgfns); sl_free2(inwcsfns); sl_free2(inwtfns); il_free(inimgexts); il_free(inwcsexts); il_free(inwtexts); anwcs_free(outwcs); return 0; }
int main(int argc, char *argv[]) { int argchar; char* infn = NULL; char* outfn = NULL; FILE* fout; anbool tostdout = FALSE; anqfits_t* anq; int W, H; qfits_header* hdr; const anqfits_image_t* animg; float* img; int loglvl = LOG_MSG; int scale = 2; int winw; int winh; int plane; int out_bitpix = -32; float* outimg; int outw, outh; int edge = EDGE_TRUNCATE; int ext = 0; int npixout = 0; while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case 'v': loglvl++; break; case 's': scale = atoi(optarg); break; case 'e': ext = atoi(optarg); break; case '?': case 'h': printHelp(argv[0]); return 0; default: return -1; } log_init(loglvl); log_to(stderr); errors_log_to(stderr); fits_use_error_system(); if (argc - optind != 2) { logerr("Need two arguments: input and output files.\n"); printHelp(argv[0]); exit(-1); } infn = argv[optind]; outfn = argv[optind+1]; if (streq(outfn, "-")) { tostdout = TRUE; fout = stdout; } else { fout = fopen(outfn, "wb"); if (!fout) { SYSERROR("Failed to open output file \"%s\"", outfn); exit(-1); } } anq = anqfits_open(infn); if (!anq) { ERROR("Failed to open input file \"%s\"", infn); exit(-1); } animg = anqfits_get_image_const(anq, ext); W = (int)animg->width; H = (int)animg->height; if (!animg) { ERROR("Failde to read image from \"%s\"", infn); exit(-1); } /* if (tostdout) dump.filename = "STDOUT"; else dump.filename = outfn; dump.ptype = PTYPE_FLOAT; dump.out_ptype = out_bitpix; */ get_output_image_size(W % scale, H % scale, scale, edge, &outw, &outh); outw += (W / scale); outh += (H / scale); hdr = qfits_header_default(); fits_header_add_int(hdr, "BITPIX", out_bitpix, "bits per pixel"); if (animg->planes > 1) fits_header_add_int(hdr, "NAXIS", 3, "number of axes"); else fits_header_add_int(hdr, "NAXIS", 2, "number of axes"); fits_header_add_int(hdr, "NAXIS1", outw, "image width"); fits_header_add_int(hdr, "NAXIS2", outh, "image height"); if (animg->planes > 1) fits_header_add_int(hdr, "NAXIS3", animg->planes, "number of planes"); if (qfits_header_dump(hdr, fout)) { ERROR("Failed to write FITS header to \"%s\"", outfn); exit(-1); } qfits_header_destroy(hdr); winw = W; winh = (int)ceil(ceil(1024*1024 / (float)winw) / (float)scale) * scale; outimg = malloc((int)ceil(winw/scale)*(int)ceil(winh/scale) * sizeof(float)); logmsg("Image is %i x %i x %i\n", W, H, (int)animg->planes); logmsg("Output will be %i x %i x %i\n", outw, outh, (int)animg->planes); logverb("Reading in blocks of %i x %i\n", winw, winh); for (plane=0; plane<animg->planes; plane++) { int bx, by; int nx, ny; for (by=0; by<(int)ceil(H / (float)winh); by++) { for (bx=0; bx<(int)ceil(W / (float)winw); bx++) { int i; int lox, loy, hix, hiy, outw, outh; nx = MIN(winw, W - bx*winw); ny = MIN(winh, H - by*winh); lox = bx*winw; loy = by*winh; hix = lox + nx; hiy = loy + ny; logverb(" reading %i,%i + %i,%i\n", lox, loy, nx, ny); img = anqfits_readpix(anq, ext, lox, hix, loy, hiy, plane, PTYPE_FLOAT, NULL, &W, &H); if (!img) { ERROR("Failed to load pixel window: x=[%i, %i), y=[%i,%i), plane %i\n", lox, hix, loy, hiy, plane); exit(-1); } average_image_f(img, nx, ny, scale, edge, &outw, &outh, outimg); free(img); logverb(" writing %i x %i\n", outw, outh); if (outw * outh == 0) continue; for (i=0; i<outw*outh; i++) { int nbytes = abs(out_bitpix)/8; char buf[nbytes]; if (qfits_pixel_ctofits(PTYPE_FLOAT, out_bitpix, outimg + i, buf)) { ERROR("Failed to convert pixel to FITS type\n"); exit(-1); } if (fwrite(buf, nbytes, 1, fout) != 1) { ERROR("Failed to write pixels\n"); exit(-1); } } npixout += outw*outh; } } } free(outimg); anqfits_close(anq); if (tostdout) { // pad. int N; char pad[2880]; N = (npixout * (abs(out_bitpix) / 8)) % 2880; memset(pad, 0, 2880); fwrite(pad, 1, N, fout); } else { if (fits_pad_file(fout)) { ERROR("Failed to pad output file"); exit(-1); } if (fclose(fout)) { SYSERROR("Failed to close output file"); exit(-1); } } logverb("Done!\n"); return 0; }
int main(int argc, char** args) { int c; char* wcsfn = NULL; char* outfn = NULL; char* infn = NULL; sip_t sip; double scale = 1.0; anbool pngformat = TRUE; char* hdpath = NULL; anbool HD = FALSE; cairos_t thecairos; cairos_t* cairos = &thecairos; cairo_surface_t* target = NULL; cairo_t* cairot = NULL; cairo_surface_t* surfbg = NULL; cairo_t* cairobg = NULL; cairo_surface_t* surfshapes = NULL; cairo_t* cairoshapes = NULL; cairo_surface_t* surfshapesmask = NULL; cairo_t* cairoshapesmask = NULL; cairo_surface_t* surffg = NULL; cairo_t* cairo = NULL; double lw = 2.0; // circle linewidth. double cw = 2.0; double ngc_fraction = 0.02; // NGC linewidth double nw = 2.0; // leave a gap short of connecting the points. double endgap = 5.0; // circle radius. double crad = endgap; double fontsize = 14.0; double label_offset = 15.0; int W = 0, H = 0; unsigned char* img = NULL; anbool NGC = FALSE, constell = FALSE; anbool bright = FALSE; anbool common_only = FALSE; anbool print_common_only = FALSE; int Nbright = 0; double ra, dec, px, py; int i, N; anbool justlist = FALSE; anbool only_messier = FALSE; anbool grid = FALSE; double gridspacing = 0.0; double gridcolor[3] = { 0.2, 0.2, 0.2 }; int loglvl = LOG_MSG; char halign = 'L'; char valign = 'C'; sl* json = NULL; anbool whitetext = FALSE; while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 'V': valign = optarg[0]; break; case 'O': halign = optarg[0]; break; case 'F': ngc_fraction = atof(optarg); break; case 'h': print_help(args[0]); exit(0); case 'J': json = sl_new(4); break; case 'G': gridspacing = atof(optarg); break; case 'g': { char *tail = NULL; gridcolor[0] = strtod(optarg,&tail); if (*tail) { tail++; gridcolor[1] = strtod(tail,&tail); } if (*tail) { tail++; gridcolor[2] = strtod(tail,&tail); } } break; case 'D': HD = TRUE; break; case 'd': hdpath = optarg; break; case 'M': only_messier = TRUE; break; case 'n': nw = atof(optarg); break; case 'f': fontsize = atof(optarg); break; case 'L': justlist = TRUE; outfn = NULL; break; case 'x': whitetext = TRUE; break; case 'v': loglvl++; break; break; case 'j': print_common_only = TRUE; break; case 'c': common_only = TRUE; break; case 'b': Nbright = atoi(optarg); break; case 'B': bright = TRUE; break; case 'N': NGC = TRUE; break; case 'C': constell = TRUE; break; case 'p': pngformat = FALSE; break; case 's': scale = atof(optarg); break; case 'o': outfn = optarg; break; case 'i': infn = optarg; break; case 'w': wcsfn = optarg; break; case 'W': W = atoi(optarg); break; case 'H': H = atoi(optarg); break; } } log_init(loglvl); log_to(stderr); fits_use_error_system(); if (optind != argc) { print_help(args[0]); exit(-1); } if (!(outfn || justlist) || !wcsfn) { logerr("Need (-o or -L) and -w args.\n"); print_help(args[0]); exit(-1); } // read WCS. logverb("Trying to parse SIP/TAN header from %s...\n", wcsfn); if (!file_exists(wcsfn)) { ERROR("No such file: \"%s\"", wcsfn); exit(-1); } if (sip_read_header_file(wcsfn, &sip)) { logverb("Got SIP header.\n"); } else { ERROR("Failed to parse SIP/TAN header from %s", wcsfn); exit(-1); } if (!(NGC || constell || bright || HD || grid)) { logerr("Neither constellations, bright stars, HD nor NGC/IC overlays selected!\n"); print_help(args[0]); exit(-1); } if (gridspacing > 0.0) grid = TRUE; // adjust for scaling... lw /= scale; cw /= scale; nw /= scale; crad /= scale; endgap /= scale; fontsize /= scale; label_offset /= scale; if (!W || !H) { W = sip.wcstan.imagew; H = sip.wcstan.imageh; } if (!(infn || (W && H))) { logerr("Image width/height unspecified, and no input image given.\n"); exit(-1); } if (infn) { cairoutils_fake_ppm_init(); img = cairoutils_read_ppm(infn, &W, &H); if (!img) { ERROR("Failed to read input image %s", infn); exit(-1); } cairoutils_rgba_to_argb32(img, W, H); } else if (!justlist) { // Allocate a black image. img = calloc(4 * W * H, 1); if (!img) { SYSERROR("Failed to allocate a blank image on which to plot!"); exit(-1); } } if (HD && !hdpath) { logerr("If you specify -D (plot Henry Draper objs), you also have to give -d (path to Henry Draper catalog)\n"); exit(-1); } if (!justlist) { /* Cairo layers: -background: surfbg / cairobg --> gets drawn first, in black, masked by surfshapesmask -shapes: surfshapes / cairoshapes --> gets drawn second, masked by surfshapesmask -foreground/text: surffg / cairo --> gets drawn last. */ surffg = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, W, H); cairo = cairo_create(surffg); cairo_set_line_join(cairo, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairo, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairo, 1.0, 1.0, 1.0, 1.0); cairo_scale(cairo, scale, scale); //cairo_select_font_face(cairo, "helvetica", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_select_font_face(cairo, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairo, fontsize); surfshapes = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, W, H); cairoshapes = cairo_create(surfshapes); cairo_set_line_join(cairoshapes, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairoshapes, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairoshapes, 1.0, 1.0, 1.0, 1.0); cairo_scale(cairoshapes, scale, scale); cairo_select_font_face(cairoshapes, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairoshapes, fontsize); surfshapesmask = cairo_image_surface_create(CAIRO_FORMAT_A8, W, H); cairoshapesmask = cairo_create(surfshapesmask); cairo_set_line_join(cairoshapesmask, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairoshapesmask, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairoshapesmask, 1.0, 1.0, 1.0, 1.0); cairo_scale(cairoshapesmask, scale, scale); cairo_select_font_face(cairoshapesmask, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairoshapesmask, fontsize); cairo_paint(cairoshapesmask); cairo_stroke(cairoshapesmask); surfbg = cairo_image_surface_create(CAIRO_FORMAT_A8, W, H); cairobg = cairo_create(surfbg); cairo_set_line_join(cairobg, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairobg, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairobg, 0, 0, 0, 1); cairo_scale(cairobg, scale, scale); cairo_select_font_face(cairobg, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairobg, fontsize); cairos->bg = cairobg; cairos->fg = cairo; cairos->shapes = cairoshapes; cairos->shapesmask = cairoshapesmask; cairos->imgW = (float)W/scale; cairos->imgH = (float)H/scale; // } if (grid) { double ramin, ramax, decmin, decmax; double ra, dec; double rastep = gridspacing / 60.0; double decstep = gridspacing / 60.0; // how many line segments int N = 10; double px, py; int i; cairo_set_source_rgba(cairo, gridcolor[0], gridcolor[1], gridcolor[2], 1.0); sip_get_radec_bounds(&sip, 100, &ramin, &ramax, &decmin, &decmax); logverb("Plotting grid lines from RA=%g to %g in steps of %g; Dec=%g to %g in steps of %g\n", ramin, ramax, rastep, decmin, decmax, decstep); for (dec = decstep * floor(decmin / decstep); dec<=decmax; dec+=decstep) { logverb(" dec=%g\n", dec); for (i=0; i<=N; i++) { ra = ramin + ((double)i / (double)N) * (ramax - ramin); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; // first time, move_to; else line_to ((ra == ramin) ? cairo_move_to : cairo_line_to)(cairo, px, py); } cairo_stroke(cairo); } for (ra = rastep * floor(ramin / rastep); ra <= ramax; ra += rastep) { //for (dec=decmin; dec<=decmax; dec += (decmax - decmin)/(double)N) { logverb(" ra=%g\n", ra); for (i=0; i<=N; i++) { dec = decmin + ((double)i / (double)N) * (decmax - decmin); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; // first time, move_to; else line_to ((dec == decmin) ? cairo_move_to : cairo_line_to)(cairo, px, py); } cairo_stroke(cairo); } cairo_set_source_rgba(cairo, 1.0, 1.0, 1.0, 1.0); } } if (constell) { N = constellations_n(); logverb("Checking %i constellations.\n", N); for (c=0; c<N; c++) { const char* shortname = NULL; const char* longname; il* lines; il* uniqstars; il* inboundstars; float r,g,b; int Ninbounds; int Nunique; cairo_text_extents_t textents; double cmass[3]; uniqstars = constellations_get_unique_stars(c); inboundstars = il_new(16); Nunique = il_size(uniqstars); debug("%s: %zu unique stars.\n", shortname, il_size(uniqstars)); // Count the number of unique stars belonging to this contellation // that are within the image bounds Ninbounds = 0; for (i=0; i<il_size(uniqstars); i++) { int star; star = il_get(uniqstars, i); constellations_get_star_radec(star, &ra, &dec); debug("star %i: ra,dec (%g,%g)\n", il_get(uniqstars, i), ra, dec); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; Ninbounds++; il_append(inboundstars, star); } il_free(uniqstars); debug("%i are in-bounds.\n", Ninbounds); // Only draw this constellation if at least 2 of its stars // are within the image bounds. if (Ninbounds < 2) { il_free(inboundstars); continue; } // Set the color based on the location of the first in-bounds star. // This is a hack -- we have two different constellation // definitions with different numbering schemes! if (!justlist && (il_size(inboundstars) > 0)) { // This is helpful for videos: ensuring that the same // color is chosen for a constellation in each frame. int star = il_get(inboundstars, 0); constellations_get_star_radec(star, &ra, &dec); if (whitetext) { r = g = b = 1; } else { color_for_radec(ra, dec, &r, &g, &b); } cairo_set_source_rgba(cairoshapes, r,g,b,0.8); cairo_set_line_width(cairoshapes, cw); cairo_set_source_rgba(cairo, r,g,b,0.8); cairo_set_line_width(cairo, cw); } // Draw circles around each star. // Find center of mass (of the in-bounds stars) cmass[0] = cmass[1] = cmass[2] = 0.0; for (i=0; i<il_size(inboundstars); i++) { double xyz[3]; int star = il_get(inboundstars, i); constellations_get_star_radec(star, &ra, &dec); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; if (!justlist) { cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI); cairo_stroke(cairoshapes); } radecdeg2xyzarr(ra, dec, xyz); cmass[0] += xyz[0]; cmass[1] += xyz[1]; cmass[2] += xyz[2]; } cmass[0] /= il_size(inboundstars); cmass[1] /= il_size(inboundstars); cmass[2] /= il_size(inboundstars); xyzarr2radecdeg(cmass, &ra, &dec); il_free(inboundstars); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; shortname = constellations_get_shortname(c); longname = constellations_get_longname(c); assert(shortname && longname); logverb("%s at (%g, %g)\n", longname, px, py); if (Ninbounds == Nunique) { printf("The constellation %s (%s)\n", longname, shortname); } else { printf("Part of the constellation %s (%s)\n", longname, shortname); } if (justlist) continue; // If the label will be off-screen, move it back on. cairo_text_extents(cairo, shortname, &textents); if (px < 0) px = 0; if (py < textents.height) py = textents.height; if ((px + textents.width)*scale > W) px = W/scale - textents.width; if ((py+textents.height)*scale > H) py = H/scale - textents.height; logverb("%s at (%g, %g)\n", shortname, px, py); add_text(cairos, longname, px, py, halign, valign); // Draw the lines. cairo_set_line_width(cairo, lw); lines = constellations_get_lines(c); for (i=0; i<il_size(lines)/2; i++) { int star1, star2; double ra1, dec1, ra2, dec2; double px1, px2, py1, py2; double dx, dy; double dist; double gapfrac; star1 = il_get(lines, i*2+0); star2 = il_get(lines, i*2+1); constellations_get_star_radec(star1, &ra1, &dec1); constellations_get_star_radec(star2, &ra2, &dec2); if (!sip_radec2pixelxy(&sip, ra1, dec1, &px1, &py1) || !sip_radec2pixelxy(&sip, ra2, dec2, &px2, &py2)) continue; dx = px2 - px1; dy = py2 - py1; dist = hypot(dx, dy); gapfrac = endgap / dist; cairo_move_to(cairoshapes, px1 + dx*gapfrac, py1 + dy*gapfrac); cairo_line_to(cairoshapes, px1 + dx*(1.0-gapfrac), py1 + dy*(1.0-gapfrac)); cairo_stroke(cairoshapes); } il_free(lines); } logverb("done constellations.\n"); } if (bright) { double dy = 0; cairo_font_extents_t extents; pl* brightstars = pl_new(16); if (!justlist) { cairo_set_source_rgba(cairoshapes, 0.75, 0.75, 0.75, 0.8); cairo_font_extents(cairo, &extents); dy = extents.ascent * 0.5; cairo_set_line_width(cairoshapes, cw); } N = bright_stars_n(); logverb("Checking %i bright stars.\n", N); for (i=0; i<N; i++) { const brightstar_t* bs = bright_stars_get(i); if (!sip_radec2pixelxy(&sip, bs->ra, bs->dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; if (!(bs->name && strlen(bs->name))) continue; if (common_only && !(bs->common_name && strlen(bs->common_name))) continue; if (strcmp(bs->common_name, "Maia") == 0) continue; pl_append(brightstars, bs); } // keep only the Nbright brightest? if (Nbright && (pl_size(brightstars) > Nbright)) { pl_sort(brightstars, sort_by_mag); pl_remove_index_range(brightstars, Nbright, pl_size(brightstars)-Nbright); } for (i=0; i<pl_size(brightstars); i++) { char* text; const brightstar_t* bs = pl_get(brightstars, i); if (!sip_radec2pixelxy(&sip, bs->ra, bs->dec, &px, &py)) continue; if (bs->common_name && strlen(bs->common_name)) if (print_common_only || common_only) text = strdup(bs->common_name); else asprintf_safe(&text, "%s (%s)", bs->common_name, bs->name); else text = strdup(bs->name); logverb("%s at (%g, %g)\n", text, px, py); if (json) { sl* names = sl_new(4); char* namearr; if (bs->common_name && strlen(bs->common_name)) sl_append(names, bs->common_name); if (bs->name) sl_append(names, bs->name); namearr = sl_join(names, "\", \""); sl_appendf(json, "{ \"type\" : \"star\", " " \"pixelx\": %g, " " \"pixely\": %g, " " \"name\" : \"%s\", " " \"names\" : [ \"%s\" ] } " , px, py, (bs->common_name && strlen(bs->common_name)) ? bs->common_name : bs->name, namearr); free(namearr); sl_free2(names); } if (bs->common_name && strlen(bs->common_name)) printf("The star %s (%s)\n", bs->common_name, bs->name); else printf("The star %s\n", bs->name); if (!justlist) { float r,g,b; // set color based on RA,Dec to match constellations above. if (whitetext) { r = g = b = 1; } else { color_for_radec(bs->ra, bs->dec, &r, &g, &b); } cairo_set_source_rgba(cairoshapes, r,g,b,0.8); cairo_set_source_rgba(cairo, r,g,b, 0.8); } if (!justlist) add_text(cairos, text, px + label_offset, py + dy, halign, valign); free(text); if (!justlist) { // plot a black circle behind the light circle... cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI); cairo_stroke(cairoshapes); } } pl_free(brightstars); } if (NGC) { double imscale; double imsize; double dy = 0; cairo_font_extents_t extents; if (!justlist) { cairo_set_source_rgb(cairoshapes, 1.0, 1.0, 1.0); cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0); cairo_set_line_width(cairo, nw); cairo_font_extents(cairo, &extents); dy = extents.ascent * 0.5; } // arcsec/pixel imscale = sip_pixel_scale(&sip); // arcmin imsize = imscale * (imin(W, H) / scale) / 60.0; N = ngc_num_entries(); logverb("Checking %i NGC/IC objects.\n", N); for (i=0; i<N; i++) { ngc_entry* ngc = ngc_get_entry(i); sl* str; sl* names; double pixsize; float ara, adec; char* text; if (!ngc) break; if (ngc->size < imsize * ngc_fraction) continue; if (ngcic_accurate_get_radec(ngc->is_ngc, ngc->id, &ara, &adec) == 0) { ngc->ra = ara; ngc->dec = adec; } if (!sip_radec2pixelxy(&sip, ngc->ra, ngc->dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; str = sl_new(4); //sl_appendf(str, "%s %i", (ngc->is_ngc ? "NGC" : "IC"), ngc->id); names = ngc_get_names(ngc, NULL); if (names) { int n; for (n=0; n<sl_size(names); n++) { if (only_messier && strncmp(sl_get(names, n), "M ", 2)) continue; sl_append(str, sl_get(names, n)); } } sl_free2(names); text = sl_implode(str, " / "); printf("%s\n", text); pixsize = ngc->size * 60.0 / imscale; if (!justlist) { // black circle behind the white one... cairo_arc(cairobg, px, py, pixsize/2.0+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_move_to(cairoshapes, px + pixsize/2.0, py); cairo_arc(cairoshapes, px, py, pixsize/2.0, 0.0, 2.0*M_PI); debug("size: %f arcsec, pixsize: %f pixels\n", ngc->size, pixsize); cairo_stroke(cairoshapes); add_text(cairos, text, px + label_offset, py + dy, halign, valign); } if (json) { char* namelist = sl_implode(str, "\", \""); sl_appendf(json, "{ \"type\" : \"ngc\", " " \"names\" : [ \"%s\" ], " " \"pixelx\" : %g, " " \"pixely\" : %g, " " \"radius\" : %g }" , namelist, px, py, pixsize/2.0); free(namelist); } free(text); sl_free2(str); } } if (HD) { double rac, decc, ra2, dec2; double arcsec; hd_catalog_t* hdcat; bl* hdlist; int i; if (!justlist) cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0); logverb("Reading HD catalog: %s\n", hdpath); hdcat = henry_draper_open(hdpath); if (!hdcat) { ERROR("Failed to open HD catalog"); exit(-1); } logverb("Got %i HD stars\n", henry_draper_n(hdcat)); sip_pixelxy2radec(&sip, W/(2.0*scale), H/(2.0*scale), &rac, &decc); sip_pixelxy2radec(&sip, 0.0, 0.0, &ra2, &dec2); arcsec = arcsec_between_radecdeg(rac, decc, ra2, dec2); // Fudge arcsec *= 1.1; hdlist = henry_draper_get(hdcat, rac, decc, arcsec); logverb("Found %zu HD stars within range (%g arcsec of RA,Dec %g,%g)\n", bl_size(hdlist), arcsec, rac, decc); for (i=0; i<bl_size(hdlist); i++) { double px, py; char* txt; hd_entry_t* hd = bl_access(hdlist, i); if (!sip_radec2pixelxy(&sip, hd->ra, hd->dec, &px, &py)) { continue; } if (px < 0 || py < 0 || px*scale > W || py*scale > H) { logverb(" HD %i at RA,Dec (%g, %g) -> pixel (%.1f, %.1f) is out of bounds\n", hd->hd, hd->ra, hd->dec, px, py); continue; } asprintf_safe(&txt, "HD %i", hd->hd); if (!justlist) { cairo_text_extents_t textents; cairo_text_extents(cairo, txt, &textents); cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI); cairo_stroke(cairoshapes); px -= (textents.width * 0.5); py -= (crad + 4.0); add_text(cairos, txt, px, py, halign, valign); } if (json) sl_appendf(json, "{ \"type\" : \"hd\"," " \"pixelx\": %g, " " \"pixely\": %g, " " \"name\" : \"HD %i\" }" , px, py, hd->hd); printf("%s\n", txt); free(txt); } bl_free(hdlist); henry_draper_close(hdcat); } if (json) { FILE* fout = stderr; char* annstr = sl_implode(json, ",\n"); fprintf(fout, "{ \n"); fprintf(fout, " \"status\": \"solved\",\n"); fprintf(fout, " \"git-revision\": %s,\n", AN_GIT_REVISION); fprintf(fout, " \"git-date\": \"%s\",\n", AN_GIT_DATE); fprintf(fout, " \"annotations\": [\n%s\n]\n", annstr); fprintf(fout, "}\n"); free(annstr); } sl_free2(json); json = NULL; if (justlist) return 0; target = cairo_image_surface_create_for_data(img, CAIRO_FORMAT_ARGB32, W, H, W*4); cairot = cairo_create(target); cairo_set_source_rgba(cairot, 0, 0, 0, 1); // Here's where you set the background surface's properties... cairo_set_source_surface(cairot, surfbg, 0, 0); cairo_mask_surface(cairot, surfshapesmask, 0, 0); cairo_stroke(cairot); // Add on the shapes. cairo_set_source_surface(cairot, surfshapes, 0, 0); //cairo_mask_surface(cairot, surfshapes, 0, 0); cairo_mask_surface(cairot, surfshapesmask, 0, 0); cairo_stroke(cairot); // Add on the foreground. cairo_set_source_surface(cairot, surffg, 0, 0); cairo_mask_surface(cairot, surffg, 0, 0); cairo_stroke(cairot); // Convert image for output... cairoutils_argb32_to_rgba(img, W, H); if (pngformat) { if (cairoutils_write_png(outfn, img, W, H)) { ERROR("Failed to write PNG"); exit(-1); } } else { if (cairoutils_write_ppm(outfn, img, W, H)) { ERROR("Failed to write PPM"); exit(-1); } } cairo_surface_destroy(target); cairo_surface_destroy(surfshapesmask); cairo_surface_destroy(surffg); cairo_surface_destroy(surfbg); cairo_surface_destroy(surfshapes); cairo_destroy(cairo); cairo_destroy(cairot); cairo_destroy(cairobg); cairo_destroy(cairoshapes); cairo_destroy(cairoshapesmask); free(img); return 0; }
int main(int argc, char** args) { int c; char* xylsfn = NULL; char* wcsfn = NULL; char* rdlsfn = NULL; xylist_t* xyls = NULL; rdlist_t* rdls = NULL; sip_t sip; int i, j; int W, H; //double xyzcenter[3]; //double fieldrad2; double pixeljitter = 1.0; int loglvl = LOG_MSG; double wcsscale; char* bgfn = NULL; //double nsigma = 3.0; fits_use_error_system(); while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 'I': bgfn = optarg; break; case 'j': pixeljitter = atof(optarg); break; case 'h': print_help(args[0]); exit(0); case 'r': rdlsfn = optarg; break; case 'x': xylsfn = optarg; break; case 'w': wcsfn = optarg; break; case 'v': loglvl++; break; } } if (optind != argc) { print_help(args[0]); exit(-1); } if (!xylsfn || !wcsfn || !rdlsfn) { print_help(args[0]); exit(-1); } log_init(loglvl); // read WCS. logmsg("Trying to parse SIP header from %s...\n", wcsfn); if (!sip_read_header_file(wcsfn, &sip)) { logmsg("Failed to parse SIP header from %s.\n", wcsfn); } // image W, H W = sip.wcstan.imagew; H = sip.wcstan.imageh; if ((W == 0.0) || (H == 0.0)) { logmsg("WCS file %s didn't contain IMAGEW and IMAGEH headers.\n", wcsfn); // FIXME - use bounds of xylist? exit(-1); } wcsscale = sip_pixel_scale(&sip); logmsg("WCS scale: %g arcsec/pixel\n", wcsscale); // read XYLS. xyls = xylist_open(xylsfn); if (!xyls) { logmsg("Failed to read an xylist from file %s.\n", xylsfn); exit(-1); } // read RDLS. rdls = rdlist_open(rdlsfn); if (!rdls) { logmsg("Failed to read an rdlist from file %s.\n", rdlsfn); exit(-1); } // Find field center and radius. /* sip_pixelxy2xyzarr(&sip, W/2, H/2, xyzcenter); fieldrad2 = arcsec2distsq(sip_pixel_scale(&sip) * hypot(W/2, H/2)); */ { // (x,y) positions of field stars. double* fieldpix; int Nfield; double* indexpix; starxy_t* xy; rd_t* rd; int Nindex; xy = xylist_read_field(xyls, NULL); if (!xy) { logmsg("Failed to read xyls entries.\n"); exit(-1); } Nfield = starxy_n(xy); fieldpix = starxy_to_xy_array(xy, NULL); logmsg("Found %i field objects\n", Nfield); // Project RDLS into pixel space. rd = rdlist_read_field(rdls, NULL); if (!rd) { logmsg("Failed to read rdls entries.\n"); exit(-1); } Nindex = rd_n(rd); logmsg("Found %i indx objects\n", Nindex); indexpix = malloc(2 * Nindex * sizeof(double)); for (i=0; i<Nindex; i++) { anbool ok; double ra = rd_getra(rd, i); double dec = rd_getdec(rd, i); ok = sip_radec2pixelxy(&sip, ra, dec, indexpix + i*2, indexpix + i*2 + 1); assert(ok); } logmsg("CRPIX is (%g,%g)\n", sip.wcstan.crpix[0], sip.wcstan.crpix[1]); /* // ?? // Look for index-field pairs that are (a) close together; and (b) close to CRPIX. // Split the image into 3x3, 5x5 or so, and in each, look for a // (small) rotation and log(scale), then (bigger) shift, using histogram // cross-correlation. // Are the rotations and scales really going to be big enough that this // is required, or can we get away with doing shift first, then fine-tuning // rotation and scale? { // NxN blocks int NB = 3; int b; // HACK - use histogram2d machinery to split image into blocks. histogram2d* blockhist = histogram2d_new_nbins(0, W, NB, 0, H, NB); int* fieldi = malloc(Nfield * sizeof(int)); int* indexi = malloc(Nindex * sizeof(int)); // rotation bins int NR = 100; // scale bins (ie, log(radius) bins) double minrad = 1.0; double maxrad = 200.0; int NS = 100; histogram2d* rsfield = histogram2d_new_nbins(-M_PI, M_PI, NR, log(minrad), log(maxrad), NS); histogram2d* rsindex = histogram2d_new_nbins(-M_PI, M_PI, NR, log(minrad), log(maxrad), NS); histogram2d_set_y_edges(rsfield, HIST2D_DISCARD); histogram2d_set_y_edges(rsindex, HIST2D_DISCARD); for (b=0; b<(NB*NB); b++) { int bin; int NF, NI; double dx, dy; NF = NI = 0; for (i=0; i<Nfield; i++) { bin = histogram2d_add(blockhist, fieldpix[2*i], fieldpix[2*i+1]); if (bin != b) continue; fieldi[NF] = i; NF++; } for (i=0; i<Nindex; i++) { bin = histogram2d_add(blockhist, indexpix[2*i], indexpix[2*i+1]); if (bin != b) continue; indexi[NI] = i; NI++; } logmsg("bin %i has %i field and %i index stars.\n", b, NF, NI); logmsg("histogramming field rotation/scale\n"); for (i=0; i<NF; i++) { for (j=0; j<i; j++) { dx = fieldpix[2*fieldi[i]] - fieldpix[2*fieldi[j]]; dy = fieldpix[2*fieldi[i]+1] - fieldpix[2*fieldi[j]+1]; histogram2d_add(rsfield, atan2(dy, dx), log(sqrt(dx*dx + dy*dy))); } } logmsg("histogramming index rotation/scale\n"); for (i=0; i<NI; i++) { for (j=0; j<i; j++) { dx = indexpix[2*indexi[i]] - fieldpix[2*indexi[j]]; dy = indexpix[2*indexi[i]+1] - fieldpix[2*indexi[j]+1]; histogram2d_add(rsindex, atan2(dy, dx), log(sqrt(dx*dx + dy*dy))); } } } histogram2d_free(rsfield); histogram2d_free(rsindex); free(fieldi); free(indexi); histogram2d_free(blockhist); } */ { double* fieldsigma2s = malloc(Nfield * sizeof(double)); int besti; int* theta; double logodds; double Q2, R2; double qc[2]; double gamma; // HACK -- quad radius-squared Q2 = square(100.0); qc[0] = sip.wcstan.crpix[0]; qc[1] = sip.wcstan.crpix[1]; // HACK -- variance growth rate wrt radius. gamma = 1.0; for (i=0; i<Nfield; i++) { R2 = distsq(qc, fieldpix + 2*i, 2); fieldsigma2s[i] = square(pixeljitter) * (1.0 + gamma * R2/Q2); } logodds = verify_star_lists(indexpix, Nindex, fieldpix, fieldsigma2s, Nfield, W*H, 0.25, log(1e-100), log(1e100), &besti, NULL, &theta, NULL, NULL); logmsg("Logodds: %g\n", logodds); if (bgfn) { plot_args_t pargs; plotimage_t* img; cairo_t* cairo; char outfn[32]; j = 0; plotstuff_init(&pargs); pargs.outformat = PLOTSTUFF_FORMAT_PNG; sprintf(outfn, "tweak-%03i.png", j); pargs.outfn = outfn; img = plotstuff_get_config(&pargs, "image"); //img->format = PLOTSTUFF_FORMAT_JPG; // guess plot_image_set_filename(img, bgfn); plot_image_setsize(&pargs, img); plotstuff_run_command(&pargs, "image"); cairo = pargs.cairo; // red circles around every field star. cairo_set_color(cairo, "red"); for (i=0; i<Nfield; i++) { cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE, fieldpix[2*i+0], fieldpix[2*i+1], 2.0 * sqrt(fieldsigma2s[i])); cairo_stroke(cairo); } // green crosshairs at every index star. cairo_set_color(cairo, "green"); for (i=0; i<Nindex; i++) { cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR, indexpix[2*i+0], indexpix[2*i+1], 3); cairo_stroke(cairo); } // thick white circles for corresponding field stars. cairo_set_line_width(cairo, 2); for (i=0; i<Nfield; i++) { if (theta[i] < 0) continue; cairo_set_color(cairo, "white"); cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE, fieldpix[2*i+0], fieldpix[2*i+1], 2.0 * sqrt(fieldsigma2s[i])); cairo_stroke(cairo); // thick cyan crosshairs for corresponding index stars. cairo_set_color(cairo, "cyan"); cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR, indexpix[2*theta[i]+0], indexpix[2*theta[i]+1], 3); cairo_stroke(cairo); } plotstuff_output(&pargs); } free(theta); free(fieldsigma2s); } free(fieldpix); free(indexpix); } if (xylist_close(xyls)) { logmsg("Failed to close XYLS file.\n"); } return 0; }
int main(int argc, char *args[]) { int loglvl = LOG_MSG; int argchar; char* progname = args[0]; plot_args_t pargs; plotstuff_init(&pargs); pargs.fout = stdout; pargs.outformat = PLOTSTUFF_FORMAT_PNG; while ((argchar = getopt(argc, args, OPTIONS)) != -1) switch (argchar) { case 'v': loglvl++; break; case 'o': pargs.outfn = optarg; break; case 'P': pargs.outformat = PLOTSTUFF_FORMAT_PPM; break; case 'j': pargs.outformat = PLOTSTUFF_FORMAT_JPG; break; case 'J': pargs.outformat = PLOTSTUFF_FORMAT_PDF; break; case 'W': pargs.W = atoi(optarg); break; case 'H': pargs.H = atoi(optarg); break; case 'h': printHelp(progname); exit(0); case '?': default: printHelp(progname); exit(-1); } if (optind != argc) { printHelp(progname); exit(-1); } log_init(loglvl); // log errors to stderr, not stdout. errors_log_to(stderr); fits_use_error_system(); for (;;) { if (plotstuff_read_and_run_command(&pargs, stdin)) break; } if (plotstuff_output(&pargs)) exit(-1); plotstuff_free(&pargs); return 0; }
int main(int argc, char** args) { int loglvl = LOG_MSG; char** myargs; int nargs; int c; char* wcsinfn = NULL; char* wcsoutfn = NULL; int ext = 0; anbool scamp = FALSE; double xlo = 1; double xhi = 1000; double xstep = 0; double ylo = 1; double yhi = 1000; double ystep = 0; anbool forcetan = FALSE; dl* xylst; double x,y; double* xy; int Nxy; int W, H; W = H = 0; while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 't': forcetan = TRUE; break; case 'W': W = atoi(optarg); break; case 'H': H = atoi(optarg); break; case 'x': xlo = atof(optarg); break; case 'X': xhi = atof(optarg); break; case 'a': xstep = atof(optarg); break; case 'y': ylo = atof(optarg); break; case 'Y': yhi = atof(optarg); break; case 'b': ystep = atof(optarg); break; case 's': scamp = TRUE; break; case 'e': ext = atoi(optarg); break; case 'v': loglvl++; break; case '?': case 'h': print_help(args[0]); exit(0); } } nargs = argc - optind; myargs = args + optind; if (nargs != 2) { print_help(args[0]); exit(-1); } wcsinfn = myargs[0]; wcsoutfn = myargs[1]; log_init(loglvl); fits_use_error_system(); logmsg("Reading WCS (with PV distortions) from %s, ext %i\n", wcsinfn, ext); logmsg("Writing WCS (with SIP distortions) to %s\n", wcsoutfn); assert(xhi >= xlo); assert(yhi >= ylo); if (xstep == 0) { int nsteps = MAX(1, round((xhi - xlo)/100.0)); xstep = (xhi - xlo) / (double)nsteps; } if (ystep == 0) { int nsteps = MAX(1, round((yhi - ylo)/100.0)); ystep = (yhi - ylo) / (double)nsteps; } logverb("Stepping from x = %g to %g, steps of %g\n", xlo, xhi, xstep); logverb("Stepping from y = %g to %g, steps of %g\n", ylo, yhi, ystep); xylst = dl_new(256); for (y=ylo; y<=(yhi+0.001); y+=ystep) { for (x=xlo; x<=(xhi+0.001); x+=xstep) { dl_append(xylst, x); dl_append(xylst, y); } } Nxy = dl_size(xylst)/2; xy = dl_to_array(xylst); dl_free(xylst); if (wcs_pv2sip(wcsinfn, ext, wcsoutfn, scamp, xy, Nxy, W, H, forcetan)) { exit(-1); } free(xy); return 0; }
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; }