# -*- coding: utf-8 -*-
"""
Created on Fri May 30 17:15:27 2014

@author: Parke
"""

from __future__ import division, print_function, absolute_import
import numpy as np
import matplotlib as mplot
import matplotlib.pyplot as plt
import mypy.my_numpy as mnp

dpi = 100
fullwidth = 10.0
halfwidth = 5.0

# use these with line.set_dashes and iterate through more linestyles than come with matplotlib
# consider ussing a ::2 slice for fewer
dashes = [[],
          [30, 10],
          [20, 8],
          [10, 5],
          [3, 2],
          [30, 5, 3, 5, 10, 5, 3, 5],
          [15] + [5, 3]*3 + [5],
          [15] + [5, 3]*2 + [5],
          [15] + [5, 3] + [5]]


def click_coords(fig=None, timeout=600.):
    if fig is None:
        fig = plt.gcf()

    xy = []
    def onclick(event):
        if not event.inaxes:
            fig.canvas.stop_event_loop()
        else:
            xy.append([event.xdata, event.ydata])

    print("Gathering coordinates of mouse clicks. Click outside of the axes " \
          "when done.")
    cid = fig.canvas.mpl_connect('button_press_event', onclick)
    fig.canvas.start_event_loop(timeout=timeout)
    fig.canvas.mpl_disconnect(cid)
    return np.array(xy)


def common_axes(fig, pos=None):
    if pos is None:
        bigax = fig.add_subplot(111)
    else:
        bigax = fig.add_axes(pos)
    [bigax.spines[s].set_visible(False) for s in ['top', 'bottom', 'left', 'right']]
    bigax.tick_params(labelleft=False, labelbottom=False, left='off', bottom='off')
    bigax.set_zorder(-10)
    return bigax


def log_frac(x, frac):
    l0, l1 = list(map(np.log10, x))
    ld = l1 - l0
    l = ld*frac + l0
    return 10**l


def log2linear(x, errneg=None, errpos=None):
    xl = 10**x
    result = [xl]
    if errneg is not None:
        xn = xl - 10**(x - np.abs(errneg))
        result.append(xn)
    if errpos is not None:
        xp = 10**(x + errpos) - xl
        result.append(xp)
    return result


def linear2log(x, errneg=None, errpos=None):
    xl = np.log10(x)
    result = [x]
    if errneg is not None:
        xn = xl - np.log10(x - np.abs(errneg))
        result.append(xn)
    if errpos is not None:
        xp = np.log10(x + errpos) - xl
        result.append(xp)
    return result


def step(*args, **kwargs):
    edges, values = args[0], args[1]

    # deal with potentially gappy 2-column bin specifications
    edges = np.asarray(edges)
    if edges.ndim == 2:
        if np.any(edges[1:,0] < edges[:-1,1]):
            raise ValueError('Some bins overlap')
        if np.any(edges[1:,0] < edges[:-1,0]):
            raise ValueError('Bins must be in increasing order.')
        gaps = edges[1:,0] > edges[:-1,1]
        edges = np.unique(edges)
        if np.any(gaps):
            values = np.insert(values, np.nonzero(gaps), np.nan)

    edges = mnp.lace(edges[:-1], edges[1:])
    values = mnp.lace(values, values)
    args = list(args)
    args[0], args[1] = edges, values
    ax = kwargs.pop('ax', plt.gca())
    return ax.plot(*args, **kwargs)


def point_along_line(x, y, xfrac=None, xlbl=None, scale='linear'):
    if scale == 'log':
        lx, ly = point_along_line(np.log10(x), np.log10(y), xfrac, xlbl, ylbl, scale)
        return 10 ** lx, 10 ** ly
    if xfrac is not None:
        if xfrac == 0:
            return x[0], y[0]
        if xfrac == 1:
            return x[-1], y[-1]
        else:
            d = np.cumsum(np.sqrt(np.diff(x)**2 + np.diff(y)**2))
            d = np.insert(d, 0, 0)
            f = d/d[-1]
            xp, yp = [np.interp(xfrac, f, a) for a in [x,y]]
            return xp, yp
    if xlbl is not None:
        return xlbl, np.interp(xlbl, x, y)


def textSize(ax_or_fig=None, coordinate='data'):
    """
    Return x & y scale factors for converting text sizes in points to another coordinate. Useful for properly spacing
    text labels and such when you need to know sizes before the text is made (otherwise you can use textBoxSize).

    Coordinate can be 'data', 'axes', or 'figure'.

    If data coordinates are requested and the data is plotted on a log scale, then the factor will be given in dex.

    """
    if ax_or_fig is None:
        fig = plt.gcf()
        ax = fig.gca()
    else:
        if isinstance(ax_or_fig, plt.Figure):
            fig = ax_or_fig
            ax = fig.gca()
        elif isinstance(ax_or_fig, plt.Axes):
            ax = ax_or_fig
            fig = ax.get_figure()
        else:
            raise TypeError('ax_or_fig must be a Figure or Axes instance, if given.')

    w_fig_in, h_fig_in = ax.get_figure().get_size_inches()

    if coordinate == 'fig':
        return 1.0/(w_fig_in*72), 1.0/(h_fig_in*72)

    w_ax_norm, h_ax_norm = ax.get_position().size
    w_ax_in = w_ax_norm * w_fig_in
    h_ax_in = h_ax_norm * h_fig_in
    w_ax_pts, h_ax_pts = w_ax_in*72, h_ax_in*72

    if coordinate == 'axes':
        return 1.0/w_ax_pts, 1.0/h_ax_pts

    if coordinate == 'data':
        xlim = ax.get_xlim()
        ylim = ax.get_ylim()
        if ax.get_xscale() == 'log': xlim = np.log10(xlim)
        if ax.get_yscale() == 'log': ylim = np.log10(ylim)
        w_ax_data = xlim[1] - xlim[0]
        h_ax_data = ylim[1] - ylim[0]
        return w_ax_data/w_ax_pts, h_ax_data/h_ax_pts


def tight_axis_limits(ax=None, xory='both', margin=0.05):
    if ax is None: ax = plt.gca()

    def newlim(oldlim):
        delta = abs(oldlim[1] - oldlim[0])
        pad = delta*margin
        if oldlim[1] > oldlim[0]:
            return (oldlim[0] - pad, oldlim[1] + pad)
        else:
            return (oldlim[0] + pad, oldlim[1] - pad)

    def newlim_log(oldlim):
        loglim = [np.log10(l) for l in oldlim]
        newloglim = newlim(loglim)
        return (10.0**newloglim[0], 10.0**newloglim[1])

    def newlim_either(oldlim,axlim,scale):
        if axlim[1] < axlim [0]: oldlim = oldlim[::-1]
        if scale == 'linear':
            return newlim(oldlim)
        elif scale == 'log':
            return newlim_log(oldlim)
        elif scale == 'symlog':
            raise NotImplementedError('Past Parke to future Parke, you did\'t write an implementation for symlog'
                                      'scaled axes.')

    if xory == 'x' or xory == 'both':
        datalim = ax.dataLim.extents[[0,2]]
        axlim = ax.get_xlim()
        scale = ax.get_xscale()
        ax.set_xlim(newlim_either(datalim,axlim,scale))
    if xory == 'y' or xory == 'both':
        datalim = ax.dataLim.extents[[1,3]]
        axlim = ax.get_ylim()
        scale = ax.get_yscale()
        ax.set_ylim(newlim_either(datalim,axlim,scale))

#TODO: discard this function?
def standard_figure(app, slideAR=1.6, height=1.0):
    """Generate a figure of standard size for publishing.

    implemented values for app (application) are:
    'fullslide'

    height is the fractional height of the figure relative to the "standard"
    height. For slides the standard is the full height of a slide.

    returns the figure object and default font size
    """

    if app == 'fullslide':
        fontsize = 20
        figsize = [fullwidth, fullwidth/slideAR*height]
        fig = mplot.pyplot.figure(figsize=figsize, dpi=dpi)

    mplot.rcParams.update({'font.size': fontsize})
    return fig, fontsize


def pcolor_reg(x, y, z, **kw):
    """
    Similar to `pcolor`, but assume that the grid is uniform,
    and do plotting with the (much faster) `imshow` function.

    """
    x, y, z = np.asarray(x), np.asarray(y), np.asarray(z)
    if x.ndim != 1 or y.ndim != 1:
        raise ValueError("x and y should be 1-dimensional")
    if z.ndim != 2 or z.shape != (y.size, x.size):
        raise ValueError("z.shape should be (y.size, x.size)")
    dx = np.diff(x)
    dy = np.diff(y)
    if not np.allclose(dx, dx[0], 1e-2) or not np.allclose(dy, dy[0], 1e-2):
        raise ValueError("The grid must be uniform")

    if np.issubdtype(z.dtype, np.complexfloating):
        zp = np.zeros(z.shape, float)
        zp[...] = z[...]
        z = zp

    plt.imshow(z, origin='lower',
               extent=[x.min(), x.max(), y.min(), y.max()],
               interpolation='nearest',
               aspect='auto',
               **kw)
    plt.axis('tight')


def errorpoly(x, y, yerr, fmt=None, ecolor=None, ealpha=0.5, ax=None, **kw):
    if ax is None: ax = plt.gca()
    p = ax.plot(x, y, **kw) if fmt is None else ax.plot(x, y, fmt, **kw)
    if len(yerr.shape) == 2:
        ylo = y - yerr[0,:]
        yhi = y + yerr[1,:]
    else:
        ylo, yhi = y - yerr, y + yerr
    if ecolor is None: ecolor = p[0].get_color()

    # deal with matplotlib sometimes not showing polygon when it extends beyond plot range
    xlim = ax.get_xlim()
    inrange = mnp.inranges(x, xlim)
    if not np.all(inrange):
        n = np.sum(inrange)
        yends = np.interp(xlim, x, y)
        yloends = np.interp(xlim, x, ylo)
        yhiends = np.interp(xlim, x, yhi)
        x = np.insert(x[inrange], [0, n], xlim)
        y = np.insert(y[inrange], [0, n], yends)
        ylo = np.insert(ylo[inrange], [0, n], yloends)
        yhi = np.insert(yhi[inrange], [0, n], yhiends)

    f = ax.fill_between(x,ylo,yhi,color=ecolor,alpha=ealpha)
    return p[0],f


def onscreen_pres(mpl, screenwidth=1200):
    """
    Set matplotlibrc values so that plots are readable as they are created
    and maximized for an audience far from a screen.

    Parameters
    ----------
    mpl : module
        Current matplotlib module. Use 'import matplotlib as mpl'.
    screewidth : int
        Width of the screen in question in pixels.

    Returns
    -------
    None
    """
    mpl.rcParams['lines.linewidth'] = 2
    fontsize = round(14 / (800.0 / screenwidth))
    mpl.rcParams['font.size'] = fontsize


def textBoxSize(txt, transformation=None, figure=None):
    """Get the width and height of a text object's bounding box transformed to the desired coordinates. Defaults to
    figure coordinates if transformation is None."""

    fig= txt.get_figure() if figure is None else figure
    if transformation is None:
        transformation = fig.transFigure

    coordConvert = transformation.inverted().transform
    bboxDisp = txt.get_window_extent(fig.canvas.renderer)
    bboxConv = coordConvert(bboxDisp)
    w = bboxConv[1,0] - bboxConv[0,0]
    h = bboxConv[1,1] - bboxConv[0,1]
    return w, h


def stars3d(ra, dec, dist, T=5000.0, r=1.0, labels='', view=None, size=(800,800), txt_scale=1.0):
    """
    Make a 3D diagram of stars positions relative to the Sun, with
    semi-accurate colors and distances as desired. Coordinates must be in
    degrees. Distance is assumed to be in pc (for axes labels).

    Meant to be used with only a handful of stars.
    """
    from mayavi import mlab
    from color.maps import true_temp

    n = len(ra)
    dec, ra = dec*np.pi/180.0, ra*np.pi/180.0
    makearr = lambda v: np.array([v] * n) if np.isscalar(v) else v
    T, r, labels = list(map(makearr, (T, r, labels)))

    # add the sun
    ra, dec, dist = list(map(np.append, (ra, dec, dist), (0.0, 0.0, 0.0)))
    r, T, labels = list(map(np.append, (r, T, labels), (1.0, 5780.0, 'Sun')))

    # get xyz coordinates
    z = dist * np.sin(dec)
    h = dist * np.cos(dec)
    x = h * np.cos(ra)
    y = h * np.sin(ra)

    # make figure
    fig = mlab.figure(bgcolor=(0,0,0), fgcolor=(1,1,1), size=size)

    # plot lines down to the dec=0 plane for all but the sun
    lines = []
    for x1, y1, z1 in list(zip(x, y, z))[:-1]:
       xx, yy, zz = [x1, x1], [y1, y1], [0.0, z1]
       line = mlab.plot3d(xx, yy, zz, color=(0.7,0.7,0.7), line_width=0.5,
                          figure=fig)
       lines.append(line)

    # plot spheres
    r_factor = np.max(dist) / 30.0
    pts = mlab.quiver3d(x, y, z, r, r, r, scalars=T, mode='sphere',
                       scale_factor=r_factor, figure=fig, resolution=100)
    pts.glyph.color_mode = 'color_by_scalar'

    # center the glyphs on the data point
    pts.glyph.glyph_source.glyph_source.center = [0, 0, 0]

    # set a temperature colormap
    cmap = true_temp(T)
    pts.module_manager.scalar_lut_manager.lut.table = cmap

    # set the camera view
    mlab.view(focalpoint=(0.0, 0.0, 0.0), figure=fig)
    if view is not None:
       mlab.view(*view, figure=fig)

    ## add labels
    # unit vec to camera
    view = mlab.view()
    az, el = view[:2]
    hc = np.sin(el * np.pi / 180.0)
    xc = hc * np.cos(az * np.pi / 180.0)
    yc = hc * np.sin(az * np.pi / 180.0)
    zc = -np.cos(el * np.pi / 180.0)

    # unit vec orthoganal to camera
    if xc**2 + yc**2 == 0.0:
       xoff = 1.0
       yoff = 0.0
       zoff = 0.0
    else:
       xoff = yc / np.sqrt(xc**2 + yc**2)
       yoff = np.sqrt(1.0 - xoff**2)
       zoff = 0.0

    #    xoff, yoff, zoff = xc, yc, zc

    # scale orthogonal vec by sphere size
    r_label = 1.0 * r_factor
    xoff, yoff, zoff = [r_label * v for v in [xoff, yoff, zoff]]

    # plot labels
    size = r_factor * txt_scale * 0.75
    for xx, yy, zz, label in zip(x, y, z, labels):
       mlab.text3d(xx + xoff, yy + yoff, zz + zoff, label, figure=fig,
                   color=(1,1,1), scale=size)

    ## add translucent dec=0 surface
    n = 101
    t = np.linspace(0.0, 2*np.pi, n)
    r = np.max(dist * np.cos(dec))
    x, y = r*np.cos(t), r*np.sin(t)
    z = np.zeros(n+1)
    x, y = [np.insert(a, 0, 0.0) for a in [x,y]]
    triangles = [(0, i, i + 1) for i in range(1, n)]
    mlab.triangular_mesh(x, y, z, triangles, color=(1,1,1), opacity=0.3, figure=fig)

    ## add ra=0 line
    line = mlab.plot3d([0, r], [0, 0], [0, 0], color=(1,1,1), line_width=1, figure=fig)
    rtxt = '{:.1f} pc'.format(r)
    orientation=np.array([180.0, 180.0, 0.0])
    mlab.text3d(r, 0, 0, rtxt, figure=fig, scale=size*1.25, orient_to_camera=False, orientation=orientation)

    if view is not None:
       mlab.view(*view, figure=fig)

    return fig



[((47, 11, 47, 23), 'numpy.array', 'np.array', ({(47, 20, 47, 22): 'xy'}, {}), '(xy)', True, 'import numpy as np\n'), ((81, 9, 81, 20), 'numpy.log10', 'np.log10', ({(81, 18, 81, 19): 'x'}, {}), '(x)', True, 'import numpy as np\n'), ((96, 12, 96, 29), 'numpy.asarray', 'np.asarray', ({(96, 23, 96, 28): 'edges'}, {}), '(edges)', True, 'import numpy as np\n'), ((107, 12, 107, 43), 'mypy.my_numpy.lace', 'mnp.lace', ({(107, 21, 107, 31): 'edges[:-1]', (107, 33, 107, 42): 'edges[1:]'}, {}), '(edges[:-1], edges[1:])', True, 'import mypy.my_numpy as mnp\n'), ((108, 13, 108, 37), 'mypy.my_numpy.lace', 'mnp.lace', ({(108, 22, 108, 28): 'values', (108, 30, 108, 36): 'values'}, {}), '(values, values)', True, 'import mypy.my_numpy as mnp\n'), ((235, 4, 235, 50), 'matplotlib.rcParams.update', 'mplot.rcParams.update', ({(235, 26, 235, 49): "{'font.size': fontsize}"}, {}), "({'font.size': fontsize})", True, 'import matplotlib as mplot\n'), ((250, 9, 250, 19), 'numpy.diff', 'np.diff', ({(250, 17, 250, 18): 'x'}, {}), '(x)', True, 'import numpy as np\n'), ((251, 9, 251, 19), 'numpy.diff', 'np.diff', ({(251, 17, 251, 18): 'y'}, {}), '(y)', True, 'import numpy as np\n'), ((255, 7, 255, 49), 'numpy.issubdtype', 'np.issubdtype', ({(255, 21, 255, 28): 'z.dtype', (255, 30, 255, 48): 'np.complexfloating'}, {}), '(z.dtype, np.complexfloating)', True, 'import numpy as np\n'), ((265, 4, 265, 21), 'matplotlib.pyplot.axis', 'plt.axis', ({(265, 13, 265, 20): '"""tight"""'}, {}), "('tight')", True, 'import matplotlib.pyplot as plt\n'), ((280, 14, 280, 35), 'mypy.my_numpy.inranges', 'mnp.inranges', ({(280, 27, 280, 28): 'x', (280, 30, 280, 34): 'xlim'}, {}), '(x, xlim)', True, 'import mypy.my_numpy as mnp\n'), ((359, 10, 359, 66), 'mayavi.mlab.figure', 'mlab.figure', (), '', False, 'from mayavi import mlab\n'), ((371, 10, 372, 73), 'mayavi.mlab.quiver3d', 'mlab.quiver3d', (), '', False, 'from mayavi import mlab\n'), ((379, 11, 379, 23), 'color.maps.true_temp', 'true_temp', ({(379, 21, 379, 22): 'T'}, {}), '(T)', False, 'from color.maps import true_temp\n'), ((383, 4, 383, 53), 'mayavi.mlab.view', 'mlab.view', (), '', False, 'from mayavi import mlab\n'), ((389, 11, 389, 22), 'mayavi.mlab.view', 'mlab.view', ({}, {}), '()', False, 'from mayavi import mlab\n'), ((391, 9, 391, 35), 'numpy.sin', 'np.sin', ({(391, 16, 391, 34): 'el * np.pi / 180.0'}, {}), '(el * np.pi / 180.0)', True, 'import numpy as np\n'), ((420, 8, 420, 36), 'numpy.linspace', 'np.linspace', ({(420, 20, 420, 23): '0.0', (420, 25, 420, 32): '2 * np.pi', (420, 34, 420, 35): 'n'}, {}), '(0.0, 2 * np.pi, n)', True, 'import numpy as np\n'), ((423, 8, 423, 21), 'numpy.zeros', 'np.zeros', ({(423, 17, 423, 20): 'n + 1'}, {}), '(n + 1)', True, 'import numpy as np\n'), ((426, 4, 426, 84), 'mayavi.mlab.triangular_mesh', 'mlab.triangular_mesh', (), '', False, 'from mayavi import mlab\n'), ((429, 11, 429, 87), 'mayavi.mlab.plot3d', 'mlab.plot3d', (), '', False, 'from mayavi import mlab\n'), ((431, 16, 431, 45), 'numpy.array', 'np.array', ({(431, 25, 431, 44): '[180.0, 180.0, 0.0]'}, {}), '([180.0, 180.0, 0.0])', True, 'import numpy as np\n'), ((432, 4, 432, 108), 'mayavi.mlab.text3d', 'mlab.text3d', (), '', False, 'from mayavi import mlab\n'), ((33, 14, 33, 23), 'matplotlib.pyplot.gcf', 'plt.gcf', ({}, {}), '()', True, 'import matplotlib.pyplot as plt\n'), ((98, 11, 98, 45), 'numpy.any', 'np.any', ({(98, 18, 98, 44): '(edges[1:, (0)] < edges[:-1, (1)])'}, {}), '(edges[1:, (0)] < edges[:-1, (1)])', True, 'import numpy as np\n'), ((100, 11, 100, 45), 'numpy.any', 'np.any', ({(100, 18, 100, 44): '(edges[1:, (0)] < edges[:-1, (0)])'}, {}), '(edges[1:, (0)] < edges[:-1, (0)])', True, 'import numpy as np\n'), ((103, 16, 103, 32), 'numpy.unique', 'np.unique', ({(103, 26, 103, 31): 'edges'}, {}), '(edges)', True, 'import numpy as np\n'), ((104, 11, 104, 23), 'numpy.any', 'np.any', ({(104, 18, 104, 22): 'gaps'}, {}), '(gaps)', True, 'import numpy as np\n'), ((111, 26, 111, 35), 'matplotlib.pyplot.gca', 'plt.gca', ({}, {}), '()', True, 'import matplotlib.pyplot as plt\n'), ((145, 14, 145, 23), 'matplotlib.pyplot.gcf', 'plt.gcf', ({}, {}), '()', True, 'import matplotlib.pyplot as plt\n'), ((181, 24, 181, 33), 'matplotlib.pyplot.gca', 'plt.gca', ({}, {}), '()', True, 'import matplotlib.pyplot as plt\n'), ((233, 14, 233, 59), 'matplotlib.pyplot.figure', 'mplot.pyplot.figure', (), '', True, 'import matplotlib as mplot\n'), ((245, 14, 245, 27), 'numpy.asarray', 'np.asarray', ({(245, 25, 245, 26): 'x'}, {}), '(x)', True, 'import numpy as np\n'), ((245, 29, 245, 42), 'numpy.asarray', 'np.asarray', ({(245, 40, 245, 41): 'y'}, {}), '(y)', True, 'import numpy as np\n'), ((245, 44, 245, 57), 'numpy.asarray', 'np.asarray', ({(245, 55, 245, 56): 'z'}, {}), '(z)', True, 'import numpy as np\n'), ((256, 13, 256, 37), 'numpy.zeros', 'np.zeros', ({(256, 22, 256, 29): 'z.shape', (256, 31, 256, 36): 'float'}, {}), '(z.shape, float)', True, 'import numpy as np\n'), ((269, 24, 269, 33), 'matplotlib.pyplot.gca', 'plt.gca', ({}, {}), '()', True, 'import matplotlib.pyplot as plt\n'), ((281, 11, 281, 26), 'numpy.all', 'np.all', ({(281, 18, 281, 25): 'inrange'}, {}), '(inrange)', True, 'import numpy as np\n'), ((282, 12, 282, 27), 'numpy.sum', 'np.sum', ({(282, 19, 282, 26): 'inrange'}, {}), '(inrange)', True, 'import numpy as np\n'), ((283, 16, 283, 37), 'numpy.interp', 'np.interp', ({(283, 26, 283, 30): 'xlim', (283, 32, 283, 33): 'x', (283, 35, 283, 36): 'y'}, {}), '(xlim, x, y)', True, 'import numpy as np\n'), ((284, 18, 284, 41), 'numpy.interp', 'np.interp', ({(284, 28, 284, 32): 'xlim', (284, 34, 284, 35): 'x', (284, 37, 284, 40): 'ylo'}, {}), '(xlim, x, ylo)', True, 'import numpy as np\n'), ((285, 18, 285, 41), 'numpy.interp', 'np.interp', ({(285, 28, 285, 32): 'xlim', (285, 34, 285, 35): 'x', (285, 37, 285, 40): 'yhi'}, {}), '(xlim, x, yhi)', True, 'import numpy as np\n'), ((286, 12, 286, 47), 'numpy.insert', 'np.insert', ({(286, 22, 286, 32): 'x[inrange]', (286, 34, 286, 40): '[0, n]', (286, 42, 286, 46): 'xlim'}, {}), '(x[inrange], [0, n], xlim)', True, 'import numpy as np\n'), ((287, 12, 287, 48), 'numpy.insert', 'np.insert', ({(287, 22, 287, 32): 'y[inrange]', (287, 34, 287, 40): '[0, n]', (287, 42, 287, 47): 'yends'}, {}), '(y[inrange], [0, n], yends)', True, 'import numpy as np\n'), ((288, 14, 288, 54), 'numpy.insert', 'np.insert', ({(288, 24, 288, 36): 'ylo[inrange]', (288, 38, 288, 44): '[0, n]', (288, 46, 288, 53): 'yloends'}, {}), '(ylo[inrange], [0, n], yloends)', True, 'import numpy as np\n'), ((289, 14, 289, 54), 'numpy.insert', 'np.insert', ({(289, 24, 289, 36): 'yhi[inrange]', (289, 38, 289, 44): '[0, n]', (289, 46, 289, 53): 'yhiends'}, {}), '(yhi[inrange], [0, n], yhiends)', True, 'import numpy as np\n'), ((353, 15, 353, 26), 'numpy.sin', 'np.sin', ({(353, 22, 353, 25): 'dec'}, {}), '(dec)', True, 'import numpy as np\n'), ((354, 15, 354, 26), 'numpy.cos', 'np.cos', ({(354, 22, 354, 25): 'dec'}, {}), '(dec)', True, 'import numpy as np\n'), ((355, 12, 355, 22), 'numpy.cos', 'np.cos', ({(355, 19, 355, 21): 'ra'}, {}), '(ra)', True, 'import numpy as np\n'), ((356, 12, 356, 22), 'numpy.sin', 'np.sin', ({(356, 19, 356, 21): 'ra'}, {}), '(ra)', True, 'import numpy as np\n'), ((365, 14, 366, 37), 'mayavi.mlab.plot3d', 'mlab.plot3d', (), '', False, 'from mayavi import mlab\n'), ((370, 15, 370, 27), 'numpy.max', 'np.max', ({(370, 22, 370, 26): 'dist'}, {}), '(dist)', True, 'import numpy as np\n'), ((385, 7, 385, 35), 'mayavi.mlab.view', 'mlab.view', (), '', False, 'from mayavi import mlab\n'), ((392, 14, 392, 40), 'numpy.cos', 'np.cos', ({(392, 21, 392, 39): '(az * np.pi / 180.0)'}, {}), '(az * np.pi / 180.0)', True, 'import numpy as np\n'), ((393, 14, 393, 40), 'numpy.sin', 'np.sin', ({(393, 21, 393, 39): '(az * np.pi / 180.0)'}, {}), '(az * np.pi / 180.0)', True, 'import numpy as np\n'), ((394, 10, 394, 36), 'numpy.cos', 'np.cos', ({(394, 17, 394, 35): '(el * np.pi / 180.0)'}, {}), '(el * np.pi / 180.0)', True, 'import numpy as np\n'), ((403, 14, 403, 36), 'numpy.sqrt', 'np.sqrt', ({(403, 22, 403, 35): '1.0 - xoff ** 2'}, {}), '(1.0 - xoff ** 2)', True, 'import numpy as np\n'), ((415, 7, 416, 45), 'mayavi.mlab.text3d', 'mlab.text3d', (), '', False, 'from mayavi import mlab\n'), ((424, 12, 424, 32), 'numpy.insert', 'np.insert', ({(424, 22, 424, 23): 'a', (424, 25, 424, 26): '(0)', (424, 28, 424, 31): '(0.0)'}, {}), '(a, 0, 0.0)', True, 'import numpy as np\n'), ((435, 7, 435, 35), 'mayavi.mlab.view', 'mlab.view', (), '', False, 'from mayavi import mlab\n'), ((87, 13, 87, 33), 'numpy.log10', 'np.log10', ({(87, 22, 87, 32): '(x + errpos)'}, {}), '(x + errpos)', True, 'import numpy as np\n'), ((117, 34, 117, 45), 'numpy.log10', 'np.log10', ({(117, 43, 117, 44): 'x'}, {}), '(x)', True, 'import numpy as np\n'), ((117, 47, 117, 58), 'numpy.log10', 'np.log10', ({(117, 56, 117, 57): 'y'}, {}), '(y)', True, 'import numpy as np\n'), ((126, 16, 126, 34), 'numpy.insert', 'np.insert', ({(126, 26, 126, 27): 'd', (126, 29, 126, 30): '0', (126, 32, 126, 33): '0'}, {}), '(d, 0, 0)', True, 'import numpy as np\n'), ((131, 21, 131, 42), 'numpy.interp', 'np.interp', ({(131, 31, 131, 35): 'xlbl', (131, 37, 131, 38): 'x', (131, 40, 131, 41): 'y'}, {}), '(xlbl, x, y)', True, 'import numpy as np\n'), ((173, 44, 173, 58), 'numpy.log10', 'np.log10', ({(173, 53, 173, 57): 'xlim'}, {}), '(xlim)', True, 'import numpy as np\n'), ((174, 44, 174, 58), 'numpy.log10', 'np.log10', ({(174, 53, 174, 57): 'ylim'}, {}), '(ylim)', True, 'import numpy as np\n'), ((192, 18, 192, 29), 'numpy.log10', 'np.log10', ({(192, 27, 192, 28): 'l'}, {}), '(l)', True, 'import numpy as np\n'), ((252, 11, 252, 39), 'numpy.allclose', 'np.allclose', ({(252, 23, 252, 25): 'dx', (252, 27, 252, 32): 'dx[0]', (252, 34, 252, 38): '(0.01)'}, {}), '(dx, dx[0], 0.01)', True, 'import numpy as np\n'), ((252, 47, 252, 75), 'numpy.allclose', 'np.allclose', ({(252, 59, 252, 61): 'dy', (252, 63, 252, 68): 'dy[0]', (252, 70, 252, 74): '(0.01)'}, {}), '(dy, dy[0], 0.01)', True, 'import numpy as np\n'), ((345, 45, 345, 59), 'numpy.isscalar', 'np.isscalar', ({(345, 57, 345, 58): 'v'}, {}), '(v)', True, 'import numpy as np\n'), ((345, 24, 345, 41), 'numpy.array', 'np.array', ({(345, 33, 345, 40): '([v] * n)'}, {}), '([v] * n)', True, 'import numpy as np\n'), ((402, 19, 402, 41), 'numpy.sqrt', 'np.sqrt', ({(402, 27, 402, 40): '(xc ** 2 + yc ** 2)'}, {}), '(xc ** 2 + yc ** 2)', True, 'import numpy as np\n'), ((421, 22, 421, 33), 'numpy.cos', 'np.cos', ({(421, 29, 421, 32): 'dec'}, {}), '(dec)', True, 'import numpy as np\n'), ((422, 13, 422, 22), 'numpy.cos', 'np.cos', ({(422, 20, 422, 21): 't'}, {}), '(t)', True, 'import numpy as np\n'), ((422, 26, 422, 35), 'numpy.sin', 'np.sin', ({(422, 33, 422, 34): 't'}, {}), '(t)', True, 'import numpy as np\n'), ((105, 39, 105, 55), 'numpy.nonzero', 'np.nonzero', ({(105, 50, 105, 54): 'gaps'}, {}), '(gaps)', True, 'import numpy as np\n'), ((128, 22, 128, 44), 'numpy.interp', 'np.interp', ({(128, 32, 128, 37): 'xfrac', (128, 39, 128, 40): 'f', (128, 42, 128, 43): 'a'}, {}), '(xfrac, f, a)', True, 'import numpy as np\n'), ((72, 27, 72, 41), 'numpy.abs', 'np.abs', ({(72, 34, 72, 40): 'errneg'}, {}), '(errneg)', True, 'import numpy as np\n'), ((84, 31, 84, 45), 'numpy.abs', 'np.abs', ({(84, 38, 84, 44): 'errneg'}, {}), '(errneg)', True, 'import numpy as np\n'), ((125, 34, 125, 44), 'numpy.diff', 'np.diff', ({(125, 42, 125, 43): 'x'}, {}), '(x)', True, 'import numpy as np\n'), ((125, 50, 125, 60), 'numpy.diff', 'np.diff', ({(125, 58, 125, 59): 'y'}, {}), '(y)', True, 'import numpy as np\n')]