Пример #1
0
def process_loop(fname):
    """
    Thread to process satobs FourFrame FITS files in a multi-thread compatible manner
    """

    # Generate star catalog
    if not os.path.exists(fname + ".cat"):
        pix_catalog = generate_star_catalog(fname)
    else:
        pix_catalog = pixel_catalog(fname + ".cat")

    # Calibrate from reference
    calibrate_from_reference(fname, "test.fits", pix_catalog)

    # Store calibration
    store_calibration(pix_catalog, fname + ".cal")

    # Generate satellite predictions
    generate_satellite_predictions(fname)

    # Detect lines with 3D Hough transform
    ids = find_hough3d_lines(fname, nhoughmin, houghrmin)

    # Get properties
    ff = fourframe(fname)

    # Extract tracks
    if is_calibrated(ff):
        screenoutput_idents = extract_tracks(fname, trkrmin, drdtmin, drdtmax, trksig, ntrkmin, root_dir, results_dir, tle_dir)
    else:
        screenoutput_idents = None 

    # Stars available and used
    nused = np.sum(pix_catalog.flag == 1)
    nstars = pix_catalog.nstars

    # Write output
    screenoutput = "%s %10.6f %10.6f %4d/%4d %5.1f %5.1f %6.2f +- %6.2f" % (
        ff.fname, ff.crval[0], ff.crval[1], nused, nstars,
        3600.0 * ff.crres[0], 3600.0 * ff.crres[1], np.mean(
            ff.zavg), np.std(ff.zavg))

    if is_calibrated(ff):
        screenoutput = colored(screenoutput, "green")
    else:
        screenoutput = colored(screenoutput, "red")

    imgstat_output = ("%s,%.8lf,%.6f,%.6f,%.3f,%.3f,%.3f," + "%.3f,%d,%d\n") % (
        (ff.fname, ff.mjd, ff.crval[0], ff.crval[1],
            3600 * ff.crres[0], 3600 * ff.crres[1], np.mean(
                ff.zavg), np.std(ff.zavg), nstars, nused))

    # Move processed files
    shutil.move(fname, os.path.join(processed_dir, fname))
    shutil.move(fname + ".png", os.path.join(processed_dir, fname + ".png"))
    shutil.move(fname + ".id", os.path.join(processed_dir, fname + ".id"))
    shutil.move(fname + ".cat", os.path.join(processed_dir, fname + ".cat"))
    shutil.move(fname + ".cal", os.path.join(processed_dir, fname + ".cal"))

    return (screenoutput, imgstat_output, screenoutput_idents)
Пример #2
0
def generate_keogram(path):
    # Get files
    fnames = sorted(glob.glob(os.path.join(path, "processed/2*.fits")))

    # Allocate arrays
    nx = len(fnames)
    ny = cfg.getint('Camera', 'camera_y')
    ixmid = cfg.getint('Camera', 'camera_x') // 2
    keogram = np.zeros(nx * ny).reshape(ny, nx)
    mjds = np.zeros(nx)

    # Get data
    for i, fname in enumerate(fnames):
        if i % 10 == 0:
            print(i, fname)

        # Read file
        ff = fourframe(fname)

        # Extract data
        keogram[:, i] = ff.zavg[:, ixmid]
        mjds[i] = ff.mjd

    # Save npy arrays
    np.save(os.path.join(path, "mjds"), mjds)
    np.save(os.path.join(path, "keogram"), keogram)
Пример #3
0
        fnames = sorted(glob.glob("2*.fits"))

        # Loop over files
        for fname in fnames:
            # Generate star catalog
            pix_catalog = generate_star_catalog(fname)

            # Create reference calibration file
            if not os.path.exists("test.fits"):
                solved = generate_reference_with_anet(fname, "")

            # Calibrate astrometry
            calibrate_from_reference(fname, "test.fits", pix_catalog)

            # Redo refence if astrometry failed
            if not is_calibrated(fourframe(fname)) and pix_catalog.nstars > 10:
                print(
                    colored(
                        "Recomputing astrometric calibration for %s" % fname,
                        "yellow"))
                solved = generate_reference_with_anet(fname, "")

                # Calibrate astrometry
                calibrate_from_reference(fname, "test.fits", pix_catalog)

            # Generate satellite predictions
            generate_satellite_predictions(fname)

            # Detect lines with 3D Hough transform
            ids = find_hough3d_lines(fname)
Пример #4
0
def find_hough3d_lines(fname, ntrkmin, trkrmin):
    # Read four frame
    ff = fourframe(fname)

    # Mask frame
    ff.mask(10, 10, 5, 5)

    # Compute selection mask
    x, y, z, t, sig = ff.selection_mask(5.0, 40.0)

    # Skip if not enough points
    if len(t) < 2:
        return []

    # Save points to a unique temporary file
    (fd, tmpfile_path) = tempfile.mkstemp(prefix="hough_tmp", suffix=".dat")

    try:
        with os.fdopen(fd, "w") as f:
            for i in range(len(t)):
                f.write("%f,%f,%f\n" % (x[i], y[i], z[i]))

        # Run 3D Hough line-finding algorithm
        command = "hough3dlines -dx %d -minvotes %d %s" % (trkrmin, ntrkmin,
                                                           tmpfile_path)
        try:
            output = subprocess.check_output(command,
                                             shell=True,
                                             stderr=subprocess.STDOUT)
        except Exception:
            return []
    finally:
        os.remove(tmpfile_path)

    # FIXME: Is this still needed? hough3dlines output does not appear to have these items -- interplanetarychris
    # Clean output (a bit cluncky)
    cleaned_output = output.decode("utf-8").replace("npoints=", "")
    cleaned_output = cleaned_output.replace(", a=(", " ")
    cleaned_output = cleaned_output.replace("), b=(", " ")
    cleaned_output = cleaned_output.replace(")", "")
    cleaned_output = cleaned_output.replace(",", " ")

    # Generate identifications
    lines = []
    s = cleaned_output.split()
    for i in range(len(s) // 7):
        # Extract points
        x0, y0, z0 = float(s[1 + 7 * i]), float(s[2 + 7 * i]), float(s[3 +
                                                                       7 * i])
        dx, dy, dz = float(s[4 + 7 * i]), float(s[5 + 7 * i]), float(s[6 +
                                                                       7 * i])

        # Reconstruct start and end points
        xmin = x0 - z0 * dx / (dz + 1e-9)
        xmax = x0 + (ff.nz - z0) * dx / (dz + 1e-9)
        ymin = y0 - z0 * dy / (dz + 1e-9)
        ymax = y0 + (ff.nz - z0) * dy / (dz + 1e-9)

        # Output line
        line = "%.23s %8.3f %8.3f %8.3f %8.3f %8.5f  %s unidentified sunlit\n" %\
               (ff.nfd, xmin, ymin, xmax, ymax, ff.texp, 99999-i)
        lines.append(line)

    # Store identifications
    with open(fname + ".id", "a") as fp:
        for line in lines:
            fp.write(line)

    return [satid(line) for line in lines]
Пример #5
0
def extract_tracks(fname, trkrmin, drdtmin, trksig, ntrkmin, path,
                   results_path):
    # Read four frame
    ff = fourframe(fname)

    # Skip saturated frames
    if np.sum(ff.zavg > 240.0) / float(ff.nx * ff.ny) > 0.95:
        return

    # Read satelite IDs
    try:
        f = open(fname + ".id")
    except OSError:
        print("Cannot open", fname + ".id")
    else:
        lines = f.readlines()
        f.close()

    tr = np.array([-0.5, 1.0, 0.0, -0.5, 0.0, 1.0])

    # Parse identifications
    idents = [satid(line) for line in lines]

    # Identify unknowns
    for ident0 in idents:
        if ident0.catalog == "unidentified":
            for ident1 in idents:
                if ident1.catalog == "unidentified":
                    continue

                # Find matches
                p1 = inside_selection(ident1, ident0.t0, ident0.x0, ident0.y0)
                p2 = inside_selection(ident1, ident0.t1, ident0.x1, ident0.y1)

                # Match found
                if p1 and p2:
                    # Copy info
                    ident0.norad = ident1.norad
                    ident0.catalog = ident1.catalog
                    ident0.state = ident1.state
                    ident1.state = "remove"
                    break

    # Loop over identifications
    for ident in idents:
        # Skip superseded unknowns
        if ident.state == "remove":
            continue

        # Skip slow moving objects
        drdt = np.sqrt(ident.dxdt**2 + ident.dydt**2)
        if drdt < drdtmin:
            continue

        # Extract significant pixels along a track
        x, y, t, sig = ff.significant_pixels_along_track(
            trksig, ident.x0, ident.y0, ident.dxdt, ident.dydt, trkrmin)

        # Fit tracks
        if len(t) > ntrkmin:
            # Get times
            tmin = np.min(t)
            tmax = np.max(t)
            tmid = 0.5 * (tmax + tmin)
            mjd = ff.mjd + tmid / 86400.0

            # Skip if no variance in time
            if np.std(t - tmid) == 0.0:
                continue

            # Very simple polynomial fit; no weighting, no cleaning
            px = np.polyfit(t - tmid, x, 1)
            py = np.polyfit(t - tmid, y, 1)

            # Extract results
            x0, y0 = px[1], py[1]
            dxdt, dydt = px[0], py[0]
            xmin = x0 + dxdt * (tmin - tmid)
            ymin = y0 + dydt * (tmin - tmid)
            xmax = x0 + dxdt * (tmax - tmid)
            ymax = y0 + dydt * (tmax - tmid)

            cospar = get_cospar(ident.norad, ff.nfd)
            obs = observation(ff, mjd, x0, y0)
            iod_line = "%s" % format_iod_line(ident.norad, cospar, ff.site_id,
                                              obs.nfd, obs.ra, obs.de)

            # Create diagnostic plot
            plot_header(fname.replace(".fits", "_%05d.png/png" % ident.norad),
                        ff, iod_line)

            ppg.pgimag(ff.zmax, ff.nx, ff.ny, 0, ff.nx - 1, 0, ff.ny - 1,
                       ff.zmaxmax, ff.zmaxmin, tr)
            ppg.pgbox("BCTSNI", 0., 0, "BCTSNI", 0., 0)
            ppg.pgstbg(1)

            ppg.pgsci(0)
            if ident.catalog.find("classfd.tle") > 0:
                ppg.pgsci(4)
            elif ident.catalog.find("inttles.tle") > 0:
                ppg.pgsci(3)

            ppg.pgpt(np.array([x0]), np.array([y0]), 4)
            ppg.pgmove(xmin, ymin)
            ppg.pgdraw(xmax, ymax)
            ppg.pgsch(0.65)
            ppg.pgtext(np.array([x0]), np.array([y0]), " %05d" % ident.norad)
            ppg.pgsch(1.0)
            ppg.pgsci(1)

            ppg.pgend()

            # Store results
            store_results(ident, fname, results_path, iod_line)

        elif ident.catalog.find("classfd.tle") > 0:
            # Track and stack
            t = np.linspace(0.0, ff.texp)
            x, y = ident.x0 + ident.dxdt * t, ident.y0 + ident.dydt * t
            c = (x > 0) & (x < ff.nx) & (y > 0) & (y < ff.ny)

            # Skip if no points selected
            if np.sum(c) == 0:
                store_not_seen(ident, fname, results_path)
                continue

            # Compute track
            tmid = np.mean(t[c])
            mjd = ff.mjd + tmid / 86400.0
            xmid = ident.x0 + ident.dxdt * tmid
            ymid = ident.y0 + ident.dydt * tmid
            ztrk = ndimage.gaussian_filter(
                ff.track(ident.dxdt, ident.dydt, tmid), 1.0)
            vmin = np.mean(ztrk) - 2.0 * np.std(ztrk)
            vmax = np.mean(ztrk) + 6.0 * np.std(ztrk)

            # Select region
            xmin = int(xmid - 100)
            xmax = int(xmid + 100)
            ymin = int(ymid - 100)
            ymax = int(ymid + 100)
            if xmin < 0:
                xmin = 0
            if ymin < 0:
                ymin = 0
            if xmax > ff.nx:
                xmax = ff.nx - 1
            if ymax > ff.ny:
                ymax = ff.ny - 1

            # Find peak
            x0, y0, w, sigma = peakfind(ztrk[ymin:ymax, xmin:xmax])
            x0 += xmin
            y0 += ymin

            # Skip if peak is not significant
            if sigma < trksig:
                store_not_seen(ident, fname, results_path)
                continue

            # Skip if point is outside selection area
            if inside_selection(ident, tmid, x0, y0) is False:
                store_not_seen(ident, fname, results_path)
                continue

            # Format IOD line
            cospar = get_cospar(ident.norad, ff.nfd)
            obs = observation(ff, mjd, x0, y0)
            iod_line = "%s" % format_iod_line(ident.norad, cospar, ff.site_id,
                                              obs.nfd, obs.ra, obs.de)

            # Create diagnostic plot
            pngfile = fname.replace(".fits", "_%05d.png" % ident.norad)
            plot_header(pngfile + "/png", ff, iod_line)

            ppg.pgimag(ztrk, ff.nx, ff.ny, 0, ff.nx - 1, 0, ff.ny - 1, vmax,
                       vmin, tr)
            ppg.pgbox("BCTSNI", 0., 0, "BCTSNI", 0., 0)
            ppg.pgstbg(1)

            plot_selection(ident, xmid, ymid)

            ppg.pgsci(0)
            if ident.catalog.find("classfd.tle") > 0:
                ppg.pgsci(4)
            elif ident.catalog.find("inttles.tle") > 0:
                ppg.pgsci(3)
            ppg.pgpt(np.array([ident.x0]), np.array([ident.y0]), 17)
            ppg.pgmove(ident.x0, ident.y0)
            ppg.pgdraw(ident.x1, ident.y1)
            ppg.pgpt(np.array([x0]), np.array([y0]), 4)
            ppg.pgsch(0.65)
            ppg.pgtext(np.array([ident.x0]), np.array([ident.y0]),
                       " %05d" % ident.norad)
            ppg.pgsch(1.0)
            ppg.pgsci(1)

            ppg.pgend()

            # Store results
            store_results(ident, fname, results_path, iod_line)
Пример #6
0
def find_hough3d_lines(fname, ntrkmin=20, dr=8):
    # Read four frame
    ff = fourframe(fname)

    # Mask frame
    ff.mask(10, 10, 5, 5)

    # Compute selection mask
    x, y, z, t, sig = ff.selection_mask(5.0, 40.0)

    # Skip if not enough points
    if len(t) < 2:
        return []

    # Save points to temporary file
    with open("/tmp/hough.dat", "w") as f:
        for i in range(len(t)):
            f.write("%f,%f,%f\n" % (x[i], y[i], z[i]))
    f.close()

    # Run 3D Hough line-finding algorithm
    command = "hough3dlines -dx %d -minvotes %d %s" % (dr, ntrkmin,
                                                       "/tmp/hough.dat")
    try:
        output = subprocess.check_output(command,
                                         shell=True,
                                         stderr=subprocess.STDOUT)
    except Exception:
        return []

    # Clean output (a bit cluncky)
    cleaned_output = output.decode("utf-8").replace("npoints=", "")
    cleaned_output = cleaned_output.replace(", a=(", " ")
    cleaned_output = cleaned_output.replace("), b=(", " ")
    cleaned_output = cleaned_output.replace(")", "")
    cleaned_output = cleaned_output.replace(",", " ")

    # Generate identifications
    lines = []
    s = cleaned_output.split()
    for i in range(len(s) // 7):
        # Extract points
        x0, y0, z0 = float(s[1 + 7 * i]), float(s[2 + 7 * i]), float(s[3 +
                                                                       7 * i])
        dx, dy, dz = float(s[4 + 7 * i]), float(s[5 + 7 * i]), float(s[6 +
                                                                       7 * i])

        # Reconstruct start and end points
        xmin = x0 - z0 * dx / (dz + 1e-9)
        xmax = x0 + (ff.nz - z0) * dx / (dz + 1e-9)
        ymin = y0 - z0 * dy / (dz + 1e-9)
        ymax = y0 + (ff.nz - z0) * dy / (dz + 1e-9)

        # Output line
        line = "%.23s %8.3f %8.3f %8.3f %8.3f %8.5f  %s unidentified sunlit\n" %\
               (ff.nfd, xmin, ymin, xmax, ymax, ff.texp, 99999-i)
        lines.append(line)

    # Store identifications
    fp = open(fname + ".id", "a")
    for line in lines:
        fp.write(line)
    fp.close()

    return [satid(line) for line in lines]
Пример #7
0
        for fname in fnames:
            # Generate star catalog
            if not os.path.exists(fname + ".cat"):
                pix_catalog = generate_star_catalog(fname)

            # Calibrate from reference
            calibrate_from_reference(fname, "test.fits", pix_catalog)

            # Generate satellite predictions
            generate_satellite_predictions(fname)

            # Detect lines with 3D Hough transform
            ids = find_hough3d_lines(fname)

            # Get properties
            ff = fourframe(fname)

            # Extract tracks
            if is_calibrated(ff):
                extract_tracks(fname, trkrmin, drdtmin, trksig, ntrkmin,
                               root_dir, results_dir)

            # Stars available and used
            nused = np.sum(pix_catalog.flag == 1)
            nstars = pix_catalog.nstars

            # Write output
            output = "%s %10.6f %10.6f %4d/%4d %5.1f %5.1f %6.2f +- %6.2f" % (
                ff.fname, ff.crval[0], ff.crval[1], nused, nstars,
                3600.0 * ff.crres[0], 3600.0 * ff.crres[1], np.mean(
                    ff.zavg), np.std(ff.zavg))