Instruction:
Can you create a Python 3 function that
generates HTTP User - Agent header for the current language.

Response:
def generate_user_agent(os=None, navigator=None, platform=None,
                        device_type=None):
    """
    Generates HTTP User-Agent header

    :param os: limit list of os for generation
    :type os: string or list/tuple or None
    :param navigator: limit list of browser engines for generation
    :type navigator: string or list/tuple or None
    :param device_type: limit possible oses by device type
    :type device_type: list/tuple or None, possible values:
        "desktop", "smartphone", "tablet", "all"
    :return: User-Agent string
    :rtype: string
    :raises InvalidOption: if could not generate user-agent for
        any combination of allowed oses and navigators
    :raise InvalidOption: if any of passed options is invalid
    """
    return generate_navigator(os=os, navigator=navigator,
                              platform=platform,
                              device_type=device_type)['user_agent']


Instruction:
Make a summary of the following Python 3 code
def generate_navigator_js(os=None, navigator=None, platform=None,
                          device_type=None):
    """
    Generates web navigator's config with keys corresponding
    to keys of `windows.navigator` JavaScript object.

    :param os: limit list of oses for generation
    :type os: string or list/tuple or None
    :param navigator: limit list of browser engines for generation
    :type navigator: string or list/tuple or None
    :param device_type: limit possible oses by device type
    :type device_type: list/tuple or None, possible values:
        "desktop", "smartphone", "tablet", "all"
    :return: User-Agent config
    :rtype: dict with keys (TODO)
    :raises InvalidOption: if could not generate user-agent for
        any combination of allowed oses and navigators
    :raise InvalidOption: if any of passed options is invalid
    """

    config = generate_navigator(os=os, navigator=navigator,
                                platform=platform,
                                device_type=device_type)
    return {
        'appCodeName': config['app_code_name'],
        'appName': config['app_name'],
        'appVersion': config['app_version'],
        'platform': config['platform'],
        'userAgent': config['user_agent'],
        'oscpu': config['oscpu'],
        'product': config['product'],
        'productSub': config['product_sub'],
        'vendor': config['vendor'],
        'vendorSub': config['vendor_sub'],
        'buildID': config['build_id'],
    }

Response:
Generates a web navigator s config with keys corresponding
    to keys of Windows. navigator JavaScript object.


Instruction:
Create a Python 3 function for
checking if there is more data left on the pipe_out

Response:
def more_data(pipe_out):
    """Check if there is more data left on the pipe

    :param pipe_out: The os pipe_out
    :rtype: bool
    """
    r, _, _ = select.select([pipe_out], [], [], 0)
    return bool(r)


Instruction:
Write a Python 3 function that can
read data on a pipe and return it as a unicode string

Response:
def read_pipe(pipe_out):
    """Read data on a pipe

    Used to capture stdout data produced by libiperf

    :param pipe_out: The os pipe_out
    :rtype: unicode string
    """
    out = b''
    while more_data(pipe_out):
        out += os.read(pipe_out, 1024)

    return out.decode('utf-8')


Instruction:
Given the following Python 3 function, write the documentation
def role(self):
        try:
            self._role = c_char(
                self.lib.iperf_get_test_role(self._test)
            ).value.decode('utf-8')
        except TypeError:
            self._role = c_char(
                chr(self.lib.iperf_get_test_role(self._test))
            ).value.decode('utf-8')
        return self._role

Response: The iperf3 instance role


Instruction:
Can you tell what is the following Python 3 function doing
def json_output(self):
        enabled = self.lib.iperf_get_test_json_output(self._test)

        if enabled:
            self._json_output = True
        else:
            self._json_output = False

        return self._json_output

Response:
Toggles json output of libiperf

        Turning this off will output the iperf3 instance results to stdout and stderr


Instruction:
Given the following Python 3 function, write the documentation
def verbose(self):
        enabled = self.lib.iperf_get_verbose(self._test)

        if enabled:
            self._verbose = True
        else:
            self._verbose = False

        return self._verbose

Response: Toggles verbose output for the iperf3 instance


Instruction:
Here you have a function in Python 3, explain what it does
def iperf_version(self):
        # TODO: Is there a better way to get the const char than allocating 30?
        VersionType = c_char * 30
        return VersionType.in_dll(self.lib, "version").value.decode('utf-8')

Response: Returns the version of the libiperf library


Instruction:
Write a Python 3 function for
returning an error string from libiperf

Response:
def _error_to_string(self, error_id):
        """Returns an error string from libiperf

        :param error_id: The error_id produced by libiperf
        :rtype: string
        """
        strerror = self.lib.iperf_strerror
        strerror.restype = c_char_p
        return strerror(error_id).decode('utf-8')


Instruction:
Write a Python 3 function that can
return the server hostname to connect to.

Response:
def server_hostname(self):
        """The server hostname to connect to.

        Accepts DNS entries or IP addresses.

        :rtype: string
        """
        result = c_char_p(
            self.lib.iperf_get_test_server_hostname(self._test)
        ).value
        if result:
            self._server_hostname = result.decode('utf-8')
        else:
            self._server_hostname = None
        return self._server_hostname


Instruction:
Make a summary of the following Python 3 code
def protocol(self):
        proto_id = self.lib.iperf_get_test_protocol_id(self._test)

        if proto_id == SOCK_STREAM:
            self._protocol = 'tcp'
        elif proto_id == SOCK_DGRAM:
            self._protocol = 'udp'

        return self._protocol

Response: The iperf3 instance protocol


Instruction:
Explain what the following Python 3 code does
def omit(self):
        self._omit = self.lib.iperf_get_test_omit(self._test)
        return self._omit

Response: The test startup duration to omit in seconds.


Instruction:
How would you implement a function in Python 3 that
targets bandwidth in bits / sec

Response:
def bandwidth(self):
        """Target bandwidth in bits/sec"""
        self._bandwidth = self.lib.iperf_get_test_rate(self._test)
        return self._bandwidth


Instruction:
How would you explain what the following Python 3 function does
def reverse(self):
        enabled = self.lib.iperf_get_test_reverse(self._test)

        if enabled:
            self._reverse = True
        else:
            self._reverse = False

        return self._reverse

Response: Toggles direction of test in the order of the test


Instruction:
How would you implement a function in Python 3 that
runs the current test client.

Response:
def run(self):
        """Run the current test client.

        :rtype: instance of :class:`TestResult`
        """
        if self.json_output:
            output_to_pipe(self._pipe_in)  # Disable stdout
            error = self.lib.iperf_run_client(self._test)

            if not self.iperf_version.startswith('iperf 3.1'):
                data = read_pipe(self._pipe_out)
                if data.startswith('Control connection'):
                    data = '{' + data.split('{', 1)[1]
            else:
                data = c_char_p(
                    self.lib.iperf_get_test_json_output_string(self._test)
                ).value
                if data:
                    data = data.decode('utf-8')

            output_to_screen(self._stdout_fd, self._stderr_fd)  # enable stdout

            if not data or error:
                data = '{"error": "%s"}' % self._error_to_string(self._errno)

            return TestResult(data)


Instruction:
How would you code a function in Python 3 to
run the iperf3 server instance.

Response:
def run(self):
        """Run the iperf3 server instance.

        :rtype: instance of :class:`TestResult`
        """

        def _run_in_thread(self, data_queue):
            """Runs the iperf_run_server

            :param data_queue: thread-safe queue
            """
            output_to_pipe(self._pipe_in)  # disable stdout
            error = self.lib.iperf_run_server(self._test)
            output_to_screen(self._stdout_fd, self._stderr_fd)  # enable stdout

            # TODO json_output_string not available on earlier iperf3 builds
            # have to build in a version check using self.iperf_version
            # The following line should work on later versions:
            # data = c_char_p(
            #    self.lib.iperf_get_test_json_output_string(self._test)
            # ).value
            data = read_pipe(self._pipe_out)

            if not data or error:
                data = '{"error": "%s"}' % self._error_to_string(self._errno)

            self.lib.iperf_reset_test(self._test)
            data_queue.put(data)

        if self.json_output:
            data_queue = Queue()

            t = threading.Thread(
                target=_run_in_thread, args=[self, data_queue]
            )
            t.daemon = True

            t.start()
            while t.is_alive():
                t.join(.1)

            return TestResult(data_queue.get())
        else:
            # setting json_output to False will output test to screen only
            self.lib.iperf_run_server(self._test)
            self.lib.iperf_reset_test(self._test)

            return None


Instruction:
Can you generate the documentation for the following Python 3 function
def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
            subplot_kw=None, hemisphere='lower', projection='equal_area',
            **fig_kw):
    """
    Identical to matplotlib.pyplot.subplots, except that this will default to
    producing equal-area stereonet axes.

    This prevents constantly doing:

        >>> fig, ax = plt.subplot(subplot_kw=dict(projection='stereonet'))

    or

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111, projection='stereonet')

    Using this function also avoids having ``mplstereonet`` continually appear
    to be an unused import when one of the above methods are used.

    Parameters
    -----------
    nrows : int
      Number of rows of the subplot grid.  Defaults to 1.

    ncols : int
      Number of columns of the subplot grid.  Defaults to 1.

    hemisphere : string
        Currently this has no effect. When upper hemisphere and dual
        hemisphere plots are implemented, this will control which hemisphere
        is displayed.

    projection : string
        The projection for the axes. Defaults to 'equal_area'--an equal-area
        (a.k.a. "Schmidtt") stereonet. May also be 'equal_angle' for an
        equal-angle (a.k.a. "Wulff") stereonet or any other valid matplotlib
        projection (e.g. 'polar' or 'rectilinear' for a "normal" axes).

    The following parameters are identical to matplotlib.pyplot.subplots:

    sharex : string or bool
      If *True*, the X axis will be shared amongst all subplots.  If
      *True* and you have multiple rows, the x tick labels on all but
      the last row of plots will have visible set to *False*
      If a string must be one of "row", "col", "all", or "none".
      "all" has the same effect as *True*, "none" has the same effect
      as *False*.
      If "row", each subplot row will share a X axis.
      If "col", each subplot column will share a X axis and the x tick
      labels on all but the last row will have visible set to *False*.

    sharey : string or bool
        If *True*, the Y axis will be shared amongst all subplots. If
        *True* and you have multiple columns, the y tick labels on all but
        the first column of plots will have visible set to *False*
        If a string must be one of "row", "col", "all", or "none".
        "all" has the same effect as *True*, "none" has the same effect
        as *False*.
        If "row", each subplot row will share a Y axis.
        If "col", each subplot column will share a Y axis and the y tick
        labels on all but the last row will have visible set to *False*.

    *squeeze* : bool
        If *True*, extra dimensions are squeezed out from the
        returned axis object:

        - if only one subplot is constructed (nrows=ncols=1), the
          resulting single Axis object is returned as a scalar.

        - for Nx1 or 1xN subplots, the returned object is a 1-d numpy
          object array of Axis objects are returned as numpy 1-d
          arrays.

        - for NxM subplots with N>1 and M>1 are returned as a 2d
          array.

       If *False*, no squeezing at all is done: the returned axis
        object is always a 2-d array contaning Axis instances, even if it
        ends up being 1x1.

    *subplot_kw* : dict
        Dict with keywords passed to the
        :meth:`~matplotlib.figure.Figure.add_subplot` call used to
        create each subplots.

    *fig_kw* : dict
        Dict with keywords passed to the :func:`figure` call.  Note that all
        keywords not recognized above will be automatically included here.

    Returns
    --------
    fig, ax : tuple

        - *fig* is the :class:`matplotlib.figure.Figure` object

        - *ax* can be either a single axis object or an array of axis
           objects if more than one supblot was created.  The dimensions
           of the resulting array can be controlled with the squeeze
           keyword, see above.
    """
    import matplotlib.pyplot as plt
    if projection in ['equal_area', 'equal_angle']:
        projection += '_stereonet'
    if subplot_kw == None:
        subplot_kw = {}
    subplot_kw['projection'] = projection
    return plt.subplots(nrows, ncols, sharex=sharex, sharey=sharey,
                        squeeze=squeeze, subplot_kw=subplot_kw, **fig_kw)

Response: Create a set of subplots for the specified number of rows and columns.


Instruction:
Here you have a function in Python 3, explain what it does
def fault_and_striae_plot(ax, strikes, dips, rakes):
    # Plot the planes
    lines = ax.plane(strikes, dips, 'k-', lw=0.5)

    # Calculate the position of the rake of the lineations, but don't plot yet
    x, y = mplstereonet.rake(strikes, dips, rakes)

    # Calculate the direction the arrows should point
    # These are all normal faults, so the arrows point away from the center
    # For thrusts, it would just be u, v = -x/mag, -y/mag
    mag = np.hypot(x, y)
    u, v = x / mag, y / mag

    # Plot the arrows at the rake locations...
    arrows = ax.quiver(x, y, u, v, width=1, headwidth=4, units='dots')
    return lines, arrows

Response:
Makes a fault - and - striae plot for normal faults
    with the given strikes dips and rakes.


Instruction:
Can you generate the documentation for the following Python 3 function
def tangent_lineation_plot(ax, strikes, dips, rakes):
    # Calculate the position of the rake of the lineations, but don't plot yet
    rake_x, rake_y = mplstereonet.rake(strikes, dips, rakes)

    # Calculate the direction the arrows should point
    # These are all normal faults, so the arrows point away from the center
    # Because we're plotting at the pole location, however, we need to flip this
    # from what we plotted with the "ball of string" plot.
    mag = np.hypot(rake_x, rake_y)
    u, v = -rake_x / mag, -rake_y / mag

    # Calculate the position of the poles
    pole_x, pole_y = mplstereonet.pole(strikes, dips)

    # Plot the arrows centered on the pole locations...
    arrows = ax.quiver(pole_x, pole_y, u, v, width=1, headwidth=4, units='dots',
                       pivot='middle')
    return arrows

Response: Makes a tangent lineation plot for normal faults with the given strikes dips and rakes.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def load():
    # Get the data file relative to this file's location...
    datadir = os.path.dirname(__file__)
    filename = os.path.join(datadir, 'angelier_data.txt')

    data = []
    with open(filename, 'r') as infile:
        for line in infile:
            # Skip comments
            if line.startswith('#'):
                continue

            # First column: strike, second: dip, third: rake.
            strike, dip, rake = line.strip().split()

            if rake[-1].isalpha():
                # If there's a directional letter on the rake column, parse it
                # normally.
                strike, dip, rake = mplstereonet.parse_rake(strike, dip, rake)
            else:
                # Otherwise, it's actually an azimuthal measurement of the
                # slickenslide directions, so we need to convert it to a rake.
                strike, dip = mplstereonet.parse_strike_dip(strike, dip)
                azimuth = float(rake)
                rake = mplstereonet.azimuth2rake(strike, dip, azimuth)

            data.append([strike, dip, rake])

    # Separate the columns back out
    strike, dip, rake = zip(*data)
    return strike, dip, rake

Response: Read data from a text file on disk.


Instruction:
Write a Python 3 function that can
return a regular grid of point density estimates for the given linear orientation measurements.

Response:
def density_grid(*args, **kwargs):
    """
    Estimates point density of the given linear orientation measurements
    (Interpreted as poles, lines, rakes, or "raw" longitudes and latitudes
    based on the `measurement` keyword argument.). Returns a regular (in
    lat-long space) grid of density estimates over a hemispherical surface.

    Parameters
    ----------

    *args : 2 or 3 sequences of measurements
        By default, this will be expected to be ``strike`` & ``dip``, both
        array-like sequences representing poles to planes.  (Rake measurements
        require three parameters, thus the variable number of arguments.) The
        ``measurement`` kwarg controls how these arguments are interpreted.

    measurement : string, optional
        Controls how the input arguments are interpreted. Defaults to
        ``"poles"``.  May be one of the following:

            ``"poles"`` : strikes, dips
                Arguments are assumed to be sequences of strikes and dips of
                planes. Poles to these planes are used for contouring.
            ``"lines"`` : plunges, bearings
                Arguments are assumed to be sequences of plunges and bearings
                of linear features.
            ``"rakes"`` : strikes, dips, rakes
                Arguments are assumed to be sequences of strikes, dips, and
                rakes along the plane.
            ``"radians"`` : lon, lat
                Arguments are assumed to be "raw" longitudes and latitudes in
                the stereonet's underlying coordinate system.

    method : string, optional
        The method of density estimation to use. Defaults to
        ``"exponential_kamb"``. May be one of the following:

        ``"exponential_kamb"`` : Kamb with exponential smoothing
            A modified Kamb method using exponential smoothing [1]_. Units are
            in numbers of standard deviations by which the density estimate
            differs from uniform.
        ``"linear_kamb"`` : Kamb with linear smoothing
            A modified Kamb method using linear smoothing [1]_.  Units are in
            numbers of standard deviations by which the density estimate
            differs from uniform.
        ``"kamb"`` : Kamb with no smoothing
            Kamb's method [2]_ with no smoothing. Units are in numbers of
            standard deviations by which the density estimate differs from
            uniform.
        ``"schmidt"`` : 1% counts
            The traditional "Schmidt" (a.k.a. 1%) method. Counts points within
            a counting circle comprising 1% of the total area of the
            hemisphere. Does not take into account sample size.  Units are in
            points per 1% area.

    sigma : int or float, optional
        The number of standard deviations defining the expected number of
        standard deviations by which a random sample from a uniform
        distribution of points would be expected to vary from being evenly
        distributed across the hemisphere.  This controls the size of the
        counting circle, and therefore the degree of smoothing.  Higher sigmas
        will lead to more smoothing of the resulting density distribution. This
        parameter only applies to Kamb-based methods.  Defaults to 3.

    gridsize : int or 2-item tuple of ints, optional
        The size of the grid that the density is estimated on. If a single int
        is given, it is interpreted as an NxN grid. If a tuple of ints is given
        it is interpreted as (nrows, ncols).  Defaults to 100.

    weights : array-like, optional
        The relative weight to be applied to each input measurement. The array
        will be normalized to sum to 1, so absolute value of the weights do not
        affect the result. Defaults to None.

    Returns
    -------
    xi, yi, zi : 2D arrays
        The longitude, latitude and density values of the regularly gridded
        density estimates. Longitude and latitude are in radians.

    See Also
    ---------
    mplstereonet.StereonetAxes.density_contourf
    mplstereonet.StereonetAxes.density_contour

    References
    ----------
    .. [1] Vollmer, 1995. C Program for Automatic Contouring of Spherical
       Orientation Data Using a Modified Kamb Method. Computers &
       Geosciences, Vol. 21, No. 1, pp. 31--49.

    .. [2] Kamb, 1959. Ice Petrofabric Observations from Blue Glacier,
       Washington, in Relation to Theory and Experiment. Journal of
       Geophysical Research, Vol. 64, No. 11, pp. 1891--1909.
    """
    def do_nothing(x, y):
        return x, y
    measurement = kwargs.get('measurement', 'poles')
    gridsize = kwargs.get('gridsize', 100)
    weights = kwargs.get('weights', None)
    try:
        gridsize = int(gridsize)
        gridsize = (gridsize, gridsize)
    except TypeError:
        pass

    func = {'poles':stereonet_math.pole,
            'lines':stereonet_math.line,
            'rakes':stereonet_math.rake,
            'radians':do_nothing}[measurement]
    lon, lat = func(*args)

    method = kwargs.get('method', 'exponential_kamb')
    sigma = kwargs.get('sigma', 3)
    func = {'linear_kamb':_linear_inverse_kamb,
            'square_kamb':_square_inverse_kamb,
            'schmidt':_schmidt_count,
            'kamb':_kamb_count,
            'exponential_kamb':_exponential_kamb,
            }[method]
    lon, lat, z = _count_points(lon, lat, func, sigma, gridsize, weights)
    return lon, lat, z


Instruction:
Given the following Python 3 function, write the documentation
def _exponential_kamb(cos_dist, sigma=3):
    n = float(cos_dist.size)
    f = 2 * (1.0 + n / sigma**2)
    count = np.exp(f * (cos_dist - 1))
    units = np.sqrt(n * (f/2.0 - 1) / f**2)
    return count, units

Response: Kernel function from Vollmer for exponential smoothing.


Instruction:
Create a Python 3 function for
kerneling function from Vollmer for linear smoothing.

Response:
def _linear_inverse_kamb(cos_dist, sigma=3):
    """Kernel function from Vollmer for linear smoothing."""
    n = float(cos_dist.size)
    radius = _kamb_radius(n, sigma)
    f = 2 / (1 - radius)
    cos_dist = cos_dist[cos_dist >= radius]
    count = (f * (cos_dist - radius))
    return count, _kamb_units(n, radius)


Instruction:
How would you explain what the following Python 3 function does
def _kamb_count(cos_dist, sigma=3):
    n = float(cos_dist.size)
    dist = _kamb_radius(n, sigma)
    count = (cos_dist >= dist).astype(float)
    return count, _kamb_units(n, dist)

Response: Original Kamb kernel function ( raw count within radius ).


Instruction:
Can you generate the documentation for the following Python 3 function
def _schmidt_count(cos_dist, sigma=None):
    radius = 0.01
    count = ((1 - cos_dist) <= radius).astype(float)
    # To offset the count.sum() - 0.5 required for the kamb methods...
    count = 0.5 / count.size + count
    return count, (cos_dist.size * radius)

Response: Schmidt counting kernel function.


Instruction:
Explain what the following Python 3 code does
def _get_affine_transform(self):
        # How big is the projected globe?
        # In the case of a stereonet, it's actually constant.
        xscale = yscale = self._scale
        # Create an affine transform to stretch the projection from 0-1
        return Affine2D() \
            .rotate(np.radians(self.rotation)) \
            .scale(0.5 / xscale, 0.5 / yscale) \
            .translate(0.5, 0.5)

Response: The affine portion of the base transform. This is called by _set_lim_and_transforms.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _set_lim_and_transforms(self):
        # Most of the transforms are set up correctly by LambertAxes
        LambertAxes._set_lim_and_transforms(self)

        # Transform for latitude ticks. These are typically unused, but just
        # in case we need them...
        yaxis_stretch = Affine2D().scale(4 * self.horizon, 1.0)
        yaxis_stretch = yaxis_stretch.translate(-self.horizon, 0.0)

        # These are identical to LambertAxes._set_lim_and_transforms, but we
        # need to update things to reflect the new "yaxis_stretch"
        yaxis_space = Affine2D().scale(1.0, 1.1)
        self._yaxis_transform = \
            yaxis_stretch + \
            self.transData
        yaxis_text_base = \
            yaxis_stretch + \
            self.transProjection + \
            (yaxis_space + \
             self.transAffine + \
             self.transAxes)
        self._yaxis_text1_transform = \
            yaxis_text_base + \
            Affine2D().translate(-8.0, 0.0)
        self._yaxis_text2_transform = \
            yaxis_text_base + \
            Affine2D().translate(8.0, 0.0)

Response: Setup the key transforms for the axes.


Instruction:
Can you generate the documentation for the following Python 3 function
def set_longitude_grid(self, degrees):
        number = (360.0 / degrees) + 1
        locs = np.linspace(-np.pi, np.pi, number, True)[1:]
        locs[-1] -= 0.01 # Workaround for "back" gridlines showing.
        self.xaxis.set_major_locator(FixedLocator(locs))
        self._logitude_degrees = degrees
        self.xaxis.set_major_formatter(self.ThetaFormatter(degrees))

Response: Set the number of degrees between each longitude gridline.


Instruction:
Write a Python 3 function that can
set the rotation of the stereonet in degrees clockwise from North.

Response:
def set_rotation(self, rotation):
        """Set the rotation of the stereonet in degrees clockwise from North."""
        self._rotation = np.radians(rotation)
        self._polar.set_theta_offset(self._rotation + np.pi / 2.0)
        self.transData.invalidate()
        self.transAxes.invalidate()
        self._set_lim_and_transforms()


Instruction:
Given the following Python 3 function, write the documentation
def format_coord(self, x, y):
        p, b = stereonet_math.geographic2plunge_bearing(x, y)
        s, d = stereonet_math.geographic2pole(x, y)
        pb = u'P/B={:0.0f}\u00b0/{:03.0f}\u00b0'.format(p[0], b[0])
        sd = u'S/D={:03.0f}\u00b0/{:0.0f}\u00b0'.format(s[0], d[0])
        return u'{}, {}'.format(pb, sd)

Response: Format displayed coordinates during mouseover of axes.


Instruction:
Explain what the following Python 3 code does
def grid(self, b=None, which='major', axis='both', kind='arbitrary',
             center=None, **kwargs):
        """
        Usage is identical to a normal axes grid except for the ``kind`` and
        ``center`` kwargs.  ``kind="polar"`` will add a polar overlay.

        The ``center`` and ``kind`` arguments allow you to add a grid from a
        differently-centered stereonet. This is useful for making "polar
        stereonets" that still use the same coordinate system as a standard
        stereonet.  (i.e. a plane/line/whatever will have the same
        representation on both, but the grid is displayed differently.)

        To display a polar grid on a stereonet, use ``kind="polar"``.

        It is also often useful to display a grid relative to an arbitrary
        measurement (e.g. a lineation axis).  In that case, use the
        ``lon_center`` and ``lat_center`` arguments.  Note that these are in
        radians in "stereonet coordinates".  Therefore, you'll often want to
        use one of the functions in ``stereonet_math`` to convert a
        line/plane/rake into the longitude and latitude you'd input here. For
        example:  ``add_overlay(center=stereonet_math.line(plunge, bearing))``.

        If no parameters are specified, this is equivalent to turning on the
        standard grid.
        """
        grid_on = self._gridOn
        Axes.grid(self, False)

        if kind == 'polar':
            center = 0, 0

        if self._overlay_axes is not None:
            self._overlay_axes.remove()
            self._overlay_axes = None

        if not b and b is not None:
            return

        if b is None:
            if grid_on:
                return

        if center is None or np.allclose(center, (np.pi/2, 0)):
            return Axes.grid(self, b, which, axis, **kwargs)

        self._add_overlay(center)
        self._overlay_axes.grid(True, which, axis, **kwargs)
        self._gridOn = True

Response: This is a simple grid of the components of the current object.


Instruction:
Can you generate the documentation for the following Python 3 function
def _add_overlay(self, center):
        plunge, bearing = stereonet_math.geographic2plunge_bearing(*center)
        lon0, lat0 = center
        fig = self.get_figure()
        self._overlay_axes = fig.add_axes(self.get_position(True),
                                          frameon=False, projection=self.name,
                                          center_longitude=0,
                                          center_latitude=np.radians(plunge),
                                          label='overlay',
                                          rotation=bearing)
        self._overlay_axes._polar.remove()
        self._overlay_axes.format_coord = self._overlay_format_coord
        self._overlay_axes.grid(True)

Response: Adds an overlay to the current figure.


Instruction:
Write a Python 3 script for
setting the azimuthal tick locations.

Response:
def set_azimuth_ticks(self, angles, labels=None, frac=None, **kwargs):
        """
        Sets the azimuthal tick locations (Note: tick lines are not currently
        drawn or supported.).

        Parameters
        ----------
        angles : sequence of numbers
            The tick locations in degrees.
        labels : sequence of strings
            The tick label at each location.  Defaults to a formatted version
            of the specified angles.
        frac : number
            The radial location of the tick labels. 1.0 is the along the edge,
            1.1 would be outside, and 0.9 would be inside.
        **kwargs
            Additional parameters are text properties for the labels.
        """
        return self._polar.set_thetagrids(angles, labels, frac, **kwargs)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def set_azimuth_ticklabels(self, labels, fontdict=None, **kwargs):
        return self._polar.set_xticklabels(labels, fontdict, **kwargs)

Response: Sets the labels for the azimuthal ticks.


Instruction:
How would you code a function in Python 3 to
plot lines representing planes on the axes.

Response:
def plane(self, strike, dip, *args, **kwargs):
        """
        Plot lines representing planes on the axes. Additional arguments and
        keyword arguments are passed on to `ax.plot`.

        Parameters
        ----------
        strike, dip : number or sequences of numbers
            The strike and dip of the plane(s) in degrees. The dip direction is
            defined by the strike following the "right-hand rule".
        segments : int, optional
            The number of vertices to use for the line. Defaults to 100.
        **kwargs
            Additional parameters are passed on to `plot`.

        Returns
        -------
        A sequence of Line2D artists representing the lines specified by
        `strike` and `dip`.
        """
        segments = kwargs.pop('segments', 100)
        center = self._center_latitude, self._center_longitude
        lon, lat = stereonet_math.plane(strike, dip, segments, center)
        return self.plot(lon, lat, *args, **kwargs)


Instruction:
Implement a Python 3 function for
plotting points representing poles to planes on the axes.

Response:
def pole(self, strike, dip, *args, **kwargs):
        """
        Plot points representing poles to planes on the axes. Additional
        arguments and keyword arguments are passed on to `ax.plot`.

        Parameters
        ----------
        strike, dip : numbers or sequences of numbers
            The strike and dip of the plane(s) in degrees. The dip direction is
            defined by the strike following the "right-hand rule".
        **kwargs
            Additional parameters are passed on to `plot`.

        Returns
        -------
        A sequence of Line2D artists representing the point(s) specified by
        `strike` and `dip`.
        """
        lon, lat = stereonet_math.pole(strike, dip)
        args, kwargs = self._point_plot_defaults(args, kwargs)
        return self.plot(lon, lat, *args, **kwargs)


Instruction:
Here you have a function in Python 3, explain what it does
def rake(self, strike, dip, rake_angle, *args, **kwargs):
        lon, lat = stereonet_math.rake(strike, dip, rake_angle)
        args, kwargs = self._point_plot_defaults(args, kwargs)
        return self.plot(lon, lat, *args, **kwargs)

Response: Plot points along planes on the axes.


Instruction:
Can you generate the documentation for the following Python 3 function
def line(self, plunge, bearing, *args, **kwargs):
        lon, lat = stereonet_math.line(plunge, bearing)
        args, kwargs = self._point_plot_defaults(args, kwargs)
        return self.plot([lon], [lat], *args, **kwargs)

Response: Plot points representing linear features on the axes.


Instruction:
Can you generate the documentation for the following Python 3 function
def _point_plot_defaults(self, args, kwargs):
        if args:
            return args, kwargs

        if 'ls' not in kwargs and 'linestyle' not in kwargs:
            kwargs['linestyle'] = 'none'
        if 'marker' not in kwargs:
            kwargs['marker'] = 'o'
        return args, kwargs

Response: This function is used to set the default values for the point plot.


Instruction:
Implement a Python 3 function for
unifying defaults and common functionality of density_contour and .

Response:
def _contour_helper(self, args, kwargs):
        """Unify defaults and common functionality of ``density_contour`` and
        ``density_contourf``."""
        contour_kwargs = {}
        contour_kwargs['measurement'] = kwargs.pop('measurement', 'poles')
        contour_kwargs['method'] = kwargs.pop('method', 'exponential_kamb')
        contour_kwargs['sigma'] = kwargs.pop('sigma', 3)
        contour_kwargs['gridsize'] = kwargs.pop('gridsize', 100)
        contour_kwargs['weights'] = kwargs.pop('weights', None)
        lon, lat, totals = contouring.density_grid(*args, **contour_kwargs)
        return lon, lat, totals, kwargs


Instruction:
Can you create a Python 3 function that
estimates point density of the given linear orientation measurements (Interpreted as poles, lines, rakes, or "raw" longitudes and latitudes based on the `measurement` keyword argument.) and plots contour lines of the resulting density distribution. Parameters ---------- *args : A variable number of sequences of measurements. By default, this will be expected to be ``strike`` & ``dip``, both array-like sequences representing poles to planes. (Rake measurements require three parameters, thus the variable number of arguments.) The ``measurement`` kwarg controls how these arguments are interpreted. measurement : string, optional Controls how the input arguments are interpreted. Defaults to ``"poles"``. May be one of the following: ``"poles"`` : strikes, dips Arguments are assumed to be sequences of strikes and dips of planes. Poles to these planes are used for contouring. ``"lines"`` : plunges, bearings Arguments are assumed to be sequences of plunges and bearings of linear features. ``"rakes"`` : strikes, dips, rakes Arguments are assumed to be sequences of strikes, dips, and rakes along the plane. ``"radians"`` : lon, lat Arguments are assumed to be "raw" longitudes and latitudes in the stereonet's underlying coordinate system. method : string, optional The method of density estimation to use. Defaults to ``"exponential_kamb"``. May be one of the following: ``"exponential_kamb"`` : Kamb with exponential smoothing A modified Kamb method using exponential smoothing [1]_. Units are in numbers of standard deviations by which the density estimate differs from uniform. ``"linear_kamb"`` : Kamb with linear smoothing A modified Kamb method using linear smoothing [1]_. Units are in numbers of standard deviations by which the density estimate differs from uniform. ``"kamb"`` : Kamb with no smoothing Kamb's method [2]_ with no smoothing. Units are in numbers of standard deviations by which the density estimate differs from uniform. ``"schmidt"`` : 1% counts The traditional "Schmidt" (a.k.a. 1%) method. Counts points within a counting circle comprising 1% of the total area of the hemisphere. Does not take into account sample size. Units are in points per 1% area. sigma : int or float, optional The number of standard deviations defining the expected number of standard deviations by which a random sample from a uniform distribution of points would be expected to vary from being evenly distributed across the hemisphere. This controls the size of the counting circle, and therefore the degree of smoothing. Higher sigmas will lead to more smoothing of the resulting density distribution. This parameter only applies to Kamb-based methods. Defaults to 3. gridsize : int or 2-item tuple of ints, optional The size of the grid that the density is estimated on. If a single int is given, it is interpreted as an NxN grid. If a tuple of ints is given it is interpreted as (nrows, ncols). Defaults to 100. weights : array-like, optional The relative weight to be applied to each input measurement. The array will be normalized to sum to 1, so absolute value of the weights do not affect the result. Defaults to None. **kwargs Additional keyword arguments are passed on to matplotlib's `contour` function. Returns ------- A matplotlib ContourSet. See Also -------- mplstereonet.density_grid mplstereonet.StereonetAxes.density_contourf matplotlib.pyplot.contour matplotlib.pyplot.clabel Examples -------- Plot density contours of poles to the specified planes using a modified Kamb method with exponential smoothing [1]_. >>> strikes, dips = [120, 315, 86], [22, 85, 31] >>> ax.density_contour(strikes, dips) Plot density contours of a set of linear orientation measurements. >>> plunges, bearings = [-10, 20, -30], [120, 315, 86] >>> ax.density_contour(plunges, bearings, measurement='lines') Plot density contours of a set of rake measurements. >>> strikes, dips, rakes = [120, 315, 86], [22, 85, 31], [-5, 20, 9] >>> ax.density_contour(strikes, dips, rakes, measurement='rakes') Plot density contours of a set of "raw" longitudes and latitudes. >>> lon, lat = np.radians([-40, 30, -85]), np.radians([21, -59, 45]) >>> ax.density_contour(lon, lat, measurement='radians') Plot density contours of poles to planes using a Kamb method [2]_ with the density estimated on a 10x10 grid (in long-lat space) >>> strikes, dips = [120, 315, 86], [22, 85, 31] >>> ax.density_contour(strikes, dips, method='kamb', gridsize=10) Plot density contours of poles to planes with contours at [1,2,3] standard deviations. >>> strikes, dips = [120, 315, 86], [22, 85, 31] >>> ax.density_contour(strikes, dips, levels=[1,2,3]) References ---------- .. [1] Vollmer, 1995. C Program for Automatic Contouring of Spherical Orientation Data Using a Modified Kamb Method. Computers & Geosciences, Vol. 21, No. 1, pp. 31--49. .. [2] Kamb, 1959. Ice Petrofabric Observations from Blue Glacier, Washington, in Relation to Theory and Experiment. Journal of Geophysical Research, Vol. 64, No. 11, pp. 1891--1909.

Response:
def density_contour(self, *args, **kwargs):
        """
        Estimates point density of the given linear orientation measurements
        (Interpreted as poles, lines, rakes, or "raw" longitudes and latitudes
        based on the `measurement` keyword argument.) and plots contour lines of
        the resulting density distribution.

        Parameters
        ----------
        *args : A variable number of sequences of measurements.
            By default, this will be expected to be ``strike`` & ``dip``, both
            array-like sequences representing poles to planes.  (Rake
            measurements require three parameters, thus the variable number of
            arguments.) The ``measurement`` kwarg controls how these arguments
            are interpreted.

        measurement : string, optional
            Controls how the input arguments are interpreted. Defaults to
            ``"poles"``.  May be one of the following:

                ``"poles"`` : strikes, dips
                    Arguments are assumed to be sequences of strikes and dips
                    of planes. Poles to these planes are used for contouring.
                ``"lines"`` : plunges, bearings
                    Arguments are assumed to be sequences of plunges and
                    bearings of linear features.
                ``"rakes"`` : strikes, dips, rakes
                    Arguments are assumed to be sequences of strikes, dips, and
                    rakes along the plane.
                ``"radians"`` : lon, lat
                    Arguments are assumed to be "raw" longitudes and latitudes
                    in the stereonet's underlying coordinate system.

        method : string, optional
            The method of density estimation to use. Defaults to
            ``"exponential_kamb"``. May be one of the following:

            ``"exponential_kamb"`` : Kamb with exponential smoothing
                A modified Kamb method using exponential smoothing [1]_. Units
                are in numbers of standard deviations by which the density
                estimate differs from uniform.
            ``"linear_kamb"`` : Kamb with linear smoothing
                A modified Kamb method using linear smoothing [1]_.  Units are
                in numbers of standard deviations by which the density estimate
                differs from uniform.
            ``"kamb"`` : Kamb with no smoothing
                Kamb's method [2]_ with no smoothing. Units are in numbers of
                standard deviations by which the density estimate differs from
                uniform.
            ``"schmidt"`` : 1% counts
                The traditional "Schmidt" (a.k.a. 1%) method. Counts points
                within a counting circle comprising 1% of the total area of the
                hemisphere. Does not take into account sample size.  Units are
                in points per 1% area.

        sigma : int or float, optional
            The number of standard deviations defining the expected number of
            standard deviations by which a random sample from a uniform
            distribution of points would be expected to vary from being evenly
            distributed across the hemisphere.  This controls the size of the
            counting circle, and therefore the degree of smoothing.  Higher
            sigmas will lead to more smoothing of the resulting density
            distribution. This parameter only applies to Kamb-based methods.
            Defaults to 3.

        gridsize : int or 2-item tuple of ints, optional
            The size of the grid that the density is estimated on. If a single
            int is given, it is interpreted as an NxN grid. If a tuple of ints
            is given it is interpreted as (nrows, ncols).  Defaults to 100.

        weights : array-like, optional
            The relative weight to be applied to each input measurement. The
            array will be normalized to sum to 1, so absolute value of the
            weights do not affect the result. Defaults to None.

        **kwargs
            Additional keyword arguments are passed on to matplotlib's
            `contour` function.

        Returns
        -------
        A matplotlib ContourSet.

        See Also
        --------
        mplstereonet.density_grid
        mplstereonet.StereonetAxes.density_contourf
        matplotlib.pyplot.contour
        matplotlib.pyplot.clabel

        Examples
        --------
        Plot density contours of poles to the specified planes using a
        modified Kamb method with exponential smoothing [1]_.

        >>> strikes, dips = [120, 315, 86], [22, 85, 31]
        >>> ax.density_contour(strikes, dips)

        Plot density contours of a set of linear orientation measurements.

        >>> plunges, bearings = [-10, 20, -30], [120, 315, 86]
        >>> ax.density_contour(plunges, bearings, measurement='lines')

        Plot density contours of a set of rake measurements.

        >>> strikes, dips, rakes = [120, 315, 86], [22, 85, 31], [-5, 20, 9]
        >>> ax.density_contour(strikes, dips, rakes, measurement='rakes')

        Plot density contours of a set of "raw" longitudes and latitudes.

        >>> lon, lat = np.radians([-40, 30, -85]), np.radians([21, -59, 45])
        >>> ax.density_contour(lon, lat, measurement='radians')

        Plot density contours of poles to planes using a Kamb method [2]_
        with the density estimated on a 10x10 grid (in long-lat space)

        >>> strikes, dips = [120, 315, 86], [22, 85, 31]
        >>> ax.density_contour(strikes, dips, method='kamb', gridsize=10)

        Plot density contours of poles to planes with contours at [1,2,3]
        standard deviations.

        >>> strikes, dips = [120, 315, 86], [22, 85, 31]
        >>> ax.density_contour(strikes, dips, levels=[1,2,3])

        References
        ----------
        .. [1] Vollmer, 1995. C Program for Automatic Contouring of Spherical
           Orientation Data Using a Modified Kamb Method. Computers &
           Geosciences, Vol. 21, No. 1, pp. 31--49.

        .. [2] Kamb, 1959. Ice Petrofabric Observations from Blue Glacier,
           Washington, in Relation to Theory and Experiment. Journal of
           Geophysical Research, Vol. 64, No. 11, pp. 1891--1909.
        """
        lon, lat, totals, kwargs = self._contour_helper(args, kwargs)
        return self.contour(lon, lat, totals, **kwargs)


Instruction:
Implement a Python 3 function for
estimating point density of the given linear orientation measurements (Interpreted as poles, lines, rakes, or "raw" longitudes and latitudes based on the `measurement` keyword argument.) and plots filled contours of the resulting density distribution. Parameters ---------- *args : A variable number of sequences of measurements. By default, this will be expected to be ``strike`` & ``dip``, both array-like sequences representing poles to planes. (Rake measurements require three parameters, thus the variable number of arguments.) The ``measurement`` kwarg controls how these arguments are interpreted. measurement : string, optional Controls how the input arguments are interpreted. Defaults to ``"poles"``. May be one of the following: ``"poles"`` : strikes, dips Arguments are assumed to be sequences of strikes and dips of planes. Poles to these planes are used for contouring. ``"lines"`` : plunges, bearings Arguments are assumed to be sequences of plunges and bearings of linear features. ``"rakes"`` : strikes, dips, rakes Arguments are assumed to be sequences of strikes, dips, and rakes along the plane. ``"radians"`` : lon, lat Arguments are assumed to be "raw" longitudes and latitudes in the stereonet's underlying coordinate system. method : string, optional The method of density estimation to use. Defaults to ``"exponential_kamb"``. May be one of the following: ``"exponential_kamb"`` : Kamb with exponential smoothing A modified Kamb method using exponential smoothing [1]_. Units are in numbers of standard deviations by which the density estimate differs from uniform. ``"linear_kamb"`` : Kamb with linear smoothing A modified Kamb method using linear smoothing [1]_. Units are in numbers of standard deviations by which the density estimate differs from uniform. ``"kamb"`` : Kamb with no smoothing Kamb's method [2]_ with no smoothing. Units are in numbers of standard deviations by which the density estimate differs from uniform. ``"schmidt"`` : 1% counts The traditional "Schmidt" (a.k.a. 1%) method. Counts points within a counting circle comprising 1% of the total area of the hemisphere. Does not take into account sample size. Units are in points per 1% area. sigma : int or float, optional The number of standard deviations defining the expected number of standard deviations by which a random sample from a uniform distribution of points would be expected to vary from being evenly distributed across the hemisphere. This controls the size of the counting circle, and therefore the degree of smoothing. Higher sigmas will lead to more smoothing of the resulting density distribution. This parameter only applies to Kamb-based methods. Defaults to 3. gridsize : int or 2-item tuple of ints, optional The size of the grid that the density is estimated on. If a single int is given, it is interpreted as an NxN grid. If a tuple of ints is given it is interpreted as (nrows, ncols). Defaults to 100. weights : array-like, optional The relative weight to be applied to each input measurement. The array will be normalized to sum to 1, so absolute value of the weights do not affect the result. Defaults to None. **kwargs Additional keyword arguments are passed on to matplotlib's `contourf` function. Returns ------- A matplotlib `QuadContourSet`. See Also -------- mplstereonet.density_grid mplstereonet.StereonetAxes.density_contour matplotlib.pyplot.contourf matplotlib.pyplot.clabel Examples -------- Plot filled density contours of poles to the specified planes using a modified Kamb method with exponential smoothing [1]_. >>> strikes, dips = [120, 315, 86], [22, 85, 31] >>> ax.density_contourf(strikes, dips) Plot filled density contours of a set of linear orientation measurements. >>> plunges, bearings = [-10, 20, -30], [120, 315, 86] >>> ax.density_contourf(plunges, bearings, measurement='lines') Plot filled density contours of a set of rake measurements. >>> strikes, dips, rakes = [120, 315, 86], [22, 85, 31], [-5, 20, 9] >>> ax.density_contourf(strikes, dips, rakes, measurement='rakes') Plot filled density contours of a set of "raw" longitudes and latitudes. >>> lon, lat = np.radians([-40, 30, -85]), np.radians([21, -59, 45]) >>> ax.density_contourf(lon, lat, measurement='radians') Plot filled density contours of poles to planes using a Kamb method [2]_ with the density estimated on a 10x10 grid (in long-lat space) >>> strikes, dips = [120, 315, 86], [22, 85, 31] >>> ax.density_contourf(strikes, dips, method='kamb', gridsize=10) Plot filled density contours of poles to planes with contours at [1,2,3] standard deviations. >>> strikes, dips = [120, 315, 86], [22, 85, 31] >>> ax.density_contourf(strikes, dips, levels=[1,2,3]) References ---------- .. [1] Vollmer, 1995. C Program for Automatic Contouring of Spherical Orientation Data Using a Modified Kamb Method. Computers & Geosciences, Vol. 21, No. 1, pp. 31--49. .. [2] Kamb, 1959. Ice Petrofabric Observations from Blue Glacier, Washington, in Relation to Theory and Experiment. Journal of Geophysical Research, Vol. 64, No. 11, pp. 1891--1909.

Response:
def density_contourf(self, *args, **kwargs):
        """
        Estimates point density of the given linear orientation measurements
        (Interpreted as poles, lines, rakes, or "raw" longitudes and latitudes
        based on the `measurement` keyword argument.) and plots filled contours
        of the resulting density distribution.

        Parameters
        ----------
        *args : A variable number of sequences of measurements.
            By default, this will be expected to be ``strike`` & ``dip``, both
            array-like sequences representing poles to planes.  (Rake
            measurements require three parameters, thus the variable number of
            arguments.) The ``measurement`` kwarg controls how these arguments
            are interpreted.

        measurement : string, optional
            Controls how the input arguments are interpreted. Defaults to
            ``"poles"``.  May be one of the following:

                ``"poles"`` : strikes, dips
                    Arguments are assumed to be sequences of strikes and dips
                    of planes. Poles to these planes are used for contouring.
                ``"lines"`` : plunges, bearings
                    Arguments are assumed to be sequences of plunges and
                    bearings of linear features.
                ``"rakes"`` : strikes, dips, rakes
                    Arguments are assumed to be sequences of strikes, dips, and
                    rakes along the plane.
                ``"radians"`` : lon, lat
                    Arguments are assumed to be "raw" longitudes and latitudes
                    in the stereonet's underlying coordinate system.

        method : string, optional
            The method of density estimation to use. Defaults to
            ``"exponential_kamb"``. May be one of the following:

            ``"exponential_kamb"`` : Kamb with exponential smoothing
                A modified Kamb method using exponential smoothing [1]_. Units
                are in numbers of standard deviations by which the density
                estimate differs from uniform.
            ``"linear_kamb"`` : Kamb with linear smoothing
                A modified Kamb method using linear smoothing [1]_.  Units are
                in numbers of standard deviations by which the density estimate
                differs from uniform.
            ``"kamb"`` : Kamb with no smoothing
                Kamb's method [2]_ with no smoothing. Units are in numbers of
                standard deviations by which the density estimate differs from
                uniform.
            ``"schmidt"`` : 1% counts
                The traditional "Schmidt" (a.k.a. 1%) method. Counts points
                within a counting circle comprising 1% of the total area of the
                hemisphere. Does not take into account sample size.  Units are
                in points per 1% area.

        sigma : int or float, optional
            The number of standard deviations defining the expected number of
            standard deviations by which a random sample from a uniform
            distribution of points would be expected to vary from being evenly
            distributed across the hemisphere.  This controls the size of the
            counting circle, and therefore the degree of smoothing.  Higher
            sigmas will lead to more smoothing of the resulting density
            distribution. This parameter only applies to Kamb-based methods.
            Defaults to 3.

        gridsize : int or 2-item tuple of ints, optional
            The size of the grid that the density is estimated on. If a single
            int is given, it is interpreted as an NxN grid. If a tuple of ints
            is given it is interpreted as (nrows, ncols).  Defaults to 100.

        weights : array-like, optional
            The relative weight to be applied to each input measurement. The
            array will be normalized to sum to 1, so absolute value of the
            weights do not affect the result. Defaults to None.

        **kwargs
            Additional keyword arguments are passed on to matplotlib's
            `contourf` function.

        Returns
        -------
        A matplotlib `QuadContourSet`.

        See Also
        --------
        mplstereonet.density_grid
        mplstereonet.StereonetAxes.density_contour
        matplotlib.pyplot.contourf
        matplotlib.pyplot.clabel

        Examples
        --------
        Plot filled density contours of poles to the specified planes using
        a modified Kamb method with exponential smoothing [1]_.

        >>> strikes, dips = [120, 315, 86], [22, 85, 31]
        >>> ax.density_contourf(strikes, dips)

        Plot filled density contours of a set of linear orientation
        measurements.

        >>> plunges, bearings = [-10, 20, -30], [120, 315, 86]
        >>> ax.density_contourf(plunges, bearings, measurement='lines')

        Plot filled density contours of a set of rake measurements.

        >>> strikes, dips, rakes = [120, 315, 86], [22, 85, 31], [-5, 20, 9]
        >>> ax.density_contourf(strikes, dips, rakes, measurement='rakes')

        Plot filled density contours of a set of "raw" longitudes and
        latitudes.

        >>> lon, lat = np.radians([-40, 30, -85]), np.radians([21, -59, 45])
        >>> ax.density_contourf(lon, lat, measurement='radians')

        Plot filled density contours of poles to planes using a Kamb method
        [2]_ with the density estimated on a 10x10 grid (in long-lat space)

        >>> strikes, dips = [120, 315, 86], [22, 85, 31]
        >>> ax.density_contourf(strikes, dips, method='kamb', gridsize=10)

        Plot filled density contours of poles to planes with contours at
        [1,2,3] standard deviations.

        >>> strikes, dips = [120, 315, 86], [22, 85, 31]
        >>> ax.density_contourf(strikes, dips, levels=[1,2,3])

        References
        ----------
        .. [1] Vollmer, 1995. C Program for Automatic Contouring of Spherical
           Orientation Data Using a Modified Kamb Method. Computers &
           Geosciences, Vol. 21, No. 1, pp. 31--49.

        .. [2] Kamb, 1959. Ice Petrofabric Observations from Blue Glacier,
           Washington, in Relation to Theory and Experiment. Journal of
           Geophysical Research, Vol. 64, No. 11, pp. 1891--1909.
        """
        lon, lat, totals, kwargs = self._contour_helper(args, kwargs)
        return self.contourf(lon, lat, totals, **kwargs)


Instruction:
Can you create a Python 3 function that
sets up a basic stereonet and plot the same data each time.

Response:
def basic():
    """Set up a basic stereonet and plot the same data each time."""
    fig, ax = mplstereonet.subplots()

    strike, dip = 315, 30
    ax.plane(strike, dip, color='lightblue')
    ax.pole(strike, dip, color='green', markersize=15)
    ax.rake(strike, dip, 40, marker='*', markersize=20, color='green')

    # Make a bit of room for the title...
    fig.subplots_adjust(top=0.8)

    return ax


Instruction:
Make a summary of the following Python 3 code
def stereonet_projection_explanation(ax):
    ax.set_title('Dip and Azimuth', y=1.1, size=18)

    # Set the azimuth ticks to be just "N", "E", etc.
    ax.set_azimuth_ticks(range(0, 360, 10))

    # Hackishly set some of the azimuth labels to North, East, etc...
    fmt = ax.yaxis.get_major_formatter()
    labels = [fmt(item) for item in ax.get_azimuth_ticks()]
    labels[0] = 'North'
    labels[9] = 'East'
    labels[18] = 'South'
    labels[27] = 'West'
    ax.set_azimuth_ticklabels(labels)

    # Unhide the xticklabels and use them for dip labels
    ax.xaxis.set_tick_params(label1On=True)
    labels = list(range(10, 100, 10)) + list(range(80, 0, -10))
    ax.set_xticks(np.radians(np.arange(-80, 90, 10)))
    ax.set_xticklabels([fmt(np.radians(item)) for item in labels])

    ax.set_xlabel('Dip or Plunge')

    xlabel_halo(ax)
    return ax

Response: Example to explain azimuth and dip on a lower - helisphere stereonet.


Instruction:
How would you explain what the following Python 3 function does
def native_projection_explanation(ax):
    ax.set_title('Longitude and Latitude', size=18, y=1.1)

    # Hide the azimuth labels
    ax.set_azimuth_ticklabels([])

    # Make the axis tick labels visible:
    ax.set_xticks(np.radians(np.arange(-80, 90, 10)))
    ax.tick_params(label1On=True)

    ax.set_xlabel('Longitude')

    xlabel_halo(ax)
    return ax

Response:
Example showing how the native longitude and latitude relate to the
    stereonet projection.


Instruction:
Given the following Python 3 function, write the documentation
def xlabel_halo(ax):
    import matplotlib.patheffects as effects
    for tick in ax.get_xticklabels() + [ax.xaxis.label]:
        tick.set_path_effects([effects.withStroke(linewidth=4, foreground='w')])

Response: Add a white halo around the xlabels.


Instruction:
Given the following Python 3 function, write the documentation
def parse_strike_dip(strike, dip):
    strike = parse_azimuth(strike)
    dip, direction = split_trailing_letters(dip)

    if direction is not None:
        expected_direc = strike + 90
        if opposite_end(expected_direc, direction):
            strike += 180

    if strike > 360:
        strike -= 360

    return strike, dip

Response: Parses the strike and dip measurement strings and returns the strike and dip measurements.


Instruction:
Write a Python 3 function for
parsing a strike and dip measurement and returns a strike dip and rake.

Response:
def parse_rake(strike, dip, rake):
    """
    Parses strings of strike, dip, and rake and returns a strike, dip, and rake
    measurement following the right-hand-rule, with the "end" of the strike
    that the rake is measured from indicated by the sign of the rake (positive
    rakes correspond to the strike direction, negative rakes correspond to the
    opposite end).

    Accepts either quadrant-formatted or azimuth-formatted strikes.

    For example, this would convert a strike of "N30E", dip of "45NW", with a
    rake of "10NE" to a strike of 210, dip of 45, and rake of 170.

    Rake angles returned by this function will always be between 0 and 180

    If no directions are specified, the measuriement is assumed to follow the
    usual right-hand-rule convention.

    Parameters
    ----------
    strike : string
        A strike measurement. May be in azimuth or quadrant format.
    dip : string
        The dip angle and direction of a plane.
    rake : string
        The rake angle and direction that the rake is measured from.

    Returns
    -------
    strike, dip, rake : floats
        Measurements of strike, dip, and rake following the conventions
        outlined above.
    """
    strike, dip = parse_strike_dip(strike, dip)
    rake, direction = split_trailing_letters(rake)

    if direction is not None:
        if opposite_end(strike, direction):
            rake = -rake

    if rake < 0:
        rake += 180
    elif rake > 180:
        rake -= 180

    return strike, dip, rake


Instruction:
Write a Python 3 script for
parsing a string of plunge and bearing and returns a consistent plunge and bearing measurement as floats.

Response:
def parse_plunge_bearing(plunge, bearing):
    """
    Parses strings of plunge and bearing and returns a consistent plunge and
    bearing measurement as floats. Plunge angles returned by this function will
    always be between 0 and 90.

    If no direction letter(s) is present, the plunge is assumed to be measured
    from the end specified by the bearing. If a direction letter(s) is present,
    the bearing will be switched to the opposite (180 degrees) end if the
    specified direction corresponds to the opposite end specified by the
    bearing.

    Parameters
    ----------
    plunge : string
        A plunge measurement.
    bearing : string
        A bearing measurement. May be in azimuth or quadrant format.

    Returns
    -------
    plunge, bearing: floats
        The plunge and bearing following the conventions outlined above.

    Examples
    ---------

        >>> parse_plunge_bearing("30NW", 160)
        ... (30, 340)

    """
    bearing = parse_azimuth(bearing)
    plunge, direction = split_trailing_letters(plunge)

    if direction is not None:
        if opposite_end(bearing, direction):
            bearing +=180

    if plunge < 0:
        bearing += 180
        plunge = -plunge
    if plunge > 90:
        bearing += 180
        plunge = 180 - plunge

    if bearing > 360:
        bearing -= 360

    return plunge, bearing


Instruction:
Can you create a Python 3 function that
converts a planar measurment of dip direction using the dip - azimuth convention into a strike using the right - hand - rule.

Response:
def dip_direction2strike(azimuth):
    """
    Converts a planar measurment of dip direction using the dip-azimuth
    convention into a strike using the right-hand-rule.

    Parameters
    ----------
    azimuth : number or string
        The dip direction of the plane in degrees. This can be either a
        numerical azimuth in the 0-360 range or a string representing a quadrant
        measurement (e.g. N30W).

    Returns
    -------
    strike : number
        The strike of the plane in degrees following the right-hand-rule.
    """
    azimuth = parse_azimuth(azimuth)
    strike = azimuth - 90
    if strike < 0:
        strike += 360
    return strike


Instruction:
Can you generate the documentation for the following Python 3 function
def strike2dip_direction(strike):
    strike = parse_azimuth(strike)
    dip_direction = strike + 90
    if dip_direction > 360:
        dip_direction -= 360
    return dip_direction

Response: Converts a planar measurement of strike using the right - hand - rule into the dip - direction that the plane dips.


Instruction:
Can you tell what is the following Python 3 function doing
def parse_azimuth(azimuth):
    try:
        azimuth = float(azimuth)
    except ValueError:
        if not azimuth[0].isalpha():
            raise ValueError('Ambiguous azimuth: {}'.format(azimuth))
        azimuth = parse_quadrant_measurement(azimuth)
    return azimuth

Response: Parses an azimuth measurement in azimuth or quadrant format.


Instruction:
How would you implement a function in Python 3 that
parses a measurement of the form AxxB or AxxB into an azimuth of the next 260 degrees.

Response:
def parse_quadrant_measurement(quad_azimuth):
    """
    Parses a quadrant measurement of the form "AxxB", where A and B are cardinal
    directions and xx is an angle measured relative to those directions.

    In other words, it converts a measurement such as E30N into an azimuth of
    60 degrees, or W10S into an azimuth of 260 degrees.

    For ambiguous quadrant measurements such as "N30S", a ValueError is raised.

    Parameters
    -----------
    quad_azimuth : string
        An azimuth measurement in quadrant form.

    Returns
    -------
    azi : float
        An azimuth in degrees clockwise from north.

    See Also
    --------
    parse_azimuth
    """
    def rotation_direction(first, second):
        return np.cross(_azimuth2vec(first), _azimuth2vec(second))

    # Parse measurement
    quad_azimuth = quad_azimuth.strip()
    try:
        first_dir = quadrantletter_to_azimuth(quad_azimuth[0].upper())
        sec_dir = quadrantletter_to_azimuth(quad_azimuth[-1].upper())
    except KeyError:
        raise ValueError('{} is not a valid azimuth'.format(quad_azimuth))

    angle = float(quad_azimuth[1:-1])

    # Convert quadrant measurement into an azimuth
    direc = rotation_direction(first_dir, sec_dir)
    azi = first_dir + direc * angle

    # Catch ambiguous measurements such as N10S and raise an error
    if abs(direc) < 0.9:
        raise ValueError('{} is not a valid azimuth'.format(quad_azimuth))

    # Ensure that 0 <= azi <= 360
    if azi < 0:
        azi += 360
    elif azi > 360:
        azi -= 360

    return azi


Instruction:
How would you implement a function in Python 3 that
returns the inverse of the transform.

Response:
def inverted(self):
        """Return the inverse of the transform."""
        # This is a bit of hackery so that we can put a single "inverse"
        # function here. If we just made "self._inverse_type" point to the class
        # in question, it wouldn't be defined yet. This way, it's done at
        # at runtime and we avoid the definition problem. Hackish, but better
        # than repeating code everywhere or making a relatively complex
        # metaclass.
        inverse_type = globals()[self._inverse_type]
        return inverse_type(self._center_longitude, self._center_latitude,
                            self._resolution)


Instruction:
Can you tell what is the following Python 3 function doing
def sph2cart(lon, lat):
    x = np.cos(lat)*np.cos(lon)
    y = np.cos(lat)*np.sin(lon)
    z = np.sin(lat)
    return x, y, z

Response:
Converts a longitude and latitude given in
    _radians_ to cartesian coordinates.


Instruction:
Create a Python 3 function to
convert cartesian coordinates x y z into a longitude and latitude in radians.

Response:
def cart2sph(x, y, z):
    """
    Converts cartesian coordinates `x`, `y`, `z` into a longitude and latitude.
    x=0, y=0, z=0 is assumed to correspond to the center of the globe.
    Returns lon and lat in radians.

    Parameters
    ----------
    `x`, `y`, `z` : Arrays of cartesian coordinates

    Returns
    -------
    lon : Longitude in radians
    lat : Latitude in radians
    """
    r = np.sqrt(x**2 + y**2 + z**2)
    lat = np.arcsin(z/r)
    lon = np.arctan2(y, x)
    return lon, lat


Instruction:
Can you write a function in Python 3 where it
rotates a node on a given axis by the given angle.

Response:
def _rotate(lon, lat, theta, axis='x'):
    """
    Rotate "lon", "lat" coords (in _degrees_) about the X-axis by "theta"
    degrees.  This effectively simulates rotating a physical stereonet.
    Returns rotated lon, lat coords in _radians_).
    """
    # Convert input to numpy arrays in radians
    lon, lat = np.atleast_1d(lon, lat)
    lon, lat = map(np.radians, [lon, lat])
    theta = np.radians(theta)

    # Convert to cartesian coords for the rotation
    x, y, z = sph2cart(lon, lat)

    lookup = {'x':_rotate_x, 'y':_rotate_y, 'z':_rotate_z}
    X, Y, Z = lookup[axis](x, y, z, theta)

    # Now convert back to spherical coords (longitude and latitude, ignore R)
    lon, lat = cart2sph(X,Y,Z)
    return lon, lat


Instruction:
Implement a function in Python 3 to
calculate the antipode of the given point or sequence of numbers lon lat.

Response:
def antipode(lon, lat):
    """
    Calculates the antipode (opposite point on the globe) of the given point or
    points. Input and output is expected to be in radians.

    Parameters
    ----------
    lon : number or sequence of numbers
        Longitude in radians
    lat : number or sequence of numbers
        Latitude in radians

    Returns
    -------
    lon, lat : arrays
        Sequences (regardless of whether or not the input was a single value or
        a sequence) of longitude and latitude in radians.
    """
    x, y, z = sph2cart(lon, lat)
    return cart2sph(-x, -y, -z)


Instruction:
Write a Python 3 script for
calculating the longitude and latitude of each plane in the base set of points.

Response:
def plane(strike, dip, segments=100, center=(0, 0)):
    """
    Calculates the longitude and latitude of `segments` points along the
    stereonet projection of each plane with a given `strike` and `dip` in
    degrees.  Returns points for one hemisphere only.

    Parameters
    ----------
    strike : number or sequence of numbers
        The strike of the plane(s) in degrees, with dip direction indicated by
        the azimuth (e.g. 315 vs. 135) specified following the "right hand
        rule".
    dip : number or sequence of numbers
        The dip of the plane(s) in degrees.
    segments : number or sequence of numbers
        The number of points in the returned `lon` and `lat` arrays.  Defaults
        to 100 segments.
    center : sequence of two numbers (lon, lat)
        The longitude and latitude of the center of the hemisphere that the
        returned points will be in. Defaults to 0,0 (approriate for a typical
        stereonet).

    Returns
    -------
    lon, lat : arrays
        `num_segments` x `num_strikes` arrays of longitude and latitude in
        radians.
    """
    lon0, lat0 = center
    strikes, dips = np.atleast_1d(strike, dip)
    lons = np.zeros((segments, strikes.size), dtype=np.float)
    lats = lons.copy()
    for i, (strike, dip) in enumerate(zip(strikes, dips)):
        # We just plot a line of constant longitude and rotate it by the strike.
        dip = 90 - dip
        lon = dip * np.ones(segments)
        lat = np.linspace(-90, 90, segments)
        lon, lat = _rotate(lon, lat, strike)

        if lat0 != 0 or lon0 != 0:
            dist = angular_distance([lon, lat], [lon0, lat0], False)
            mask = dist > (np.pi / 2)
            lon[mask], lat[mask] = antipode(lon[mask], lat[mask])
            change = np.diff(mask.astype(int))
            ind = np.flatnonzero(change) + 1
            lat = np.hstack(np.split(lat, ind)[::-1])
            lon = np.hstack(np.split(lon, ind)[::-1])

        lons[:,i] = lon
        lats[:,i] = lat

    return lons, lats


Instruction:
Make a summary of the following Python 3 code
def pole(strike, dip):
    strike, dip = np.atleast_1d(strike, dip)
    mask = dip > 90
    dip[mask] = 180 - dip[mask]
    strike[mask] += 180
    # Plot the approriate point for a strike of 0 and rotate it
    lon, lat = -dip, 0.0
    lon, lat = _rotate(lon, lat, strike)
    return lon, lat

Response: Calculates the longitude and latitude of the pole to the plane.


Instruction:
Explain what the following Python 3 code does
def rake(strike, dip, rake_angle):
    strike, dip, rake_angle = np.atleast_1d(strike, dip, rake_angle)
    # Plot the approriate point for a strike of 0 and rotate it
    dip = 90 - dip
    lon = dip

    rake_angle = rake_angle.copy()
    rake_angle[rake_angle < 0] += 180
    lat = 90 - rake_angle

    lon, lat = _rotate(lon, lat, strike)
    return lon, lat

Response: Calculates the longitude and latitude of the linear feature specified by strike dip and rake_angle.


Instruction:
Here you have a function in Python 3, explain what it does
def line(plunge, bearing):
    plunge, bearing = np.atleast_1d(plunge, bearing)
    # Plot the approriate point for a bearing of 0 and rotate it
    lat = 90 - plunge
    lon = 0
    lon, lat = _rotate(lon, lat, bearing)
    return lon, lat

Response: Calculates the longitude and latitude of the linear feature specified by the plunge and bearing.


Instruction:
How would you explain what the following Python 3 function does
def cone(plunge, bearing, angle, segments=100):
    plunges, bearings, angles = np.atleast_1d(plunge, bearing, angle)
    lons, lats = [], []
    for plunge, bearing, angle in zip(plunges, bearings, angles):
        lat = (90 - angle) * np.ones(segments, dtype=float)
        lon = np.linspace(-180, 180, segments)
        lon, lat = _rotate(lon, lat, -plunge, axis='y')
        lon, lat = _rotate(np.degrees(lon), np.degrees(lat), bearing, axis='x')
        lons.append(lon)
        lats.append(lat)
    return np.vstack(lons), np.vstack(lats)

Response: Calculates the longitude and latitude of a small circle.


Instruction:
Write a Python 3 script for
converting the given plunge and bearing in degrees to a strike and dip tuple.

Response:
def plunge_bearing2pole(plunge, bearing):
    """
    Converts the given `plunge` and `bearing` in degrees to a strike and dip
    of the plane whose pole would be parallel to the line specified. (i.e. The
    pole to the plane returned would plot at the same point as the specified
    plunge and bearing.)

    Parameters
    ----------
    plunge : number or sequence of numbers
        The plunge of the line(s) in degrees. The plunge is measured in degrees
        downward from the end of the feature specified by the bearing.
    bearing : number or sequence of numbers
        The bearing (azimuth) of the line(s) in degrees.

    Returns
    -------
    strike, dip : arrays
        Arrays of strikes and dips in degrees following the right-hand-rule.
    """
    plunge, bearing = np.atleast_1d(plunge, bearing)
    strike = bearing + 90
    dip = 90 - plunge
    strike[strike >= 360] -= 360
    return strike, dip


Instruction:
Given the following Python 3 function, write the documentation
def pole2plunge_bearing(strike, dip):
    strike, dip = np.atleast_1d(strike, dip)
    bearing = strike - 90
    plunge = 90 - dip
    bearing[bearing < 0] += 360
    return plunge, bearing

Response:
Converts the given strike and dip in dgrees of a plane to a plunge
    and bearing of its pole.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def mean_vector(lons, lats):
    xyz = sph2cart(lons, lats)
    xyz = np.vstack(xyz).T
    mean_vec = xyz.mean(axis=0)
    r_value = np.linalg.norm(mean_vec)
    mean_vec = cart2sph(*mean_vec)
    return mean_vec, r_value

Response: Returns the resultant vector from a series of longitudes and latitudes.


Instruction:
Can you generate the documentation for the following Python 3 function
def fisher_stats(lons, lats, conf=95):
    xyz = sph2cart(lons, lats)
    xyz = np.vstack(xyz).T
    mean_vec = xyz.mean(axis=0)
    r_value = np.linalg.norm(mean_vec)
    num = xyz.shape[0]
    mean_vec = cart2sph(*mean_vec)

    if num > 1:
        p = (100.0 - conf) / 100.0
        vector_sum = xyz.sum(axis=0)
        result_vect = np.sqrt(np.sum(np.square(vector_sum)))
        fract1 = (num - result_vect) / result_vect
        fract3 = 1.0 / (num - 1.0)
        angle = np.arccos(1 - fract1 * ((1 / p) ** fract3 - 1))
        angle = np.degrees(angle)
        kappa = (num - 1.0) / (num - result_vect)
        return mean_vec, (r_value, angle, kappa)
    else:
        return None, None

Response: Function that calculates the Fisher statistics for a set of longitudes and latitudes.


Instruction:
Given the following Python 3 function, write the documentation
def geographic2pole(lon, lat):
    plunge, bearing = geographic2plunge_bearing(lon, lat)
    strike = bearing + 90
    strike[strike >= 360] -= 360
    dip = 90 - plunge
    return strike, dip

Response: Converts a longitude and latitude from a stereonet into a strike and dip tuple.


Instruction:
Write a Python 3 script for
converting longitude and latitude in stereonet coordinates into plunge and bearing arrays.

Response:
def geographic2plunge_bearing(lon, lat):
    """
    Converts longitude and latitude in stereonet coordinates into a
    plunge/bearing.

    Parameters
    ----------
    lon, lat : numbers or sequences of numbers
        Longitudes and latitudes in radians as measured from a
        lower-hemisphere stereonet

    Returns
    -------
    plunge : array
        The plunge of the vector in degrees downward from horizontal.
    bearing : array
        The bearing of the vector in degrees clockwise from north.
    """
    lon, lat = np.atleast_1d(lon, lat)
    x, y, z = sph2cart(lon, lat)

    # Bearing will be in the y-z plane...
    bearing = np.arctan2(z, y)

    # Plunge is the angle between the line and the y-z plane
    r = np.sqrt(x*x + y*y + z*z)
    r[r == 0] = 1e-15
    plunge = np.arcsin(x / r)

    # Convert back to azimuths in degrees..
    plunge, bearing = np.degrees(plunge), np.degrees(bearing)
    bearing = 90 - bearing
    bearing[bearing < 0] += 360

    # If the plunge angle is upwards, get the opposite end of the line
    upwards = plunge < 0
    plunge[upwards] *= -1
    bearing[upwards] -= 180
    bearing[upwards & (bearing < 0)] += 360

    return plunge, bearing


Instruction:
Write a Python 3 function for
finding the intersection of two strikes and dips.

Response:
def plane_intersection(strike1, dip1, strike2, dip2):
    """
    Finds the intersection of two planes. Returns a plunge/bearing of the linear
    intersection of the two planes.

    Also accepts sequences of strike1s, dip1s, strike2s, dip2s.

    Parameters
    ----------
    strike1, dip1 : numbers or sequences of numbers
        The strike and dip (in degrees, following the right-hand-rule) of the
        first plane(s).
    strike2, dip2 : numbers or sequences of numbers
        The strike and dip (in degrees, following the right-hand-rule) of the
        second plane(s).

    Returns
    -------
    plunge, bearing : arrays
        The plunge and bearing(s) (in degrees) of the line representing the
        intersection of the two planes.
    """
    norm1 = sph2cart(*pole(strike1, dip1))
    norm2 = sph2cart(*pole(strike2, dip2))
    norm1, norm2 = np.array(norm1), np.array(norm2)
    lon, lat = cart2sph(*np.cross(norm1, norm2, axis=0))
    return geographic2plunge_bearing(lon, lat)


Instruction:
Can you implement a function in Python 3 that
projects a linear feature onto the surface of a plane.

Response:
def project_onto_plane(strike, dip, plunge, bearing):
    """
    Projects a linear feature(s) onto the surface of a plane. Returns a rake
    angle(s) along the plane.

    This is also useful for finding the rake angle of a feature that already
    intersects the plane in question.

    Parameters
    ----------
    strike, dip : numbers or sequences of numbers
        The strike and dip (in degrees, following the right-hand-rule) of the
        plane(s).
    plunge, bearing : numbers or sequences of numbers
        The plunge and bearing (in degrees) or of the linear feature(s) to be
        projected onto the plane.

    Returns
    -------
    rake : array
        A sequence of rake angles measured downwards from horizontal in
        degrees.  Zero degrees corresponds to the "right- hand" direction
        indicated by the strike, while a negative angle corresponds to the
        opposite direction. Rakes returned by this function will always be
        between -90 and 90 (inclusive).
    """
    # Project the line onto the plane
    norm = sph2cart(*pole(strike, dip))
    feature = sph2cart(*line(plunge, bearing))
    norm, feature = np.array(norm), np.array(feature)
    perp = np.cross(norm, feature, axis=0)
    on_plane = np.cross(perp, norm, axis=0)
    on_plane /= np.sqrt(np.sum(on_plane**2, axis=0))

    # Calculate the angle between the projected feature and horizontal
    # This is just a dot product, but we need to work with multiple measurements
    # at once, so einsum is quicker than apply_along_axis.
    strike_vec = sph2cart(*line(0, strike))
    dot = np.einsum('ij,ij->j', on_plane, strike_vec)
    rake = np.degrees(np.arccos(dot))

    # Convert rakes over 90 to negative rakes...
    rake[rake > 90] -= 180
    rake[rake < -90] += 180
    return rake


Instruction:
Write a Python 3 function that can
project an azimuth of a linear feature onto a plane as a rake angle. Parameters ---------- strike, dip : numbers The strike and dip of the plane in degrees following the right-hand-rule. azimuth : numbers The azimuth of the linear feature in degrees clockwise from north (i.e. a 0-360 azimuth). Returns ------- rake : number A rake angle in degrees measured downwards from horizontal. Negative values correspond to the opposite end of the strike.

Response:
def azimuth2rake(strike, dip, azimuth):
    """
    Projects an azimuth of a linear feature onto a plane as a rake angle.

    Parameters
    ----------
    strike, dip : numbers
        The strike and dip of the plane in degrees following the
        right-hand-rule.
    azimuth : numbers
        The azimuth of the linear feature in degrees clockwise from north (i.e.
        a 0-360 azimuth).

    Returns
    -------
    rake : number
        A rake angle in degrees measured downwards from horizontal.  Negative
        values correspond to the opposite end of the strike.
    """
    plunge, bearing = plane_intersection(strike, dip, azimuth, 90)
    rake = project_onto_plane(strike, dip, plunge, bearing)
    return rake


Instruction:
Implement a Python 3 function for
converting x y z in _world_ cartesian coordinates into lower - helisphere stereonet coordinates.

Response:
def xyz2stereonet(x, y, z):
    """
    Converts x, y, z in _world_ cartesian coordinates into lower-hemisphere
    stereonet coordinates.

    Parameters
    ----------
    x, y, z : array-likes
        Sequences of world coordinates

    Returns
    -------
    lon, lat : arrays
        Sequences of longitudes and latitudes (in radians)
    """
    x, y, z = np.atleast_1d(x, y, z)
    return cart2sph(-z, x, y)


Instruction:
Make a summary of the following Python 3 code
def stereonet2xyz(lon, lat):
    lon, lat = np.atleast_1d(lon, lat)
    x, y, z = sph2cart(lon, lat)
    return y, z, -x

Response: Converts a sequence of longitudes and latitudes from a lower - helisphere stereonet into _world_ x y z coordinates.


Instruction:
Create a Python 3 function for
calculating the angular distance between two sets of linear features or elementwise linear features or elementwise linear features.

Response:
def angular_distance(first, second, bidirectional=True):
    """
    Calculate the angular distance between two linear features or elementwise
    angular distance between two sets of linear features. (Note: a linear
    feature in this context is a point on a stereonet represented
    by a single latitude and longitude.)

    Parameters
    ----------
    first : (lon, lat) 2xN array-like or sequence of two numbers
        The longitudes and latitudes of the first measurements in radians.
    second : (lon, lat) 2xN array-like or sequence of two numbers
        The longitudes and latitudes of the second measurements in radians.
    bidirectional : boolean
        If True, only "inner" angles will be returned. In other words, all
        angles returned by this function will be in the range [0, pi/2]
        (0 to 90 in degrees).  Otherwise, ``first`` and ``second``
        will be treated as vectors going from the origin outwards
        instead of bidirectional infinite lines.  Therefore, with
        ``bidirectional=False``, angles returned by this function
        will be in the range [0, pi] (zero to 180 degrees).

    Returns
    -------
    dist : array
        The elementwise angular distance between each pair of measurements in
        (lon1, lat1) and (lon2, lat2).

    Examples
    --------

    Calculate the angle between two lines specified as a plunge/bearing

        >>> angle = angular_distance(line(30, 270), line(40, 90))
        >>> np.degrees(angle)
        array([ 70.])

    Let's do the same, but change the "bidirectional" argument:

        >>> first, second = line(30, 270), line(40, 90)
        >>> angle = angular_distance(first, second, bidirectional=False)
        >>> np.degrees(angle)
        array([ 110.])

    Calculate the angle between two planes.

        >>> angle = angular_distance(pole(0, 10), pole(180, 10))
        >>> np.degrees(angle)
        array([ 20.])
    """
    lon1, lat1 = first
    lon2, lat2 = second
    lon1, lat1, lon2, lat2 = np.atleast_1d(lon1, lat1, lon2, lat2)
    xyz1 = sph2cart(lon1, lat1)
    xyz2 = sph2cart(lon2, lat2)
    # This is just a dot product, but we need to work with multiple measurements
    # at once, so einsum is quicker than apply_along_axis.
    dot = np.einsum('ij,ij->j', xyz1, xyz2)
    angle = np.arccos(dot)

    # There are numerical sensitivity issues around 180 and 0 degrees...
    # Sometimes a result will have an absolute value slighly over 1.
    if np.any(np.isnan(angle)):
        rtol = 1e-4
        angle[np.isclose(dot, -1, rtol)] = np.pi
        angle[np.isclose(dot, 1, rtol)] = 0

    if bidirectional:
        mask = angle > np.pi / 2
        angle[mask] = np.pi - angle[mask]

    return angle


Instruction:
Explain what the following Python 3 code does
def _repole(lon, lat, center):
    vec3 = sph2cart(*center)
    vec3 = np.squeeze(vec3)
    if not np.allclose(vec3, [0, 0, 1]):
        vec1 = np.cross(vec3, [0, 0, 1])
    else:
        vec1 = np.cross(vec3, [1, 0, 0])
    vec2 = np.cross(vec3, vec1)
    vecs = [item / np.linalg.norm(item) for item in [vec1, vec2, vec3]]
    basis = np.column_stack(vecs)

    xyz = sph2cart(lon, lat)
    xyz = np.column_stack(xyz)
    prime = xyz.dot(np.linalg.inv(basis))
    lon, lat = cart2sph(*prime.T)
    return lon[:,None], lat[:,None]

Response: Reproject data such that center is the north pole. Returns lon lat in the new rotated reference frame.


Instruction:
Implement a function in Python 3 to
unify fit_pole and fit_girdle.

Response:
def _sd_of_eigenvector(data, vec, measurement='poles', bidirectional=True):
    """Unifies ``fit_pole`` and ``fit_girdle``."""
    lon, lat = _convert_measurements(data, measurement)
    vals, vecs = cov_eig(lon, lat, bidirectional)
    x, y, z = vecs[:, vec]
    s, d = stereonet_math.geographic2pole(*stereonet_math.cart2sph(x, y, z))
    return s[0], d[0]


Instruction:
Can you generate the documentation for the following Python 3 function
def eigenvectors(*args, **kwargs):
    lon, lat = _convert_measurements(args, kwargs.get('measurement', 'poles'))
    vals, vecs = cov_eig(lon, lat, kwargs.get('bidirectional', True))
    lon, lat = stereonet_math.cart2sph(*vecs)
    plunges, bearings = stereonet_math.geographic2plunge_bearing(lon, lat)
    # Largest eigenvalue first...
    return plunges[::-1], bearings[::-1], vals[::-1]

Response: Returns the 3D eigenvectors of the 3D covariance matrix of the avec of the specified set of measurements.


Instruction:
Explain what the following Python 3 code does
def find_mean_vector(*args, **kwargs):
    lon, lat = _convert_measurements(args, kwargs.get('measurement', 'lines'))
    vector, r_value = stereonet_math.mean_vector(lon, lat)
    plunge, bearing = stereonet_math.geographic2plunge_bearing(*vector)
    return (plunge[0], bearing[0]), r_value

Response: Returns the mean vector for a set of measurments.


Instruction:
Write a Python 3 function for
returning the mean vector and summary statistics for a set of measurements.

Response:
def find_fisher_stats(*args, **kwargs):
    """
    Returns the mean vector and summary statistics for a set of measurements.
    By default, this expects the input to be plunges and bearings, but the type
    of input can be controlled through the ``measurement`` kwarg.

    Parameters
    ----------
    *args : 2 or 3 sequences of measurements
        By default, this will be expected to be ``plunge`` & ``bearing``, both
        array-like sequences representing linear features.  (Rake measurements
        require three parameters, thus the variable number of arguments.) The
        *measurement* kwarg controls how these arguments are interpreted.

    conf : number
        The confidence level (0-100). Defaults to 95%, similar to 2 sigma.

    measurement : string, optional
        Controls how the input arguments are interpreted. Defaults to
        ``"lines"``.  May be one of the following:

            ``"poles"`` : strikes, dips
                Arguments are assumed to be sequences of strikes and dips of
                planes. Poles to these planes are used for analysis.
            ``"lines"`` : plunges, bearings
                Arguments are assumed to be sequences of plunges and bearings
                of linear features.
            ``"rakes"`` : strikes, dips, rakes
                Arguments are assumed to be sequences of strikes, dips, and
                rakes along the plane.
            ``"radians"`` : lon, lat
                Arguments are assumed to be "raw" longitudes and latitudes in
                the stereonet's underlying coordinate system.

    Returns
    -------

    mean_vector: tuple of two floats
        A set consisting of the plunge and bearing of the mean vector (in
        degrees).

    stats : tuple of three floats
        ``(r_value, confidence, kappa)``
        The ``r_value`` is the magnitude of the mean vector as a number between
        0 and 1.
        The ``confidence`` radius is the opening angle of a small circle that
        corresponds to the confidence in the calculated direction, and is
        dependent on the input ``conf``.
        The ``kappa`` value is the dispersion factor that quantifies the amount
        of dispersion of the given vectors, analgous to a variance/stddev.
    """
    # How the heck did this wind up as a separate function?
    lon, lat = _convert_measurements(args, kwargs.get('measurement', 'lines'))
    conf = kwargs.get('conf', 95)
    center, stats = stereonet_math.fisher_stats(lon, lat, conf)
    plunge, bearing = stereonet_math.geographic2plunge_bearing(*center)
    mean_vector = (plunge[0], bearing[0])
    return mean_vector, stats


Instruction:
Can you create a Python 3 function that
returns a new Nx2 array - like structure that can be used to create a multi - modal cluster for a set of measurements.

Response:
def kmeans(*args, **kwargs):
    """
    Find centers of multi-modal clusters of data using a kmeans approach
    modified for spherical measurements.

    Parameters
    ----------

    *args : 2 or 3 sequences of measurements
        By default, this will be expected to be ``strike`` & ``dip``, both
        array-like sequences representing poles to planes.  (Rake measurements
        require three parameters, thus the variable number of arguments.) The
        ``measurement`` kwarg controls how these arguments are interpreted.

    num : int
        The number of clusters to find. Defaults to 2.

    bidirectional : bool
        Whether or not the measurements are bi-directional linear/planar
        features or directed vectors. Defaults to True.

    tolerance : float
        Iteration will continue until the centers have not changed by more
        than this amount. Defaults to 1e-5.

    measurement : string, optional
        Controls how the input arguments are interpreted. Defaults to
        ``"poles"``.  May be one of the following:

            ``"poles"`` : strikes, dips
                Arguments are assumed to be sequences of strikes and dips of
                planes. Poles to these planes are used for analysis.
            ``"lines"`` : plunges, bearings
                Arguments are assumed to be sequences of plunges and bearings
                of linear features.
            ``"rakes"`` : strikes, dips, rakes
                Arguments are assumed to be sequences of strikes, dips, and
                rakes along the plane.
            ``"radians"`` : lon, lat
                Arguments are assumed to be "raw" longitudes and latitudes in
                the stereonet's underlying coordinate system.

    Returns
    -------

    centers : An Nx2 array-like
        Longitude and latitude in radians of the centers of each cluster.
    """
    lon, lat = _convert_measurements(args, kwargs.get('measurement', 'poles'))
    num = kwargs.get('num', 2)
    bidirectional = kwargs.get('bidirectional', True)
    tolerance = kwargs.get('tolerance', 1e-5)

    points = lon, lat
    dist = lambda x: stereonet_math.angular_distance(x, points, bidirectional)

    center_lon = np.random.choice(lon, num)
    center_lat = np.random.choice(lat, num)
    centers = np.column_stack([center_lon, center_lat])

    while True:
        dists = np.array([dist(item) for item in centers]).T
        closest = dists.argmin(axis=1)

        new_centers = []
        for i in range(num):
            mask = mask = closest == i
            _, vecs = cov_eig(lon[mask], lat[mask], bidirectional)
            new_centers.append(stereonet_math.cart2sph(*vecs[:,-1]))

        if np.allclose(centers, new_centers, atol=tolerance):
            break
        else:
            centers = new_centers

    return centers


Instruction:
How would you code a function in Python 3 to
check if a connection is closed or not.

Response:
def is_disconnect(e, connection, cursor):
    """
    Connection state check from SQLAlchemy:
    https://bitbucket.org/sqlalchemy/sqlalchemy/src/tip/lib/sqlalchemy/dialects/postgresql/psycopg2.py
    """
    if isinstance(e, OperationalError):
        # these error messages from libpq: interfaces/libpq/fe-misc.c.
        # TODO: these are sent through gettext in libpq and we can't
        # check within other locales - consider using connection.closed
        return 'terminating connection' in str(e) or \
                'closed the connection' in str(e) or \
                'connection not open' in str(e) or \
                'could not receive data from server' in str(e)
    elif isinstance(e, InterfaceError):
        # psycopg2 client errors, psycopg2/conenction.h, psycopg2/cursor.h
        return 'connection already closed' in str(e) or \
                'cursor already closed' in str(e)
    elif isinstance(e, ProgrammingError):
        # not sure where this path is originally from, it may
        # be obsolete.   It really says "losed", not "closed".
        return "closed the connection unexpectedly" in str(e)
    else:
        return False


Instruction:
Make a summary of the following Python 3 code
def _dispose(self):
        self.close()
        # _DBProxy.dispose doesn't actually call dispose on the pool
        conn_params = self.get_connection_params()
        key = db_pool._serialize(**conn_params)
        try:
            pool = db_pool.pools[key]
        except KeyError:
            pass
        else:
            pool.dispose()
            del db_pool.pools[key]

Response: Dispose of the pool for this instance closing all connections and deleting the pool.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def calc_fc_size(img_height, img_width):
    '''Calculates shape of data after encoding.

    Parameters
    ----------
    img_height : int
        Height of input image.
    img_width : int
        Width of input image.

    Returns
    -------
    encoded_shape : tuple(int)
        Gives back 3-tuple with new dims.
    '''
    height, width = img_height, img_width
    for _ in range(5):
        height, width = _get_conv_outsize(
            (height, width),
            4, 2, 1)

    conv_out_layers = 512
    return conv_out_layers, height, width

Response: Calculates the shape of data after encoding.


Instruction:
Given the following Python 3 function, write the documentation
def calc_im_size(img_height, img_width):
    '''Calculates shape of data after decoding.

    Parameters
    ----------
    img_height : int
        Height of encoded data.
    img_width : int
        Width of encoded data.

    Returns
    -------
    encoded_shape : tuple(int)
        Gives back 2-tuple with decoded image dimensions.
    '''
    height, width = img_height, img_width
    for _ in range(5):
        height, width = _get_deconv_outsize((height, width),
                                            4, 2, 1)

    return height, width

Response: Calculates the shape of data after decoding.