def has_data(fitsfile, ra0, dec0):
    "Check whether there is any non-zero data in fitsfile at the source position (ra0, dec0)"
    fitspath = misc_utils.expand_fits_path(fitsfile)
    if cmd_args.debug: print("\nReading from", fitspath)
    hdu = fits_utils.get_image_hdu(fits.open(fitspath), debug=cmd_args.debug)
    if cmd_args.debug: print("Image size", hdu.data.shape)
    w = wcs.WCS(hdu.header)
    x, y = w.wcs_world2pix(ra0, dec0, 0)
    if cmd_args.debug: print("Coords", ra0, dec0, "->", x, y)
    i1 = int(x)
    j1 = int(y)
    pixel_data = hdu.data[j1:j1+2, i1:i1+2].mean()
    if cmd_args.debug: print("{}[{}:{},{}:{}] = {}".format(
            fitsfile, j1, j1+2, i1, i1+2, pixel_data))
    return pixel_data > 0.0 
def plot_map(limits, figname, canvas_size,
             fitsfile='$LARGE_FITS_DIR/wfi/Orion_H_A_shallow.fits',
             north=False,
             vmin=0.0, vmax=None, stretch='linear',
             innerbox=None, arrowscale=1.0):
    # Use an image as a backdrop
    fig = aplpy.FITSFigure(expand_fits_path(fitsfile),
                           figsize=canvas_size, north=north)
    # Set the viewport
    xc, yc = (limits[0] + limits[1])/2, (limits[2] + limits[3])/2
    w, h = limits[1] - limits[0], limits[3] - limits[2]
    fig.recenter(c0.ra.deg - xc/3600, c0.dec.deg + yc/3600,
                 width=w/3600, height=h/3600)
    fig.show_grayscale(vmin=vmin, vmax=vmax, invert=True,
                       stretch=stretch, interpolation='none')
    ax = fig._ax1


    c = coord.SkyCoord(RAs, Decs, unit=(u.hourangle, u.degree))
    # Cartesian pixel coordinates of each source
    x, y = fig.world2pixel(c.ra.deg, c.dec.deg)

    # Pixel size in degrees
    pix_scale = aplpy.wcs_util.celestial_pixel_scale(fig._wcs)
    # Convert to arcsec
    pix_scale *= 3600

    ax.plot(x, y, "o", alpha=0.2)
    for label, xx, yy in zip(names, x, y):
        
        #
        # Try and draw the inner and outer arcs
        #

        name = label.split()[-1]
        if name in problem_sources:
            continue

        nickname = nicknames.get(name, name)
        jsonfile = "{}-arcdata.json".format(name)
        jsonfilex = "{}-arcdata.json".format(nickname)
        found = find(jsonfilex, "../JorgeBowshocks/Jorge_prop/PC-will")
        if found is not None:
            f = open(found)
        else:
            found = find(jsonfile, ".")
            if found is not None:
                f = open(found)
            else:
                print("Could not open ", jsonfile)
                continue
        arc_data = json.load(f)

        # Second, load in the data and draw the arcs
        for arc, color in ["inner", "m"], ["outer", "g"]:
            if arc in arc_data:
                dx = np.array(arc_data[arc]["x"])/pix_scale
                dy = np.array(arc_data[arc]["y"])/pix_scale
                ax.plot(xx - dx, yy + dy, "-" + color, lw=1.0, alpha=0.6)
                print("Plotted {} arc for {}".format(arc, found))
                if "Rc" in arc_data[arc]:
                    xc = arc_data[arc]["xc"]/pix_scale
                    yc = arc_data[arc]["yc"]/pix_scale
                    Rc = arc_data[arc]["Rc"]/pix_scale
                    PAc = np.radians(arc_data[arc]["PAc"])
                    PAm = np.radians(arc_data[arc]["PA0"]
                                     + np.mean(arc_data[arc]["theta"]))

                    # Plot the fitted circle if present
                    ax.plot(xx - xc, yy + yc, "+k", ms=2.0)
                    c = plt.Circle((xx - xc, yy + yc), radius=Rc, fc='none', ec="k", alpha=0.2, lw=0.2)
                    ax.add_patch(c)
                    PA = PAm if arc_data[arc]["Rc"] < 1.5*arc_data[arc]["R0"] else PAc
                    arrowx = -0.5*Rc*np.sin(PA)
                    arrowy = 0.5*Rc*np.cos(PA)
                    ax.arrow(xx-xc, yy+yc, 4*arrowx*arrowscale, 4*arrowy*arrowscale,
                             fc='none', ec=color, 
                             width=0.001, alpha=0.8, lw=1.5,
                             head_width=8.0*arrowscale, head_length=16.0*arrowscale,
                         )

        if innerbox is None:
            skip_annotation = False
        else:
            x1, y1 = fig.world2pixel(c0.ra.deg - innerbox[0]/3600,
                                     c0.dec.deg + innerbox[2]/3600)
            x2, y2 = fig.world2pixel(c0.ra.deg - innerbox[1]/3600,
                                     c0.dec.deg + innerbox[3]/3600)
            skip_annotation = (x1 <= xx <= x2) and (y1 <= yy <= y2)
            
        # Order of octants is anticlockwise around square starting at top:
        #    1 0 7
        #    2 * 6
        #    3 4 5
        alignment_by_octant = [
            ('center', 'bottom'),
            ('right', 'bottom'),
            ('right', 'center'),
            ('right', 'top'),
            ('center', 'top'),
            ('left', 'top'),
            ('left', 'center'),
            ('left', 'bottom'),
        ]
        if not skip_annotation:
            boxcolor = 'orange' if name in interprop_sources else 'white'
            PA = np.radians(arc_data["star"]["PA"] + 180.0)
            ioctant = int(((np.degrees(PA) + 22.5) % 360)*8/360)
            print('Octant:', ioctant, 'PA:', np.degrees(PA))
            ha, va = alignment_by_octant[ioctant]
            xytext = (-3*np.sin(PA), 3*np.cos(PA))
            ax.annotate(label, (xx, yy), alpha=0.8, size=5,
                        xytext=xytext, textcoords='offset points',
                        ha=ha, va=va,
                        bbox={'facecolor': boxcolor, 
                              'alpha': 0.5,
                              'pad': 2,
                              'linewidth': 0.1,
                          },
            )

    c = coord.SkyCoord(pRAs, pDecs, unit=(u.hourangle, u.degree))
    x, y = fig.world2pixel(c.ra.deg, c.dec.deg)
    ax.scatter(x, y, c=pColors, s=pSizes, edgecolors='none', alpha=0.5, zorder=100)

    if innerbox is not None:
        ax.fill_between([x1, x2], [y1, y1], [y2, y2],
                         edgecolor='black', lw=0.5, facecolor='yellow', alpha=0.3)

    fig.save(figname)