示例#1
0
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);
}
示例#2
0
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;
}
示例#3
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;
}
示例#7
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;
}
示例#8
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;
}
示例#9
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;
}
示例#10
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;
}
示例#11
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;
}
示例#12
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;
}
示例#13
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;
}
示例#14
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;
}
示例#15
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;
}
示例#16
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;
}
示例#17
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;
}
示例#18
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;
}
示例#19
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;
}
示例#20
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;
}