Ejemplo n.º 1
0
void test_sorting(CuTest* tc) {
	double flux[] = { 50, 100, 50, 100, 20, 20, 40, 40 };
	double bg[]   = {  0,  10, 10,   0, 10,  0,  5,  0 };

	int trueorder[] = { 4, 5, 7, 6, 2, 0, 1, 3 };

	int i, N;
	starxy_t* s;
	char* infn = "/tmp/test-resort-xylist";
	char* outfn = "/tmp/test-resort-xylist-out";
	xylist_t* xy;

	xylist_t* xy2;
	starxy_t* s2;

	xy = xylist_open_for_writing(infn);
	CuAssertPtrNotNull(tc, xy);
    xylist_set_include_flux(xy, TRUE);
    xylist_set_include_background(xy, TRUE);
	if (xylist_write_primary_header(xy) ||
		xylist_write_header(xy)) {
		CuFail(tc, "write header");
	}

	N = sizeof(flux) / sizeof(double);
	s = starxy_new(N, TRUE, TRUE);

	for (i=0; i<N; i++) {
		starxy_setx(s, i, random()%1000);
		starxy_sety(s, i, random()%1000);
	}
	starxy_set_flux_array(s, flux);
	starxy_set_bg_array(s, bg);
	if (xylist_write_field(xy, s) ||
		xylist_fix_header(xy) ||
		xylist_fix_primary_header(xy) ||
		xylist_close(xy)) {
		CuFail(tc, "close xy");
	}

	CuAssertIntEquals(tc, 0,
					  resort_xylist(infn, outfn, NULL, NULL, TRUE));

	xy2 = xylist_open(outfn);
	s2 = xylist_read_field(xy2, NULL);
	CuAssertPtrNotNull(tc, s2);

	CuAssertPtrNotNull(tc, s2->x);
	CuAssertPtrNotNull(tc, s2->y);
	CuAssertPtrNotNull(tc, s2->flux);
	CuAssertPtrNotNull(tc, s2->background);

	for (i=0; i<N; i++) {
		CuAssertDblEquals(tc, s->x[trueorder[i]], s2->x[i], 1e-6);
		CuAssertDblEquals(tc, s->y[trueorder[i]], s2->y[i], 1e-6);
		CuAssertDblEquals(tc, s->flux[trueorder[i]], s2->flux[i], 1e-6);
		CuAssertDblEquals(tc, s->background[trueorder[i]], s2->background[i], 1e-6);
	}
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
void test_solve_multiindex(CuTest* ct) {
    sl* fns;
    multiindex_t* mi;
    int i;
    solver_t* s = NULL;
    starxy_t* field = NULL;
    MatchObj* mo = NULL;
    xylist_t* xy = NULL;

    log_init(LOG_VERB);

    fns = sl_new(4);
    sl_append(fns, "../util/t10.ind");
    sl_append(fns, "../util/t11.ind");
    sl_append(fns, "../util/t12.ind");
    mi = multiindex_open("../util/t10.skdt", fns, 0);

    printf("Got %i indices\n", multiindex_n(mi));
    for (i=0; i<multiindex_n(mi); i++) {
        index_t* ind = multiindex_get(mi, i);
        printf("  %i: %s, %i stars, %i quads (%g to %g arcmin)\n",
               i, ind->indexname, index_nquads(ind), index_nstars(ind),
               ind->index_scale_lower/60., ind->index_scale_upper/60.);
    }

    s = solver_new();

    // 10.8
    s->funits_lower = 5.0;
    s->funits_upper = 15.0;

    xy = xylist_open("../util/t1.xy");
    if (!xy) {
        ERROR("Failed to open xylist\n");
        CuFail(ct, "xylist");
    }
    field = xylist_read_field(xy, NULL);

    solver_set_field(s, field);
    solver_set_field_bounds(s, 0, 1000, 0, 1000);

    for (i=0; i<multiindex_n(mi); i++) {
        index_t* ind = multiindex_get(mi, i);
        solver_add_index(s, ind);
    }

    solver_run(s);

    if (solver_did_solve(s)) {
        mo = solver_get_best_match(s);
        matchobj_print(mo, LOG_MSG);

        // HACK -- ugly!!
        verify_free_matchobj(mo);
    }

    xylist_close(xy);

    solver_cleanup_field(s);
    solver_free(s);

    multiindex_free(mi);
    sl_free2(fns);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
// This runs after "astrometry-engine" is run on the file.
static void after_solved(augment_xylist_t* axy,
						 solve_field_args_t* sf,
						 anbool makeplots,
						 const char* me,
						 anbool verbose,
						 const char* tempdir,
						 sl* tempdirs,
						 sl* tempfiles,
						 double plotscale,
						 const char* bgfn) {
	sip_t wcs;
	double ra, dec, fieldw, fieldh;
	char rastr[32], decstr[32];
	char* fieldunits;

	// print info about the field.
	logmsg("Field: %s\n", axy->imagefn ? axy->imagefn : axy->xylsfn);
	if (file_exists(axy->wcsfn)) {
		double orient;
		if (axy->wcs_last_mod) {
			time_t t = file_get_last_modified_time(axy->wcsfn);
			if (t == axy->wcs_last_mod) {
				logmsg("Warning: there was already a WCS file, and its timestamp has not changed.\n");
			}
		}
		if (!sip_read_header_file(axy->wcsfn, &wcs)) {
			ERROR("Failed to read WCS header from file %s", axy->wcsfn);
			exit(-1);
		}
		sip_get_radec_center(&wcs, &ra, &dec);
		sip_get_radec_center_hms_string(&wcs, rastr, decstr);
		sip_get_field_size(&wcs, &fieldw, &fieldh, &fieldunits);
		orient = sip_get_orientation(&wcs);
		logmsg("Field center: (RA,Dec) = (%3.6f, %3.6f) deg.\n", ra, dec);
		logmsg("Field center: (RA H:M:S, Dec D:M:S) = (%s, %s).\n", rastr, decstr);
		logmsg("Field size: %g x %g %s\n", fieldw, fieldh, fieldunits);
		logmsg("Field rotation angle: up is %g degrees E of N\n", orient);
	} else {
		logmsg("Did not solve (or no WCS file was written).\n");
	}

	// create new FITS file...
	if (axy->fitsimgfn && sf->newfitsfn && file_exists(axy->wcsfn)) {
		logmsg("Creating new FITS file \"%s\"...\n", sf->newfitsfn);
		if (new_wcs(axy->fitsimgfn, axy->wcsfn, sf->newfitsfn, TRUE)) {
			ERROR("Failed to create FITS image with new WCS headers");
			exit(-1);
		}
	}

	// write list of index stars in image coordinates
	if (sf->indxylsfn && file_exists(axy->wcsfn) && file_exists(axy->rdlsfn)) {
		assert(axy->wcsfn);
		assert(axy->rdlsfn);
		// index rdls to xyls.
		if (wcs_rd2xy(axy->wcsfn, 0, axy->rdlsfn, sf->indxylsfn,
					  NULL, NULL, FALSE, FALSE, NULL)) {
			ERROR("Failed to project index stars into field coordinates using wcs-rd2xy");
			exit(-1);
		}
	}

	if (makeplots && file_exists(sf->indxylsfn) && file_readable(axy->matchfn) && file_readable(axy->wcsfn)) {
		logmsg("Creating index object overlay plot...\n");
		if (plot_index_overlay(axy, me, sf->indxylsfn, sf->redgreenfn, plotscale, bgfn)) {
			ERROR("Plot index overlay failed.");
		}
	}

	if (makeplots && file_readable(axy->wcsfn)) {
		logmsg("Creating annotation plot...\n");
		if (plot_annotations(axy, me, verbose, sf->ngcfn, plotscale, bgfn)) {
			ERROR("Plot annotations failed.");
		}
	}

	if (axy->imagefn && sf->kmzfn && file_exists(axy->wcsfn)) {
		logmsg("Writing kmz file...\n");
		if (write_kmz(axy, sf->kmzfn, tempdir, tempdirs, tempfiles)) {
			ERROR("Failed to write KMZ.");
			exit(-1);
		}
	}

	if (sf->scampfn && file_exists(axy->wcsfn)) {
		//char* hdrfile = NULL;
		qfits_header* imageheader = NULL;
		starxy_t* xy;
		xylist_t* xyls;

		xyls = xylist_open(axy->axyfn);
		if (!xyls) {
			ERROR("Failed to read xylist to write SCAMP catalog");
			exit(-1);
		}
		if (axy->xcol)
			xylist_set_xname(xyls, axy->xcol);
		if (axy->ycol)
			xylist_set_yname(xyls, axy->ycol);
		//xylist_set_include_flux(xyls, FALSE);
		xylist_set_include_background(xyls, FALSE);
		xy = xylist_read_field(xyls, NULL);
		xylist_close(xyls);

		if (axy->fitsimgfn) {
			//hdrfile = axy->fitsimgfn;
			imageheader = anqfits_get_header2(axy->fitsimgfn, 0);
		}
		if (axy->xylsfn) {
			char val[32];
			//hdrfile = axy->xylsfn;
			imageheader = anqfits_get_header2(axy->xylsfn, 0);
			// Set NAXIS=2, NAXIS1=IMAGEW, NAXIS2=IMAGEH
			fits_header_mod_int(imageheader, "NAXIS", 2, NULL);
			sprintf(val, "%i", axy->W);
			qfits_header_add_after(imageheader, "NAXIS",  "NAXIS1", val, "image width", NULL);
			sprintf(val, "%i", axy->H);
			qfits_header_add_after(imageheader, "NAXIS1", "NAXIS2", val, "image height", NULL);
			//fits_header_add_int(imageheader, "NAXIS1", axy->W, NULL);
			//fits_header_add_int(imageheader, "NAXIS2", axy->H, NULL);
			logverb("Using NAXIS 1,2 = %i,%i\n", axy->W, axy->H);
		}

		if (scamp_write_field(imageheader, &wcs, xy, sf->scampfn)) {
			ERROR("Failed to write SCAMP catalog");
			exit(-1);
		}
		starxy_free(xy);
		if (imageheader)
			qfits_header_destroy(imageheader);
	}

	if (sf->scampconfigfn) {
		if (scamp_write_config_file(axy->scampfn, sf->scampconfigfn)) {
			ERROR("Failed to write SCAMP config file snippet to %s", sf->scampconfigfn);
			exit(-1);
		}
	}
}