Instruction:
How would you explain what the following Python 3 function does
def verify_deprecated_policy(old_policy, new_policy, default_rule, context):

    if _ENFORCER:
        current_rule = str(_ENFORCER.rules[old_policy])
    else:
        current_rule = None

    if current_rule != default_rule:
        LOG.warning("Start using the new action '{0}'. The existing "
                    "action '{1}' is being deprecated and will be "
                    "removed in future release.".format(new_policy,
                                                        old_policy))
        target = {'project_id': context.project_id,
                  'user_id': context.user_id}

        return authorize(context=context, action=old_policy, target=target)
    else:
        return False

Response: Verify that the old_policy is being deprecated and that the new_policy is being replaced with the new_policy.


Instruction:
Write a Python 3 script for
building sample problem from Wang 2004.

Response:
def build_sample_ace_problem_wang04(N=100):
    """Build sample problem from Wang 2004."""
    x = [numpy.random.uniform(-1, 1, size=N)
         for _i in range(0, 5)]
    noise = numpy.random.standard_normal(N)
    y = numpy.log(4.0 + numpy.sin(4 * x[0]) + numpy.abs(x[1]) + x[2] ** 2 +
                  x[3] ** 3 + x[4] + 0.1 * noise)
    return x, y


Instruction:
Can you write a function in Python 3 where it
runs sample problem with Wang - 04 ACE.

Response:
def run_wang04():
    """Run sample problem."""
    x, y = build_sample_ace_problem_wang04(N=200)
    ace_solver = ace.ACESolver()
    ace_solver.specify_data_set(x, y)
    ace_solver.solve()
    try:
        ace.plot_transforms(ace_solver, 'ace_transforms_wang04.png')
        ace.plot_input(ace_solver, 'ace_input_wang04.png')
    except ImportError:
        pass

    return ace_solver


Instruction:
Can you tell what is the following Python 3 function doing
def add_robot(self, controller):

        # connect to the controller
        # -> this is to support module robots
        controller.on_mode_change(self._on_robot_mode_change)
        self.robots.append(controller)

Response: Add a robot controller to the list of robots


Instruction:
Can you generate the documentation for the following Python 3 function
def set_joystick(self, x, y, n):
        self.robots[n].set_joystick(x, y)

Response: Sets the joystick coordinates of the iCal entry with the coordinates x y.


Instruction:
Implement a Python 3 function for
disconnecting from the broker.

Response:
async def disconnect(self):
        """
            Disconnect coroutine
        """

        async with self._disconnect_lock:
            if self._state == ConnectionState.DISCONNECTED:
                return

            self._set_state(ConnectionState.DISCONNECTING)

            logger.info('%s Disconnecting...', self.fingerprint)
            if self._reconnect_task:
                self._reconnect_task.cancel()
                self._reconnect_task = None

            if self._ping_task and not self._ping_task.done():
                self._ping_task.cancel()
                self._ping_task = None

            self._db = _DbMock()
            if self._transport:
                self._disconnect_waiter = _create_future(self._loop)
                self._transport.close()
                self._transport = None
                self._protocol = None

                await self._disconnect_waiter
                self._disconnect_waiter = None
                self._set_state(ConnectionState.DISCONNECTED)
            else:
                self._transport = None
                self._protocol = None
                self._disconnect_waiter = None
                self._set_state(ConnectionState.DISCONNECTED)


Instruction:
Can you tell what is the following Python 3 function doing
def close(self):

        if self._state == ConnectionState.DISCONNECTED:
            return

        self._set_state(ConnectionState.DISCONNECTING)
        logger.info('%s Disconnecting...', self.fingerprint)

        if self._reconnect_task and not self._reconnect_task.done():
            self._reconnect_task.cancel()
            self._reconnect_task = None

        if self._ping_task and not self._ping_task.done():
            self._ping_task.cancel()
            self._ping_task = None

        if self._transport:
            self._transport.close()

        self._transport = None
        self._protocol = None
        self._disconnect_waiter = None
        self._db = _DbMock()
        self._set_state(ConnectionState.DISCONNECTED)

Response:
Same as disconnect, but not a coroutine, i.e. it does not wait
            for disconnect to finish.


Instruction:
Can you create a Python 3 function that
calls request coroutine. It is a call with a new behaviour (return result of a Tarantool procedure is not wrapped into an extra tuple). If you're connecting to Tarantool with version < 1.7, then this call method acts like a call16 method Examples: .. code-block:: pycon # tarantool function: # function f(...) # return ... # end >>> await conn.call('f') <Response sync=3 rowcount=0 data=[]> >>> await conn.call('f', [20, 42]) <Response sync=3 rowcount=2 data=[20, 42]> :param func_name: function name to call :param args: arguments to pass to the function (list object) :param timeout: Request timeout :param push_subscribe: Subscribe to push notifications :returns: :class:`asynctnt.Response` instance

Response:
def call(self, func_name, args=None, *,
             timeout=-1.0, push_subscribe=False) -> _MethodRet:
        """
            Call request coroutine. It is a call with a new behaviour
            (return result of a Tarantool procedure is not wrapped into
            an extra tuple). If you're connecting to Tarantool with
            version < 1.7, then this call method acts like a call16 method

            Examples:

            .. code-block:: pycon

                # tarantool function:
                # function f(...)
                #     return ...
                # end

                >>> await conn.call('f')
                <Response sync=3 rowcount=0 data=[]>

                >>> await conn.call('f', [20, 42])
                <Response sync=3 rowcount=2 data=[20, 42]>

            :param func_name: function name to call
            :param args: arguments to pass to the function (list object)
            :param timeout: Request timeout
            :param push_subscribe: Subscribe to push notifications

            :returns: :class:`asynctnt.Response` instance
        """
        return self._db.call(func_name, args,
                             timeout=timeout, push_subscribe=push_subscribe)


Instruction:
Create a Python 3 function for
executing an expression and return the result.

Response:
def eval(self, expression, args=None, *,
             timeout=-1.0, push_subscribe=False) -> _MethodRet:
        """
            Eval request coroutine.

            Examples:

            .. code-block:: pycon

                >>> await conn.eval('return 42')
                <Response sync=3 rowcount=1 data=[42]>

                >>> await conn.eval('return box.info.version')
                <Response sync=3 rowcount=1 data=['2.1.1-7-gd381a45b6']>

            :param expression: expression to execute
            :param args: arguments to pass to the function, that will
                         execute your expression (list object)
            :param timeout: Request timeout
            :param push_subscribe: Subscribe to push messages

            :returns: :class:`asynctnt.Response` instance
        """
        return self._db.eval(expression, args,
                             timeout=timeout, push_subscribe=push_subscribe)


Instruction:
Write a Python 3 script for
selecting an object in a specific space.

Response:
def select(self, space, key=None, **kwargs) -> _MethodRet:
        """
            Select request coroutine.

            Examples:

            .. code-block:: pycon

                >>> await conn.select('tester')
                <Response sync=3 rowcount=2 data=[
                    <TarantoolTuple id=1 name='one'>,
                    <TarantoolTuple id=2 name='two'>
                ]>

                >>> res = await conn.select('_space', ['tester'], index='name')
                >>> res.data
                [<TarantoolTuple id=512
                                 owner=1
                                 name='tester'
                                 engine='memtx'
                                 field_count=0
                                 flags={}
                                 format=[
                                    {'name': 'id', 'type': 'unsigned'},
                                    {'name': 'name', 'type': 'string'}
                                 ]>]

            :param space: space id or space name.
            :param key: key to select
            :param offset: offset to use
            :param limit: limit to use
            :param index: index id or name
            :param iterator: one of the following

                        * iterator id (int number),
                        * :class:`asynctnt.Iterator` object
                        * string with an iterator name

            :param timeout: Request timeout

            :returns: :class:`asynctnt.Response` instance
        """
        return self._db.select(space, key, **kwargs)


Instruction:
How would you code a function in Python 3 to
insert a new entry into the database.

Response:
def insert(self, space, t, *, replace=False, timeout=-1) -> _MethodRet:
        """
            Insert request coroutine.

            Examples:

            .. code-block:: pycon

                # Basic usage
                >>> await conn.insert('tester', [0, 'hello'])
                <Response sync=3 rowcount=1 data=[
                    <TarantoolTuple id=0 name='hello'>
                ]>

                # Using dict as an argument tuple
                >>> await conn.insert('tester', {
                ...                     'id': 0
                ...                     'text': 'hell0'
                ...                   })
                <Response sync=3 rowcount=1 data=[
                    <TarantoolTuple id=0 name='hello'>
                ]>

            :param space: space id or space name.
            :param t: tuple to insert (list object)
            :param replace: performs replace request instead of insert
            :param timeout: Request timeout

            :returns: :class:`asynctnt.Response` instance
        """
        return self._db.insert(space, t,
                               replace=replace,
                               timeout=timeout)


Instruction:
Make a summary of the following Python 3 code
def replace(self, space, t, *, timeout=-1.0) -> _MethodRet:
        return self._db.replace(space, t, timeout=timeout)

Response: Replace an entry in the cache with a new one.


Instruction:
Here you have a function in Python 3, explain what it does
def delete(self, space, key, **kwargs) -> _MethodRet:
        return self._db.delete(space, key, **kwargs)

Response: Delete an object in a specific space.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def update(self, space, key, operations, **kwargs) -> _MethodRet:
        return self._db.update(space, key, operations, **kwargs)

Response: Update the object in a specific key in a space.


Instruction:
Implement a Python 3 function for
inserting or update a tuple in a space.

Response:
def upsert(self, space, t, operations, **kwargs) -> _MethodRet:
        """
            Update request coroutine. Performs either insert or update
            (depending of either tuple exists or not)

            Examples:

            .. code-block:: pycon

                # upsert does not return anything
                >>> await conn.upsert('tester', [0, 'hello'],
                ...                   [ ['=', 1, 'hi!'] ])
                <Response sync=3 rowcount=0 data=[]>

            :param space: space id or space name.
            :param t: tuple to insert if it's not in space
            :param operations:
                    Operations list to use for update if tuple is already in
                    space. It has the same format as in update requets:
                    [ [op_type, field_no, ...], ... ]. Please refer to
                    https://tarantool.org/doc/book/box/box_space.html?highlight=update#lua-function.space_object.update
                    You can use field numbers as well as their names in space
                    format as a field_no (if only fetch_schema is True).
                    If field is unknown then TarantoolSchemaError is raised.
            :param timeout: Request timeout

            :returns: :class:`asynctnt.Response` instance
        """
        return self._db.upsert(space, t, operations, **kwargs)


Instruction:
Given the following Python 3 function, write the documentation
def sql(self, query, args=None, *,
            parse_metadata=True, timeout=-1.0) -> _MethodRet:
        """
            Executes an SQL statement (only for Tarantool > 2)

            Examples:

            .. code-block:: pycon

                >>> await conn.sql("select 1 as a, 2 as b")
                <Response sync=3 rowcount=1 data=[<TarantoolTuple A=1 B=2>]>

                >>> await conn.sql("select * from sql_space")
                <Response sync=3 rowcount=2 data=[
                    <TarantoolTuple ID=1 NAME='James Bond'>,
                    <TarantoolTuple ID=2 NAME='Ethan Hunt'>
                ]>

                >>> await conn.sql("select * from sql_space",
                ...                parse_metadata=False)
                <Response sync=3 rowcount=2 data=[
                    <TarantoolTuple 0=1 1='James Bond'>,
                    <TarantoolTuple 0=2 1='Ethan Hunt'>
                ]>

            :param query: SQL query
            :param args: Query arguments
            :param parse_metadata: Set to False to disable response's metadata
                                   parsing for better performance
            :param timeout: Request timeout

            :returns: :class:`asynctnt.Response` instance
        """
        return self._db.sql(query, args,
                            parse_metadata=parse_metadata,
                            timeout=timeout)

Response: Executes an SQL query and returns the result.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _compute_primary_smooths(self):
        for span in DEFAULT_SPANS:
            smooth = smoother.perform_smooth(self.x, self.y, span)
            self._primary_smooths.append(smooth)

Response: Compute fixed - span smooths with all of the default spans.


Instruction:
Can you tell what is the following Python 3 function doing
def _smooth_the_residuals(self):
        for primary_smooth in self._primary_smooths:
            smooth = smoother.perform_smooth(self.x,
                                             primary_smooth.cross_validated_residual,
                                             MID_SPAN)
            self._residual_smooths.append(smooth.smooth_result)

Response: Perform the MID_SPAN on the residuals of the primary smooths.


Instruction:
Can you tell what is the following Python 3 function doing
def _select_best_smooth_at_each_point(self):
        for residuals_i in zip(*self._residual_smooths):
            index_of_best_span = residuals_i.index(min(residuals_i))
            self._best_span_at_each_point.append(DEFAULT_SPANS[index_of_best_span])

Response: Select the best smooth for each observation at each point.


Instruction:
How would you explain what the following Python 3 function does
def _enhance_bass(self):
        if not self._bass_enhancement:
            # like in supsmu, skip if alpha=0
            return
        bass_span = DEFAULT_SPANS[BASS_INDEX]
        enhanced_spans = []
        for i, best_span_here in enumerate(self._best_span_at_each_point):
            best_smooth_index = DEFAULT_SPANS.index(best_span_here)
            best_span = DEFAULT_SPANS[best_smooth_index]
            best_span_residual = self._residual_smooths[best_smooth_index][i]
            bass_span_residual = self._residual_smooths[BASS_INDEX][i]
            if 0 < best_span_residual < bass_span_residual:
                ri = best_span_residual / bass_span_residual
                bass_factor = ri ** (10.0 - self._bass_enhancement)
                enhanced_spans.append(best_span + (bass_span - best_span) * bass_factor)
            else:
                enhanced_spans.append(best_span)
        self._best_span_at_each_point = enhanced_spans

Response: Update the best span choices with bass enhancement as requested by user.


Instruction:
Implement a Python 3 function for
applying a MID_SPAN smooth to the best span estimates at each observation.

Response:
def _smooth_best_span_estimates(self):
        """Apply a MID_SPAN smooth to the best span estimates at each observation."""
        self._smoothed_best_spans = smoother.perform_smooth(self.x,
                                                            self._best_span_at_each_point,
                                                            MID_SPAN)


Instruction:
Implement a Python 3 function for
applying the best spans. Given the best span interpolate to compute the best smoothed value at each observation.

Response:
def _apply_best_spans_to_primaries(self):
        """
        Apply best spans.

        Given the best span, interpolate to compute the best smoothed value
        at each observation.
        """
        self.smooth_result = []
        for xi, best_span in enumerate(self._smoothed_best_spans.smooth_result):
            primary_values = [s.smooth_result[xi] for s in self._primary_smooths]
            # pylint: disable=no-member
            best_value = numpy.interp(best_span, DEFAULT_SPANS, primary_values)
            self.smooth_result.append(best_value)


Instruction:
Can you tell what is the following Python 3 function doing
def _smooth_interpolated_smooth(self):
        smoothed_results = smoother.perform_smooth(self.x,
                                                   self.smooth_result,
                                                   TWEETER_SPAN)
        self.smooth_result = smoothed_results.smooth_result

Response: Smooth interpolated results with tweeter span.


Instruction:
How would you explain what the following Python 3 function does
def _mp_consume(client, group, topic, queue, size, events, **consumer_options):

    # Initial interval for retries in seconds.
    interval = 1
    while not events.exit.is_set():
        try:
            # Make the child processes open separate socket connections
            client.reinit()

            # We will start consumers without auto-commit. Auto-commit will be
            # done by the master controller process.
            consumer = SimpleConsumer(client, group, topic,
                                      auto_commit=False,
                                      auto_commit_every_n=None,
                                      auto_commit_every_t=None,
                                      **consumer_options)

            # Ensure that the consumer provides the partition information
            consumer.provide_partition_info()

            while True:
                # Wait till the controller indicates us to start consumption
                events.start.wait()

                # If we are asked to quit, do so
                if events.exit.is_set():
                    break

                # Consume messages and add them to the queue. If the controller
                # indicates a specific number of messages, follow that advice
                count = 0

                message = consumer.get_message()
                if message:
                    while True:
                        try:
                            queue.put(message, timeout=FULL_QUEUE_WAIT_TIME_SECONDS)
                            break
                        except queue.Full:
                            if events.exit.is_set():
                                break

                    count += 1

                    # We have reached the required size. The controller might have
                    # more than what he needs. Wait for a while.
                    # Without this logic, it is possible that we run into a big
                    # loop consuming all available messages before the controller
                    # can reset the 'start' event
                    if count == size.value:
                        events.pause.wait()

                else:
                    # In case we did not receive any message, give up the CPU for
                    # a while before we try again
                    time.sleep(NO_MESSAGES_WAIT_TIME_SECONDS)

            consumer.stop()

        except KafkaError as e:
            # Retry with exponential backoff
            log.error(
                "Problem communicating with Kafka (%s), retrying in %d seconds..." % (e, interval))
            time.sleep(interval)
            interval = interval * 2 if interval * 2 < MAX_BACKOFF_SECONDS else MAX_BACKOFF_SECONDS

Response: This function is a multiprocessing module which processes messages based on the messages in the queue and processes them.


Instruction:
Can you write a function in Python 3 where it
moves the object to the new location

Response:
def move(self, v):
        """v is a tuple of x/y coordinates to move object"""

        # rotate movement vector according to the angle of the object
        vx, vy = v
        vx, vy = (
            vx * math.cos(self.angle) - vy * math.sin(self.angle),
            vx * math.sin(self.angle) + vy * math.cos(self.angle),
        )

        def _move(xy):
            x, y = xy
            return x + vx, y + vy

        # TODO: detect other objects in the way, stop movement appropriately

        self.pts = [p for p in map(lambda x: _move(x), self.pts)]
        self.center = _move(self.center)


Instruction:
Can you tell what is the following Python 3 function doing
def rotate(self, angle):

        self.angle = (self.angle + angle) % (math.pi * 2.0)

        # precalculate these parameters
        c = math.cos(angle)
        s = math.sin(angle)
        px, py = self.center

        def _rotate_point(xy):

            x, y = xy

            x = x - px
            y = y - py

            return (x * c - y * s) + px, (x * s + y * c) + py

        # calculate rotation for each point
        self.pts = [p for p in map(lambda x: _rotate_point(x), self.pts)]

Response: This works. Rotates the object about its center.


Instruction:
Write a Python 3 function for
publishing messages to the specified topic.

Response:
def publish(self, topic, messages, key=None, timeout=2):
        """
        Publish messages to the topic.

        :param str topic: Topic to produce messages to.
        :param list(str) messages:  List of message payloads.
        :param str key: Message key.
        :param float timeout: Maximum time to block in seconds.
        :returns: Number of messages still in queue.
        :rtype int
        """

        if not isinstance(messages, list):
            messages = [messages]

        try:
            for m in messages:
                m = encodeutils.safe_encode(m, incoming='utf-8')
                self._producer.produce(topic, m, key,
                                       callback=KafkaProducer.delivery_report)
                self._producer.poll(0)

            return self._producer.flush(timeout)

        except (BufferError, confluent_kafka.KafkaException,
                NotImplementedError):
            log.exception(u'Error publishing to {} topic.'.format(topic))
            raise


Instruction:
Can you generate the documentation for the following Python 3 function
def increment_time_by(self, secs):
        self.slept = [True] * 3

        was_paused = False

        with self.lock:

            self._increment_tm(secs)

            while self.paused and secs > 0:

                if self.pause_secs is not None:
                    # if pause_secs is set, this means it was a step operation,
                    # so we adjust the wait accordingly
                    if secs > self.pause_secs:
                        secs -= self.pause_secs
                    else:
                        secs = 0

                    self.pause_secs = None

                was_paused = True

                self.lock.wait()

                # if the operator tried to do another step, this will update
                # the paused flag so we don't escape the loop
                self._increment_tm(secs)

        if not was_paused:
            time.sleep(secs)

Response: This is called when the time is in the middle of the operation.


Instruction:
Explain what the following Python 3 code does
def get_cache_key(page):
    try:
        site_id = page.node.site_id
    except AttributeError:
        site_id = page.site_id
    return _get_cache_key('page_sitemap', page, 'default', site_id)

Response: Create the cache key for the current page and language


Instruction:
Here you have a function in Python 3, explain what it does
def out_name(stem, timestep=None):
    if timestep is not None:
        stem = (stem + INT_FMT).format(timestep)
    return conf.core.outname + '_' + stem

Response: Return StagPy out file name.


Instruction:
Write a Python 3 function that can
save matplotlib figure. You need to provide :data:`stem` as a positional or keyword argument (see :func:`out_name`). Args: fig (:class:`matplotlib.figure.Figure`): matplotlib figure. close (bool): whether to close the figure. name_args: positional arguments passed on to :func:`out_name`. name_kwargs: keyword arguments passed on to :func:`out_name`.

Response:
def saveplot(fig, *name_args, close=True, **name_kwargs):
    """Save matplotlib figure.

    You need to provide :data:`stem` as a positional or keyword argument (see
    :func:`out_name`).

    Args:
        fig (:class:`matplotlib.figure.Figure`): matplotlib figure.
        close (bool): whether to close the figure.
        name_args: positional arguments passed on to :func:`out_name`.
        name_kwargs: keyword arguments passed on to :func:`out_name`.
    """
    oname = out_name(*name_args, **name_kwargs)
    fig.savefig('{}.{}'.format(oname, conf.plot.format),
                format=conf.plot.format, bbox_inches='tight')
    if close:
        plt.close(fig)


Instruction:
Can you create a Python 3 function that
returns the first line of the docstring of an object.

Response:
def baredoc(obj):
    """Return the first line of the docstring of an object.

    Trailing periods and spaces as well as leading spaces are removed from the
    output.

    Args:
        obj: any Python object.
    Returns:
        str: the first line of the docstring of obj.
    """
    doc = getdoc(obj)
    if not doc:
        return ''
    doc = doc.splitlines()[0]
    return doc.rstrip(' .').lstrip()


Instruction:
Can you implement a function in Python 3 that
returns LaTeX expression with time in scientific notation.

Response:
def fmttime(tin):
    """Return LaTeX expression with time in scientific notation.

    Args:
        tin (float): the time.
    Returns:
        str: the LaTeX expression.
    """
    aaa, bbb = '{:.2e}'.format(tin).split('e')
    bbb = int(bbb)
    return r'$t={} \times 10^{{{}}}$'.format(aaa, bbb)


Instruction:
Can you generate the documentation for the following Python 3 function
def list_of_vars(arg_plot):
    lovs = [[[var for var in svars.split(',') if var]
             for svars in pvars.split('.') if svars]
            for pvars in arg_plot.split('-') if pvars]
    lovs = [[slov for slov in lov if slov] for lov in lovs if lov]
    return [lov for lov in lovs if lov]

Response: Construct list of variables per plot.


Instruction:
Here you have a function in Python 3, explain what it does
def set_of_vars(lovs):
    return set(var for pvars in lovs for svars in pvars for var in svars)

Response: Build set of variables from list of variables.


Instruction:
Write a Python 3 function for
returning the radial or vertical positions of boundaries of the current object.

Response:
def get_rbounds(step):
    """Radial or vertical position of boundaries.

    Args:
        step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
            instance.
    Returns:
        tuple of floats: radial or vertical positions of boundaries of the
        domain.
    """
    if step.geom is not None:
        rcmb = step.geom.rcmb
    else:
        rcmb = step.sdat.par['geometry']['r_cmb']
        if step.sdat.par['geometry']['shape'].lower() == 'cartesian':
            rcmb = 0
    rcmb = max(rcmb, 0)
    return rcmb, rcmb + 1


Instruction:
Can you generate the documentation for the following Python 3 function
def fnames(self, names):
        names = list(names[:len(self._fnames)])
        self._fnames = names + self._fnames[len(names):]

Response: Ensure constant size of fnames


Instruction:
Can you implement a function in Python 3 that
extracts or compute a time series from a StagyyData instance and a key of the appropriate type.

Response:
def get_time_series(sdat, var, tstart, tend):
    """Extract or compute and rescale a time series.

    Args:
        sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
        var (str): time series name, a key of :data:`stagpy.phyvars.TIME`
            or :data:`stagpy.phyvars.TIME_EXTRA`.
        tstart (float): starting time of desired series. Set to None to start
            at the beginning of available data.
        tend (float): ending time of desired series. Set to None to stop at the
            end of available data.
    Returns:
        tuple of :class:`numpy.array` and :class:`stagpy.phyvars.Vart`:
        series, time, meta
            series is the requested time series, time the time at which it
            is evaluated (set to None if it is the one of time series output
            by StagYY), and meta is a :class:`stagpy.phyvars.Vart` instance
            holding metadata of the requested variable.
    """
    tseries = sdat.tseries_between(tstart, tend)
    if var in tseries.columns:
        series = tseries[var]
        time = None
        if var in phyvars.TIME:
            meta = phyvars.TIME[var]
        else:
            meta = phyvars.Vart(var, None, '1')
    elif var in phyvars.TIME_EXTRA:
        meta = phyvars.TIME_EXTRA[var]
        series, time = meta.description(sdat, tstart, tend)
        meta = phyvars.Vart(misc.baredoc(meta.description),
                            meta.kind, meta.dim)
    else:
        raise UnknownTimeVarError(var)

    series, _ = sdat.scale(series, meta.dim)
    if time is not None:
        time, _ = sdat.scale(time, 's')
    return series, time, meta


Instruction:
How would you explain what the following Python 3 function does
def plot_time_series(sdat, lovs):
    sovs = misc.set_of_vars(lovs)
    tseries = {}
    times = {}
    metas = {}
    for tvar in sovs:
        series, time, meta = get_time_series(
            sdat, tvar, conf.time.tstart, conf.time.tend)
        tseries[tvar] = series
        metas[tvar] = meta
        if time is not None:
            times[tvar] = time
    tseries['t'] = get_time_series(
        sdat, 't', conf.time.tstart, conf.time.tend)[0]

    _plot_time_list(sdat, lovs, tseries, metas, times)

Response: Plot requested time series.


Instruction:
Can you tell what is the following Python 3 function doing
def compstat(sdat, tstart=None, tend=None):
    data = sdat.tseries_between(tstart, tend)
    time = data['t'].values
    delta_time = time[-1] - time[0]
    data = data.iloc[:, 1:].values  # assume t is first column

    mean = np.trapz(data, x=time, axis=0) / delta_time
    rms = np.sqrt(np.trapz((data - mean)**2, x=time, axis=0) / delta_time)

    with open(misc.out_name('statistics.dat'), 'w') as out_file:
        mean.tofile(out_file, sep=' ', format="%10.5e")
        out_file.write('\n')
        rms.tofile(out_file, sep=' ', format="%10.5e")
        out_file.write('\n')

Response: Compute statistics from series output by StagYY.


Instruction:
Make a summary of the following Python 3 code
def cmd():
    sdat = StagyyData(conf.core.path)
    if sdat.tseries is None:
        return

    if conf.time.fraction is not None:
        if not 0 < conf.time.fraction <= 1:
            raise InvalidTimeFractionError(conf.time.fraction)
        conf.time.tend = None
        t_0 = sdat.tseries.iloc[0].loc['t']
        t_f = sdat.tseries.iloc[-1].loc['t']
        conf.time.tstart = (t_0 * conf.time.fraction +
                            t_f * (1 - conf.time.fraction))

    lovs = misc.list_of_vars(conf.time.plot)
    if lovs:
        plot_time_series(sdat, lovs)

    if conf.time.compstat:
        compstat(sdat, conf.time.tstart, conf.time.tend)

Response: Implementation of time subcommand.


Instruction:
Can you write a function in Python 3 where it
prints basic information about the current StagYY run.

Response:
def info_cmd():
    """Print basic information about StagYY run."""
    sdat = stagyydata.StagyyData(conf.core.path)
    lsnap = sdat.snaps.last
    lstep = sdat.steps.last
    print('StagYY run in {}'.format(sdat.path))
    if lsnap.geom.threed:
        dimension = '{} x {} x {}'.format(lsnap.geom.nxtot,
                                          lsnap.geom.nytot,
                                          lsnap.geom.nztot)
    elif lsnap.geom.twod_xz:
        dimension = '{} x {}'.format(lsnap.geom.nxtot,
                                     lsnap.geom.nztot)
    else:
        dimension = '{} x {}'.format(lsnap.geom.nytot,
                                     lsnap.geom.nztot)
    if lsnap.geom.cartesian:
        print('Cartesian', dimension)
    elif lsnap.geom.cylindrical:
        print('Cylindrical', dimension)
    else:
        print('Spherical', dimension)
    print('Last timestep:',
          '  istep: {}'.format(lstep.istep),
          '  time:  {}'.format(lstep.timeinfo['t']),
          '  <T>:   {}'.format(lstep.timeinfo['Tmean']),
          sep='\n')
    print('Last snapshot (istep {}):'.format(lsnap.istep),
          '  isnap: {}'.format(lsnap.isnap),
          '  time:  {}'.format(lsnap.timeinfo['t']),
          '  output fields: {}'.format(','.join(lsnap.fields)),
          sep='\n')


Instruction:
Can you write a function in Python 3 where it
prints a list of key - value pairs in a pretty format.

Response:
def _pretty_print(key_val, sep=': ', min_col_width=39, text_width=None):
    """Print a iterable of key/values

    Args:
        key_val (list of (str, str)): the pairs of section names and text.
        sep (str): separator between section names and text.
        min_col_width (int): minimal acceptable column width
        text_width (int): text width to use. If set to None, will try to infer
            the size of the terminal.
    """
    if text_width is None:
        text_width = get_terminal_size().columns
    if text_width < min_col_width:
        min_col_width = text_width
    ncols = (text_width + 1) // (min_col_width + 1)
    colw = (text_width + 1) // ncols - 1
    ncols = min(ncols, len(key_val))

    wrapper = TextWrapper(width=colw)
    lines = []
    for key, val in key_val:
        if len(key) + len(sep) >= colw // 2:
            wrapper.subsequent_indent = ' '
        else:
            wrapper.subsequent_indent = ' ' * (len(key) + len(sep))
        lines.extend(wrapper.wrap('{}{}{}'.format(key, sep, val)))

    chunks = []
    for rem_col in range(ncols, 1, -1):
        isep = ceil(len(lines) / rem_col)
        while isep < len(lines) and lines[isep][0] == ' ':
            isep += 1
        chunks.append(lines[:isep])
        lines = lines[isep:]
    chunks.append(lines)
    lines = zip_longest(*chunks, fillvalue='')

    fmt = '|'.join(['{{:{}}}'.format(colw)] * (ncols - 1))
    fmt += '|{}' if ncols > 1 else '{}'
    print(*(fmt.format(*line) for line in lines), sep='\n')


Instruction:
Make a summary of the following Python 3 code
def _layout(dict_vars, dict_vars_extra):
    desc = [(v, m.description) for v, m in dict_vars.items()]
    desc.extend((v, baredoc(m.description))
                for v, m in dict_vars_extra.items())
    _pretty_print(desc, min_col_width=26)

Response: Print nicely [ var description from phyvars


Instruction:
Can you generate the documentation for the following Python 3 function
def var_cmd():
    print_all = not any(val for _, val in conf.var.opt_vals_())
    if print_all or conf.var.field:
        print('field:')
        _layout(phyvars.FIELD, phyvars.FIELD_EXTRA)
        print()
    if print_all or conf.var.sfield:
        print('surface field:')
        _layout(phyvars.SFIELD, {})
        print()
    if print_all or conf.var.rprof:
        print('rprof:')
        _layout(phyvars.RPROF, phyvars.RPROF_EXTRA)
        print()
    if print_all or conf.var.time:
        print('time:')
        _layout(phyvars.TIME, phyvars.TIME_EXTRA)
        print()
    if print_all or conf.var.plates:
        print('plates:')
        _layout(phyvars.PLATES, {})

Response: Print a list of available variables.


Instruction:
Make a summary of the following Python 3 code
def report_parsing_problems(parsing_out):
    _, empty, faulty = parsing_out
    if CONFIG_FILE in empty or CONFIG_FILE in faulty:
        print('Unable to read global config file', CONFIG_FILE,
              file=sys.stderr)
        print('Please run stagpy config --create',
              sep='\n', end='\n\n', file=sys.stderr)
    if CONFIG_LOCAL in faulty:
        print('Unable to read local config file', CONFIG_LOCAL,
              file=sys.stderr)
        print('Please run stagpy config --create_local',
              sep='\n', end='\n\n', file=sys.stderr)

Response: Output message about potential parsing problems.


Instruction:
How would you explain what the following Python 3 function does
def config_cmd():
    if not (conf.common.config or conf.config.create or
            conf.config.create_local or conf.config.update or
            conf.config.edit):
        config_pp(conf.sections_())
    loam.tools.config_cmd_handler(conf)

Response:
Configuration handling.
    Other Parameters :
        conf. config


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_rprof(step, var):
    if var in step.rprof.columns:
        rprof = step.rprof[var]
        rad = None
        if var in phyvars.RPROF:
            meta = phyvars.RPROF[var]
        else:
            meta = phyvars.Varr(var, None, '1')
    elif var in phyvars.RPROF_EXTRA:
        meta = phyvars.RPROF_EXTRA[var]
        rprof, rad = meta.description(step)
        meta = phyvars.Varr(misc.baredoc(meta.description),
                            meta.kind, meta.dim)
    else:
        raise UnknownRprofVarError(var)
    rprof, _ = step.sdat.scale(rprof, meta.dim)
    if rad is not None:
        rad, _ = step.sdat.scale(rad, 'm')

    return rprof, rad, meta

Response: Extract or compute requested radial profile.


Instruction:
Make a summary of the following Python 3 code
def plot_grid(step):
    rad = get_rprof(step, 'r')[0]
    drad = get_rprof(step, 'dr')[0]
    _, unit = step.sdat.scale(1, 'm')
    if unit:
        unit = ' ({})'.format(unit)
    fig, (ax1, ax2) = plt.subplots(2, sharex=True)
    ax1.plot(rad, '-ko')
    ax1.set_ylabel('$r$' + unit)
    ax2.plot(drad, '-ko')
    ax2.set_ylabel('$dr$' + unit)
    ax2.set_xlim([-0.5, len(rad) - 0.5])
    ax2.set_xlabel('Cell number')
    misc.saveplot(fig, 'grid', step.istep)

Response: Plot cell position and thickness of a single object.


Instruction:
How would you explain what the following Python 3 function does
def plot_average(sdat, lovs):
    steps_iter = iter(sdat.walk.filter(rprof=True))
    try:
        step = next(steps_iter)
    except StopIteration:
        return

    sovs = misc.set_of_vars(lovs)

    istart = step.istep
    nprofs = 1
    rprof_averaged = {}
    rads = {}
    metas = {}

    # assume constant z spacing for the moment
    for rvar in sovs:
        rprof_averaged[rvar], rad, metas[rvar] = get_rprof(step, rvar)
        if rad is not None:
            rads[rvar] = rad

    for step in steps_iter:
        nprofs += 1
        for rvar in sovs:
            rprof_averaged[rvar] += get_rprof(step, rvar)[0]

    ilast = step.istep
    for rvar in sovs:
        rprof_averaged[rvar] /= nprofs
    rcmb, rsurf = misc.get_rbounds(step)
    rprof_averaged['bounds'] = (step.sdat.scale(rcmb, 'm')[0],
                                step.sdat.scale(rsurf, 'm')[0])
    rprof_averaged['r'] = get_rprof(step, 'r')[0] + rprof_averaged['bounds'][0]

    stepstr = '{}_{}'.format(istart, ilast)

    _plot_rprof_list(sdat, lovs, rprof_averaged, metas, stepstr, rads)

Response: Plot time averaged profiles.


Instruction:
Here you have a function in Python 3, explain what it does
def plot_every_step(sdat, lovs):
    sovs = misc.set_of_vars(lovs)

    for step in sdat.walk.filter(rprof=True):
        rprofs = {}
        rads = {}
        metas = {}
        for rvar in sovs:
            rprof, rad, meta = get_rprof(step, rvar)
            rprofs[rvar] = rprof
            metas[rvar] = meta
            if rad is not None:
                rads[rvar] = rad
        rprofs['bounds'] = misc.get_rbounds(step)
        rcmb, rsurf = misc.get_rbounds(step)
        rprofs['bounds'] = (step.sdat.scale(rcmb, 'm')[0],
                            step.sdat.scale(rsurf, 'm')[0])
        rprofs['r'] = get_rprof(step, 'r')[0] + rprofs['bounds'][0]
        stepstr = str(step.istep)

        _plot_rprof_list(sdat, lovs, rprofs, metas, stepstr, rads)

Response: Plot profiles at each time step.


Instruction:
How would you explain what the following Python 3 function does
def cmd():
    sdat = StagyyData(conf.core.path)
    if sdat.rprof is None:
        return

    if conf.rprof.grid:
        for step in sdat.walk.filter(rprof=True):
            plot_grid(step)

    lovs = misc.list_of_vars(conf.rprof.plot)
    if not lovs:
        return

    if conf.rprof.average:
        plot_average(sdat, lovs)
    else:
        plot_every_step(sdat, lovs)

Response:
Implementation of rprof
    Other Parameters


Instruction:
Write a Python 3 script for
enriching a par namelist with the content of a file.

Response:
def _enrich_with_par(par_nml, par_file):
    """Enrich a par namelist with the content of a file."""
    par_new = f90nml.read(str(par_file))
    for section, content in par_new.items():
        if section not in par_nml:
            par_nml[section] = {}
        for par, value in content.items():
            try:
                content[par] = value.strip()
            except AttributeError:
                pass
        par_nml[section].update(content)


Instruction:
Can you write a function in Python 3 where it
reads a new StagYY par file and return a dictionary of names and values.

Response:
def readpar(par_file, root):
    """Read StagYY par file.

    The namelist is populated in chronological order with:

    - :data:`PAR_DEFAULT`, an internal dictionary defining defaults;
    - :data:`PAR_DFLT_FILE`, the global configuration par file;
    - ``par_name_defaultparameters`` if it is defined in ``par_file``;
    - ``par_file`` itself;
    - ``parameters.dat`` if it can be found in the StagYY output directories.

    Args:
        par_file (:class:`pathlib.Path`): path of par file.
        root (:class:`pathlib.Path`): path on which other paths are rooted.
            This is usually par.parent.
    Returns:
        :class:`f90nml.namelist.Namelist`: case insensitive dict of dict of
        values with first key being the namelist and second key the variables'
        name.
    """
    par_nml = deepcopy(PAR_DEFAULT)

    if PAR_DFLT_FILE.is_file():
        _enrich_with_par(par_nml, PAR_DFLT_FILE)
    else:
        PAR_DFLT_FILE.parent.mkdir(exist_ok=True)
        f90nml.write(par_nml, str(PAR_DFLT_FILE))

    if not par_file.is_file():
        raise NoParFileError(par_file)

    par_main = f90nml.read(str(par_file))
    if 'default_parameters_parfile' in par_main:
        par_dflt = par_main['default_parameters_parfile'].get(
            'par_name_defaultparameters', 'par_defaults')
        par_dflt = root / par_dflt
        if not par_dflt.is_file():
            raise NoParFileError(par_dflt)
        _enrich_with_par(par_nml, par_dflt)

    _enrich_with_par(par_nml, par_file)

    par_out = root / par_nml['ioin']['output_file_stem'] / '_parameters.dat'
    if par_out.is_file():
        _enrich_with_par(par_nml, par_out)
    par_out = root / par_nml['ioin']['hdf5_output_folder'] / 'parameters.dat'
    if par_out.is_file():
        _enrich_with_par(par_nml, par_out)
    return par_nml


Instruction:
Can you tell what is the following Python 3 function doing
def get_meshes_fld(step, var):
    fld = step.fields[var]
    if step.geom.twod_xz:
        xmesh, ymesh = step.geom.x_mesh[:, 0, :], step.geom.z_mesh[:, 0, :]
        fld = fld[:, 0, :, 0]
    elif step.geom.cartesian and step.geom.twod_yz:
        xmesh, ymesh = step.geom.y_mesh[0, :, :], step.geom.z_mesh[0, :, :]
        fld = fld[0, :, :, 0]
    else:  # spherical yz
        xmesh, ymesh = step.geom.x_mesh[0, :, :], step.geom.y_mesh[0, :, :]
        fld = fld[0, :, :, 0]
    return xmesh, ymesh, fld

Response: Return scalar field along with coordinates meshes.


Instruction:
Create a Python 3 function to
return vector field components along with coordinates meshes.

Response:
def get_meshes_vec(step, var):
    """Return vector field components along with coordinates meshes.

    Only works properly in 2D geometry.

    Args:
        step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
            instance.
        var (str): vector field name.
    Returns:
        tuple of :class:`numpy.array`: xmesh, ymesh, fldx, fldy
            2D arrays containing respectively the x position, y position, x
            component and y component of the requested vector field.
    """
    if step.geom.twod_xz:
        xmesh, ymesh = step.geom.x_mesh[:, 0, :], step.geom.z_mesh[:, 0, :]
        vec1 = step.fields[var + '1'][:, 0, :, 0]
        vec2 = step.fields[var + '3'][:, 0, :, 0]
    elif step.geom.cartesian and step.geom.twod_yz:
        xmesh, ymesh = step.geom.y_mesh[0, :, :], step.geom.z_mesh[0, :, :]
        vec1 = step.fields[var + '2'][0, :, :, 0]
        vec2 = step.fields[var + '3'][0, :, :, 0]
    else:  # spherical yz
        xmesh, ymesh = step.geom.x_mesh[0, :, :], step.geom.y_mesh[0, :, :]
        pmesh = step.geom.p_mesh[0, :, :]
        vec_phi = step.fields[var + '2'][0, :, :, 0]
        vec_r = step.fields[var + '3'][0, :, :, 0]
        vec1 = vec_r * np.cos(pmesh) - vec_phi * np.sin(pmesh)
        vec2 = vec_phi * np.cos(pmesh) + vec_r * np.sin(pmesh)
    return xmesh, ymesh, vec1, vec2


Instruction:
Write a Python 3 script to
build set of needed field variables.

Response:
def set_of_vars(arg_plot):
    """Build set of needed field variables.

    Each var is a tuple, first component is a scalar field, second component is
    either:

    - a scalar field, isocontours are added to the plot.
    - a vector field (e.g. 'v' for the (v1,v2,v3) vector), arrows are added to
      the plot.

    Args:
        arg_plot (str): string with variable names separated with
            ``,`` (figures), and ``+`` (same plot).
    Returns:
        set of str: set of needed field variables.
    """
    sovs = set(tuple((var + '+').split('+')[:2])
               for var in arg_plot.split(','))
    sovs.discard(('', ''))
    return sovs


Instruction:
Given the following Python 3 function, write the documentation
def plot_scalar(step, var, field=None, axis=None, set_cbar=True, **extra):
    if var in phyvars.FIELD:
        meta = phyvars.FIELD[var]
    else:
        meta = phyvars.FIELD_EXTRA[var]
        meta = phyvars.Varf(misc.baredoc(meta.description), meta.dim)
    if step.geom.threed:
        raise NotAvailableError('plot_scalar only implemented for 2D fields')

    xmesh, ymesh, fld = get_meshes_fld(step, var)
    xmin, xmax = xmesh.min(), xmesh.max()
    ymin, ymax = ymesh.min(), ymesh.max()

    if field is not None:
        fld = field
    if conf.field.perturbation:
        fld = fld - np.mean(fld, axis=0)
    if conf.field.shift:
        fld = np.roll(fld, conf.field.shift, axis=0)

    fld, unit = step.sdat.scale(fld, meta.dim)

    if axis is None:
        fig, axis = plt.subplots(ncols=1)
    else:
        fig = axis.get_figure()

    if step.sdat.par['magma_oceans_in']['magma_oceans_mode']:
        rcmb = step.sdat.par['geometry']['r_cmb']
        xmax = rcmb + 1
        ymax = xmax
        xmin = -xmax
        ymin = -ymax
        rsurf = xmax if step.timeinfo['thick_tmo'] > 0 \
            else step.geom.r_mesh[0, 0, -3]
        cmb = mpat.Circle((0, 0), rcmb, color='dimgray', zorder=0)
        psurf = mpat.Circle((0, 0), rsurf, color='indianred', zorder=0)
        axis.add_patch(psurf)
        axis.add_patch(cmb)

    extra_opts = dict(
        cmap=conf.field.cmap.get(var),
        vmin=conf.plot.vmin,
        vmax=conf.plot.vmax,
        norm=mpl.colors.LogNorm() if var == 'eta' else None,
        rasterized=conf.plot.raster,
        shading='gouraud' if conf.field.interpolate else 'flat',
    )
    extra_opts.update(extra)
    surf = axis.pcolormesh(xmesh, ymesh, fld, **extra_opts)

    cbar = None
    if set_cbar:
        cbar = plt.colorbar(surf, shrink=conf.field.shrinkcb)
        cbar.set_label(meta.description +
                       (' pert.' if conf.field.perturbation else '') +
                       (' ({})'.format(unit) if unit else ''))
    if step.geom.spherical or conf.plot.ratio is None:
        plt.axis('equal')
        plt.axis('off')
    else:
        axis.set_aspect(conf.plot.ratio / axis.get_data_ratio())
    axis.set_adjustable('box')
    axis.set_xlim(xmin, xmax)
    axis.set_ylim(ymin, ymax)
    return fig, axis, surf, cbar

Response: Plot a scalar field.


Instruction:
Write a Python 3 script for
plotting isocontours of scalar field.

Response:
def plot_iso(axis, step, var):
    """Plot isocontours of scalar field.

    Args:
        axis (:class:`matplotlib.axes.Axes`): the axis handler of an
            existing matplotlib figure where the isocontours should
            be plotted.
        step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
            instance.
        var (str): the scalar field name.
    """
    xmesh, ymesh, fld = get_meshes_fld(step, var)
    if conf.field.shift:
        fld = np.roll(fld, conf.field.shift, axis=0)
    axis.contour(xmesh, ymesh, fld, linewidths=1)


Instruction:
Here you have a function in Python 3, explain what it does
def plot_vec(axis, step, var):
    xmesh, ymesh, vec1, vec2 = get_meshes_vec(step, var)
    dipz = step.geom.nztot // 10
    if conf.field.shift:
        vec1 = np.roll(vec1, conf.field.shift, axis=0)
        vec2 = np.roll(vec2, conf.field.shift, axis=0)
    if step.geom.spherical or conf.plot.ratio is None:
        dipx = dipz
    else:
        dipx = step.geom.nytot if step.geom.twod_yz else step.geom.nxtot
        dipx = int(dipx // 10 * conf.plot.ratio) + 1
    axis.quiver(xmesh[::dipx, ::dipz], ymesh[::dipx, ::dipz],
                vec1[::dipx, ::dipz], vec2[::dipx, ::dipz],
                linewidths=1)

Response: Plot the vector field.


Instruction:
Given the following Python 3 function, write the documentation
def cmd():
    sdat = StagyyData(conf.core.path)
    sovs = set_of_vars(conf.field.plot)
    minmax = {}
    if conf.plot.cminmax:
        conf.plot.vmin = None
        conf.plot.vmax = None
        for step in sdat.walk.filter(snap=True):
            for var, _ in sovs:
                if var in step.fields:
                    if var in phyvars.FIELD:
                        dim = phyvars.FIELD[var].dim
                    else:
                        dim = phyvars.FIELD_EXTRA[var].dim
                    field, _ = sdat.scale(step.fields[var], dim)
                    if var in minmax:
                        minmax[var] = (min(minmax[var][0], np.nanmin(field)),
                                       max(minmax[var][1], np.nanmax(field)))
                    else:
                        minmax[var] = np.nanmin(field), np.nanmax(field)
    for step in sdat.walk.filter(snap=True):
        for var in sovs:
            if var[0] not in step.fields:
                print("'{}' field on snap {} not found".format(var[0],
                                                               step.isnap))
                continue
            opts = {}
            if var[0] in minmax:
                opts = dict(vmin=minmax[var[0]][0], vmax=minmax[var[0]][1])
            fig, axis, _, _ = plot_scalar(step, var[0], **opts)
            if valid_field_var(var[1]):
                plot_iso(axis, step, var[1])
            elif var[1]:
                plot_vec(axis, step, var[1])
            oname = '{}_{}'.format(*var) if var[1] else var[0]
            misc.saveplot(fig, oname, step.isnap)

Response: Implementation of field subcommand.


Instruction:
Can you generate the documentation for the following Python 3 function
def _steps_to_slices():
    if not (conf.core.timesteps or conf.core.snapshots):
        # default to the last snap
        conf.core.timesteps = None
        conf.core.snapshots = slice(-1, None, None)
        return
    elif conf.core.snapshots:
        # snapshots take precedence over timesteps
        # if both are defined
        conf.core.timesteps = None
        steps = conf.core.snapshots
    else:
        conf.core.snapshots = None
        steps = conf.core.timesteps
    steps = steps.split(':')
    steps[0] = int(steps[0]) if steps[0] else None
    if len(steps) == 1:
        steps.append(steps[0] + 1)
    steps[1] = int(steps[1]) if steps[1] else None
    if len(steps) != 3:
        steps = steps[0:2] + [1]
    steps[2] = int(steps[2]) if steps[2] else None
    steps = slice(*steps)
    if conf.core.snapshots is not None:
        conf.core.snapshots = steps
    else:
        conf.core.timesteps = steps

Response: parse timesteps and snapshots arguments and return slices


Instruction:
Write a Python 3 function that can
parse cmd line arguments.

Response:
def parse_args(arglist=None):
    """Parse cmd line arguments.

    Update :attr:`stagpy.conf` accordingly.

    Args:
        arglist (list of str): the list of cmd line arguments. If set to
            None, the arguments are taken from :attr:`sys.argv`.

    Returns:
        function: the function implementing the sub command to be executed.
    """
    climan = CLIManager(conf, **SUB_CMDS)

    create_complete_files(climan, CONFIG_DIR, 'stagpy', 'stagpy-git',
                          zsh_sourceable=True)

    cmd_args, all_subs = climan.parse_args(arglist)
    sub_cmd = cmd_args.loam_sub_name

    if sub_cmd is None:
        return cmd_args.func

    if sub_cmd != 'config':
        commands.report_parsing_problems(PARSING_OUT)

    if conf.common.set:
        set_conf_str(conf, conf.common.set)

    if conf.common.config:
        commands.config_pp(all_subs)

    load_mplstyle()

    try:
        _steps_to_slices()
    except AttributeError:
        pass
    return cmd_args.func


Instruction:
Can you generate the documentation for the following Python 3 function
def detect_plates_vzcheck(step, seuil_memz):
    v_z = step.fields['v3'][0, :, :, 0]
    v_x = step.fields['v2'][0, :, :, 0]
    tcell = step.fields['T'][0, :, :, 0]
    n_z = step.geom.nztot
    nphi = step.geom.nptot  # -1? should be OK, ghost not included
    rcmb = max(0, step.geom.rcmb)
    radius = step.geom.r_coord + rcmb
    radiusgrid = step.geom.rgeom[:, 0] + rcmb
    dphi = 1 / nphi

    # calculing temperature on the grid and vz_mean
    vz_mean = 0
    tgrid = np.zeros((nphi, n_z + 1))
    tgrid[:, 0] = 1
    for i_z in range(1, n_z):
        for phi in range(nphi):
            tgrid[phi, i_z] = (
                tcell[phi, i_z - 1] *
                (radiusgrid[i_z] - radius[i_z - 1]) + tcell[phi, i_z] *
                (-radiusgrid[i_z] + radius[i_z])) / (radius[i_z] -
                                                     radius[i_z - 1])
            vz_mean += abs(v_z[phi, i_z]) / (nphi * n_z)

    flux_c = n_z * [0]
    for i_z in range(1, n_z - 1):
        for phi in range(nphi):
            flux_c[i_z] += (tgrid[phi, i_z] - step.timeinfo.loc['Tmean']) * \
                v_z[phi, i_z] * radiusgrid[i_z] * dphi

    # checking stagnant lid
    if all(abs(flux_c[i_z]) <= np.max(flux_c) / 50
           for i_z in range(n_z - n_z // 20, n_z)):
        raise error.StagnantLidError(step.sdat)
    else:
        # verifying horizontal plate speed and closeness of plates
        dvphi = nphi * [0]
        dvx_thres = 16 * step.timeinfo.loc['vrms']

        for phi in range(0, nphi):
            dvphi[phi] = (v_x[phi, n_z - 1] -
                          v_x[phi - 1, n_z - 1]) / ((1 + rcmb) * dphi)
        limits = []
        for phi in range(0, nphi - nphi // 33):
            mark = all(abs(dvphi[i]) <= abs(dvphi[phi])
                       for i in range(phi - nphi // 33, phi + nphi // 33))
            if mark and abs(dvphi[phi]) >= dvx_thres:
                limits.append(phi)
        for phi in range(nphi - nphi // 33 + 1, nphi):
            mark = all(abs(dvphi[i]) <= abs(dvphi[phi])
                       for i in range(phi - nphi // 33 - nphi,
                                      phi + nphi // 33 - nphi))
            if mark and abs(dvphi[phi]) >= dvx_thres:
                limits.append(phi)

        # verifying vertical speed
        k = 0
        for i in range(len(limits)):
            vzm = 0
            phi = limits[i - k]
            for i_z in range(1 if phi == nphi - 1 else 0, n_z):
                vzm += (abs(v_z[phi, i_z]) +
                        abs(v_z[phi - 1, i_z]) +
                        abs(v_z[(phi + 1) % nphi, i_z])) / (n_z * 3)

            vz_thres = vz_mean * 0.1 + seuil_memz / 2 if seuil_memz else 0
            if vzm < vz_thres:
                limits.remove(phi)
                k += 1

    return limits, nphi, dvphi, vz_thres, v_x[:, n_z - 1]

Response: detect plates and check with vz and plate size


Instruction:
Can you generate the documentation for the following Python 3 function
def detect_plates(step, vrms_surface, fids, time):
    vphi = step.fields['v2'][0, :, :, 0]
    ph_coord = step.geom.p_coord

    if step.sdat.par['boundaries']['air_layer']:
        dsa = step.sdat.par['boundaries']['air_thickness']
        # we are a bit below the surface; should check if you are in the
        # thermal boundary layer
        indsurf = np.argmin(abs((1 - dsa) - step.geom.r_coord)) - 4
    else:
        indsurf = -1

    vph2 = 0.5 * (vphi + np.roll(vphi, 1, 0))  # interpolate to the same phi
    # velocity derivation
    dvph2 = (np.diff(vph2[:, indsurf]) / (ph_coord[0] * 2.))

    io_surface(step.isnap, time, fids[6], dvph2)
    io_surface(step.isnap, time, fids[7], vph2[:-1, indsurf])

    # prepare stuff to find trenches and ridges
    myorder_trench = 15 if step.sdat.par['boundaries']['air_layer'] else 10
    myorder_ridge = 20  # threshold

    # finding trenches
    pom2 = np.copy(dvph2)
    if step.sdat.par['boundaries']['air_layer']:
        maskbigdvel = -30 * vrms_surface
    else:
        maskbigdvel = -10 * vrms_surface
    pom2[pom2 > maskbigdvel] = maskbigdvel
    argless_dv = argrelextrema(
        pom2, np.less, order=myorder_trench, mode='wrap')[0]
    trench = ph_coord[argless_dv]
    velocity_trench = vph2[argless_dv, indsurf]
    dv_trench = dvph2[argless_dv]

    # finding ridges
    pom2 = np.copy(dvph2)
    masksmalldvel = np.amax(dvph2) * 0.2
    pom2[pom2 < masksmalldvel] = masksmalldvel
    arggreat_dv = argrelextrema(
        pom2, np.greater, order=myorder_ridge, mode='wrap')[0]
    ridge = ph_coord[arggreat_dv]

    # elimination of ridges that are too close to trench
    argdel = []
    if trench.any() and ridge.any():
        for i, ridge_i in enumerate(ridge):
            mdistance = np.amin(abs(trench - ridge_i))
            if mdistance < 0.016:
                argdel.append(i)
        if argdel:
            print('deleting from ridge', trench, ridge[argdel])
            ridge = np.delete(ridge, np.array(argdel))
            arggreat_dv = np.delete(arggreat_dv, np.array(argdel))

    dv_ridge = dvph2[arggreat_dv]
    if 'age' in conf.plates:
        agefld = step.fields['age'][0, :, :, 0]
        age_surface = np.ma.masked_where(agefld[:, indsurf] < 0.00001,
                                         agefld[:, indsurf])
        age_surface_dim = age_surface * vrms_surface *\
            conf.scaling.ttransit / conf.scaling.yearins / 1.e6
        agetrench = age_surface_dim[argless_dv]  # age at the trench
    else:
        agetrench = np.zeros(len(argless_dv))

    # writing the output into a file, all time steps are in one file
    for itrench in np.arange(len(trench)):
        fids[0].write("%7.0f %11.7f %10.6f %9.2f %9.2f \n" % (
            step.isnap,
            step.geom.ti_ad,
            trench[itrench],
            velocity_trench[itrench],
            agetrench[itrench]
        ))

    return trench, ridge, agetrench, dv_trench, dv_ridge

Response: detect plates using derivative of horizontal velocity


Instruction:
Write a Python 3 function that can
plot lines designating ridges and trenches

Response:
def plot_plate_limits(axis, ridges, trenches, ymin, ymax):
    """plot lines designating ridges and trenches"""
    for trench in trenches:
        axis.axvline(
            x=trench, ymin=ymin, ymax=ymax,
            color='red', ls='dashed', alpha=0.4)
    for ridge in ridges:
        axis.axvline(
            x=ridge, ymin=ymin, ymax=ymax,
            color='green', ls='dashed', alpha=0.4)
    axis.set_xlim(0, 2 * np.pi)
    axis.set_ylim(ymin, ymax)


Instruction:
Can you generate the documentation for the following Python 3 function
def plot_plate_limits_field(axis, rcmb, ridges, trenches):
    for trench in trenches:
        xxd = (rcmb + 1.02) * np.cos(trench)  # arrow begin
        yyd = (rcmb + 1.02) * np.sin(trench)  # arrow begin
        xxt = (rcmb + 1.35) * np.cos(trench)  # arrow end
        yyt = (rcmb + 1.35) * np.sin(trench)  # arrow end
        axis.annotate('', xy=(xxd, yyd), xytext=(xxt, yyt),
                      arrowprops=dict(facecolor='red', shrink=0.05))
    for ridge in ridges:
        xxd = (rcmb + 1.02) * np.cos(ridge)
        yyd = (rcmb + 1.02) * np.sin(ridge)
        xxt = (rcmb + 1.35) * np.cos(ridge)
        yyt = (rcmb + 1.35) * np.sin(ridge)
        axis.annotate('', xy=(xxd, yyd), xytext=(xxt, yyt),
                      arrowprops=dict(facecolor='green', shrink=0.05))

Response: plot arrows designating ridges and trenches in 2D field plots


Instruction:
Can you generate a brief explanation for the following Python 3 code
def io_surface(timestep, time, fid, fld):
    fid.write("{} {}".format(timestep, time))
    fid.writelines(["%10.2e" % item for item in fld[:]])
    fid.writelines(["\n"])

Response: Output for surface files


Instruction:
Write a Python 3 function that can
calculate stress in the lithosphere

Response:
def lithospheric_stress(step, trench, ridge, time):
    """calculate stress in the lithosphere"""
    timestep = step.isnap
    base_lith = step.geom.rcmb + 1 - 0.105

    stressfld = step.fields['sII'][0, :, :, 0]
    stressfld = np.ma.masked_where(step.geom.r_mesh[0] < base_lith, stressfld)

    # stress integration in the lithosphere
    dzm = (step.geom.r_coord[1:] - step.geom.r_coord[:-1])
    stress_lith = np.sum((stressfld[:, 1:] * dzm.T), axis=1)
    ph_coord = step.geom.p_coord  # probably doesn't need alias

    # plot stress in the lithosphere
    fig, axis, _, _ = field.plot_scalar(step, 'sII', stressfld,
                                        cmap='plasma_r', vmin=0, vmax=300)
    # Annotation with time and step
    axis.text(1., 0.9, str(round(time, 0)) + ' My', transform=axis.transAxes)
    axis.text(1., 0.1, str(timestep), transform=axis.transAxes)
    misc.saveplot(fig, 'lith', timestep)

    # velocity
    vphi = step.fields['v2'][0, :, :, 0]
    vph2 = 0.5 * (vphi + np.roll(vphi, 1, 0))  # interpolate to the same phi

    # position of continents
    concfld = step.fields['c'][0, :, :, 0]
    if step.sdat.par['boundaries']['air_layer']:
        # we are a bit below the surface; delete "-some number"
        # to be just below
        dsa = step.sdat.par['boundaries']['air_thickness']
        # depth to detect the continents
        indcont = np.argmin(abs((1 - dsa) - step.geom.r_coord)) - 10
    else:
        # depth to detect continents
        indcont = -1
    if step.sdat.par['boundaries']['air_layer'] and\
            not step.sdat.par['continents']['proterozoic_belts']:
        continents = np.ma.masked_where(
            np.logical_or(concfld[:-1, indcont] < 3,
                          concfld[:-1, indcont] > 4),
            concfld[:-1, indcont])
    elif step.sdat.par['boundaries']['air_layer'] and\
            step.sdat.par['continents']['proterozoic_belts']:
        continents = np.ma.masked_where(
            np.logical_or(concfld[:-1, indcont] < 3,
                          concfld[:-1, indcont] > 5),
            concfld[:-1, indcont])
    elif step.sdat.par['tracersin']['tracers_weakcrust']:
        continents = np.ma.masked_where(
            concfld[:-1, indcont] < 3, concfld[:-1, indcont])
    else:
        continents = np.ma.masked_where(
            concfld[:-1, indcont] < 2, concfld[:-1, indcont])

    # masked array, only continents are true
    continentsall = continents / continents

    # plot integrated stress in the lithosphere
    fig0, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(12, 8))
    ax1.plot(ph_coord[:-1], vph2[:-1, -1], label='Vel')
    ax1.axhline(y=0, xmin=0, xmax=2 * np.pi,
                color='black', ls='solid', alpha=0.2)
    ax1.set_ylabel("Velocity")
    ax1.text(0.95, 1.07, str(round(time, 0)) + ' My',
             transform=ax1.transAxes)
    ax1.text(0.01, 1.07, str(round(step.geom.ti_ad, 8)),
             transform=ax1.transAxes)

    intstr_scale = step.sdat.scales.stress * step.sdat.scales.length / 1.e12
    ax2.plot(ph_coord, stress_lith * intstr_scale, color='k', label='Stress')
    ax2.set_ylabel(r"Integrated stress [$TN\,m^{-1}$]")

    plot_plate_limits(ax1, ridge, trench, conf.plates.vmin,
                      conf.plates.vmax)
    plot_plate_limits(ax2, ridge, trench, conf.plates.stressmin,
                      conf.plates.lstressmax)
    ax1.set_xlim(0, 2 * np.pi)
    ax1.set_title(timestep)

    ax1.fill_between(
        ph_coord[:-1], continentsall * conf.plates.vmin,
        conf.plates.vmax, facecolor='#8b6914', alpha=0.2)
    ax1.set_ylim(conf.plates.vmin, conf.plates.vmax)
    ax2.fill_between(
        ph_coord[:-1], continentsall * conf.plates.stressmin,
        conf.plates.lstressmax, facecolor='#8b6914', alpha=0.2)
    ax2.set_ylim(conf.plates.stressmin, conf.plates.lstressmax)

    misc.saveplot(fig0, 'svelslith', timestep)


Instruction:
Write a Python 3 script for
building set of needed variables.

Response:
def set_of_vars(arg_plot):
    """Build set of needed variables.

    Args:
        arg_plot (str): string with variable names separated with ``,``.
    Returns:
        set of str: set of variables.
    """
    return set(var for var in arg_plot.split(',') if var in phyvars.PLATES)


Instruction:
Write a Python 3 function that can
plot several plates information.

Response:
def main_plates(sdat):
    """Plot several plates information."""
    # calculating averaged horizontal surface velocity
    # needed for redimensionalisation
    ilast = sdat.rprof.index.levels[0][-1]
    rlast = sdat.rprof.loc[ilast]
    nprof = 0
    uprof_averaged = rlast.loc[:, 'vhrms'] * 0
    for step in sdat.walk.filter(rprof=True):
        uprof_averaged += step.rprof['vhrms']
        nprof += 1
    uprof_averaged /= nprof
    radius = rlast['r'].values
    if sdat.par['boundaries']['air_layer']:
        dsa = sdat.par['boundaries']['air_thickness']
        isurf = np.argmin(abs(radius - radius[-1] + dsa))
        vrms_surface = uprof_averaged.iloc[isurf]
        isurf = np.argmin(abs((1 - dsa) - radius))
        isurf -= 4  # why different isurf for the rest?
    else:
        isurf = -1
        vrms_surface = uprof_averaged.iloc[isurf]

    with misc.InchoateFiles(8, 'plates') as fids:
        fids.fnames = ['plate_velocity', 'distance_subd', 'continents',
                       'flux', 'topography', 'age', 'velderiv', 'velocity']
        fids[0].write('#  it  time  ph_trench vel_trench age_trench\n')
        fids[1].write('#  it      time   time [My]   distance     '
                      'ph_trench     ph_cont  age_trench [My]\n')

        istart, iend = None, None
        for step in sdat.walk.filter(fields=['T']):
            # could check other fields too
            timestep = step.isnap
            istart = timestep if istart is None else istart
            iend = timestep
            print('Treating snapshot', timestep)

            rcmb = step.geom.rcmb
            # topography
            fname = sdat.filename('sc', timestep=timestep, suffix='.dat')
            topo = np.genfromtxt(str(fname))
            # rescaling topography!
            if sdat.par['boundaries']['air_layer']:
                topo[:, 1] = topo[:, 1] / (1. - dsa)

            time = step.geom.ti_ad * vrms_surface *\
                conf.scaling.ttransit / conf.scaling.yearins / 1.e6
            trenches, ridges, agetrenches, _, _ =\
                detect_plates(step, vrms_surface, fids, time)
            plot_plates(step, time, vrms_surface, trenches, ridges,
                        agetrenches, topo, fids)

            # prepare for continent plotting
            concfld = step.fields['c'][0, :, :, 0]
            continentsfld = np.ma.masked_where(
                concfld < 3, concfld)  # plotting continents, to-do
            continentsfld = continentsfld / continentsfld

            temp = step.fields['T'][0, :, :, 0]
            tgrad = (temp[:, isurf - 1] - temp[:, isurf]) /\
                (step.geom.r_coord[isurf] - step.geom.r_coord[isurf - 1])

            io_surface(timestep, time, fids[2], concfld[:-1, isurf])
            io_surface(timestep, time, fids[3], tgrad)
            io_surface(timestep, time, fids[4], topo[:, 1])
            if 'age' in conf.plates.plot:
                io_surface(timestep, time, fids[5],
                           step.fields['age'][0, :, isurf, 0])

            # plot viscosity field with position of trenches and ridges
            etamin, _ = sdat.scale(1e-2, 'Pa')
            etamax, _ = sdat.scale(sdat.par['viscosity']['eta_max'], 'Pa')
            fig, axis, _, _ = field.plot_scalar(step, 'eta',
                                                vmin=etamin, vmax=etamax)

            # plotting continents
            field.plot_scalar(step, 'c', continentsfld, axis, False,
                              cmap='cool_r', vmin=0, vmax=0)
            cmap2 = plt.cm.ocean
            cmap2.set_over('m')

            # plotting velocity vectors
            field.plot_vec(axis, step, 'v')

            # Annotation with time and step
            axis.text(1., 0.9, str(round(time, 0)) + ' My',
                      transform=axis.transAxes)
            axis.text(1., 0.1, str(timestep),
                      transform=axis.transAxes)

            # Put arrow where ridges and trenches are
            plot_plate_limits_field(axis, rcmb, ridges, trenches)

            misc.saveplot(fig, 'eta', timestep, close=False)

            # Zoom
            if conf.plates.zoom is not None:
                if not 0 <= conf.plates.zoom <= 360:
                    raise error.InvalidZoomError(conf.plates.zoom)
                if 45 < conf.plates.zoom <= 135:
                    ladd, radd, uadd, dadd = 0.8, 0.8, 0.05, 0.1
                elif 135 < conf.plates.zoom <= 225:
                    ladd, radd, uadd, dadd = 0.05, 0.1, 0.8, 0.8
                elif 225 < conf.plates.zoom <= 315:
                    ladd, radd, uadd, dadd = 0.8, 0.8, 0.1, 0.05
                else:  # >315 or <=45
                    ladd, radd, uadd, dadd = 0.1, 0.05, 0.8, 0.8
                xzoom = (rcmb + 1) * np.cos(np.radians(conf.plates.zoom))
                yzoom = (rcmb + 1) * np.sin(np.radians(conf.plates.zoom))
                axis.set_xlim(xzoom - ladd, xzoom + radd)
                axis.set_ylim(yzoom - dadd, yzoom + uadd)
                misc.saveplot(fig, 'etazoom', timestep, close=False)
            plt.close(fig)

            # plot stress field with position of trenches and ridges
            if 'str' in conf.plates.plot:
                fig, axis, _, _ = field.plot_scalar(step, 'sII',
                                                    vmin=0, vmax=300)

                # Annotation with time and step
                axis.text(1., 0.9, str(round(time, 0)) + ' My',
                          transform=axis.transAxes)
                axis.text(1., 0.1, str(timestep),
                          transform=axis.transAxes)

                # Put arrow where ridges and trenches are
                plot_plate_limits_field(axis, rcmb, ridges, trenches)

                misc.saveplot(fig, 's', timestep, close=False)

                # Zoom
                if conf.plates.zoom is not None:
                    axis.set_xlim(xzoom - ladd, xzoom + radd)
                    axis.set_ylim(yzoom - dadd, yzoom + uadd)
                    misc.saveplot(fig, 'szoom', timestep, close=False)
                plt.close(fig)

                # calculate stresses in the lithosphere
                lithospheric_stress(step, trenches, ridges, time)

            # plotting the principal deviatoric stress field
            if 'sx' in conf.plates.plot:
                fig, axis, _, _ = field.plot_scalar(step, 'sII',
                                                    alpha=0.1)

                # plotting continents
                field.plot_scalar(step, 'c', continentsfld, axis, False,
                                  cmap='cool_r', vmin=0, vmax=0)
                cmap2 = plt.cm.ocean
                cmap2.set_over('m')

                # plotting principal deviatoric stress
                field.plot_vec(axis, step, 'sx')

                # Annotation with time and step
                axis.text(1., 0.9, str(round(time, 0)) + ' My',
                          transform=axis.transAxes)
                axis.text(1., 0.1, str(timestep),
                          transform=axis.transAxes)

                # Put arrow where ridges and trenches are
                plot_plate_limits_field(axis, rcmb, ridges, trenches)

                misc.saveplot(fig, 'sx', timestep)

        # determine names of files
        ptn = misc.out_name('{}_{}_{}')
        stem = ptn.format(fids.fnames[0], istart, iend)
        idx = 0
        fmt = '{}.dat'
        while pathlib.Path(fmt.format(stem, idx)).is_file():
            fmt = '{}_{}.dat'
            idx += 1
        fids.fnames = [fmt.format(ptn.format(fname, istart, iend), idx)
                       for fname in fids.fnames]


Instruction:
Write a Python 3 script to
create config files as necessary.

Response:
def _check_config():
    """Create config files as necessary."""
    config.CONFIG_DIR.mkdir(parents=True, exist_ok=True)
    verfile = config.CONFIG_DIR / '.version'
    uptodate = verfile.is_file() and verfile.read_text() == __version__
    if not uptodate:
        verfile.write_text(__version__)
    if not (uptodate and config.CONFIG_FILE.is_file()):
        conf.create_config_(update=True)
    for stfile in ('stagpy-paper.mplstyle',
                   'stagpy-slides.mplstyle'):
        stfile_conf = config.CONFIG_DIR / stfile
        if not (uptodate and stfile_conf.is_file()):
            stfile_local = pathlib.Path(__file__).parent / stfile
            shutil.copy(str(stfile_local), str(stfile_conf))


Instruction:
Make a summary of the following Python 3 code
def load_mplstyle():
    plt = importlib.import_module('matplotlib.pyplot')
    if conf.plot.mplstyle:
        for style in conf.plot.mplstyle.split():
            stfile = config.CONFIG_DIR / (style + '.mplstyle')
            if stfile.is_file():
                style = str(stfile)
            try:
                plt.style.use(style)
            except OSError:
                print('Cannot import style {}.'.format(style),
                      file=sys.stderr)
                conf.plot.mplstyle = ''
    if conf.plot.xkcd:
        plt.xkcd()

Response: Try to load conf. plot. mplstyle matplotlib style.


Instruction:
Given the following Python 3 function, write the documentation
def dtime(sdat, tstart=None, tend=None):
    tseries = sdat.tseries_between(tstart, tend)
    time = tseries['t'].values
    return time[1:] - time[:-1], time[:-1]

Response:
Time increment dt.

    Compute dt as a function of time.

    Args:
        sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
        tstart (float): time at which the computation should start. Use the
            beginning of the time series data if set to None.
        tend (float): time at which the computation should end. Use the
            end of the time series data if set to None.
    Returns:
        tuple of :class:`numpy.array`: dt and time arrays.


Instruction:
Here you have a function in Python 3, explain what it does
def dt_dt(sdat, tstart=None, tend=None):
    tseries = sdat.tseries_between(tstart, tend)
    time = tseries['t'].values
    temp = tseries['Tmean'].values
    dtdt = (temp[1:] - temp[:-1]) / (time[1:] - time[:-1])
    return dtdt, time[:-1]

Response: Compute dT and dt as a function of time using an explicit Euler scheme.


Instruction:
Create a Python 3 function for
computing the energy balance of a given time series.

Response:
def ebalance(sdat, tstart=None, tend=None):
    """Energy balance.

    Compute Nu_t - Nu_b + V*dT/dt as a function of time using an explicit
    Euler scheme. This should be zero if energy is conserved.

    Args:
        sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
        tstart (float): time at which the computation should start. Use the
            beginning of the time series data if set to None.
        tend (float): time at which the computation should end. Use the
            end of the time series data if set to None.
    Returns:
        tuple of :class:`numpy.array`: energy balance and time arrays.
    """
    tseries = sdat.tseries_between(tstart, tend)
    rbot, rtop = misc.get_rbounds(sdat.steps.last)
    if rbot != 0:  # spherical
        coefsurf = (rtop / rbot)**2
        volume = rbot * ((rtop / rbot)**3 - 1) / 3
    else:
        coefsurf = 1.
        volume = 1.
    dtdt, time = dt_dt(sdat, tstart, tend)
    ftop = tseries['ftop'].values * coefsurf
    fbot = tseries['fbot'].values
    radio = tseries['H_int'].values
    ebal = ftop[1:] - fbot[1:] + volume * (dtdt - radio[1:])
    return ebal, time


Instruction:
Can you generate the documentation for the following Python 3 function
def mobility(sdat, tstart=None, tend=None):
    tseries = sdat.tseries_between(tstart, tend)
    steps = sdat.steps[tseries.index[0]:tseries.index[-1]]
    time = []
    mob = []
    for step in steps.filter(rprof=True):
        time.append(step.timeinfo['t'])
        mob.append(step.rprof.iloc[-1].loc['vrms'] / step.timeinfo['vrms'])
    return np.array(mob), np.array(time)

Response:
Plates mobility.
    Compute the ratio vsurf / vrms.
    Compute the ratio vsurf / vrms.
    Compute the ratio vsurf / vrms.
    Compute the ratio vsurf / vrms.
    Compute the ratio vsurf / vrms.
    Compute the ratio vsurf / vrms.
    Compute the ratio vsurf / vrms.
    Compute the ratio vsurf to the mobility of the mobility of the mobility.


Instruction:
Here you have a function in Python 3, explain what it does
def r_edges(step):
    rbot, rtop = misc.get_rbounds(step)
    centers = step.rprof.loc[:, 'r'].values + rbot
    # assume walls are mid-way between T-nodes
    # could be T-nodes at center between walls
    edges = (centers[:-1] + centers[1:]) / 2
    edges = np.insert(edges, 0, rbot)
    edges = np.append(edges, rtop)
    return edges, edges

Response: Returns the edges of the bottom and top walls of a cluster.


Instruction:
How would you implement a function in Python 3 that
scales profile to take sphericity into account

Response:
def _scale_prof(step, rprof, rad=None):
    """Scale profile to take sphericity into account"""
    rbot, rtop = misc.get_rbounds(step)
    if rbot == 0:  # not spherical
        return rprof
    if rad is None:
        rad = step.rprof['r'].values + rbot
    return rprof * (2 * rad / (rtop + rbot))**2


Instruction:
Implement a function in Python 3 to
scale diffusion. This computation takes sphericity into account if necessary. This computation takes sphericity into account if necessary.

Response:
def diffs_prof(step):
    """Scaled diffusion.

    This computation takes sphericity into account if necessary.

    Args:
        step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
            instance.
    Returns:
        tuple of :class:`numpy.array`: the diffusion and the radial position
        at which it is evaluated.
    """
    diff, rad = diff_prof(step)
    return _scale_prof(step, diff, rad), rad


Instruction:
Can you generate the documentation for the following Python 3 function
def energy_prof(step):
    diff, rad = diffs_prof(step)
    adv, _ = advts_prof(step)
    return (diff + np.append(adv, 0)), rad

Response:
Energy flux.

    This computation takes sphericity into account if necessary.

    Args:
        step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
            instance.
    Returns:
        tuple of :class:`numpy.array`: the energy flux and the radial position
        at which it is evaluated.


Instruction:
Given the following Python 3 function, write the documentation
def advth(step):
    rbot, rtop = misc.get_rbounds(step)
    rmean = 0.5 * (rbot + rtop)
    rad = step.rprof['r'].values + rbot
    radio = step.timeinfo['H_int']
    if rbot != 0:  # spherical
        th_adv = -(rtop**3 - rad**3) / rmean**2 / 3
    else:
        th_adv = rad - rtop
    th_adv *= radio
    th_adv += step.timeinfo['Nutop']
    return th_adv, None

Response:
Theoretical advection.

    This compute the theoretical profile of total advection as function of
    radius.

    Args:
        step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
            instance.
    Returns:
        tuple of :class:`numpy.array` and None: the theoretical advection.
        The second element of the tuple is None.


Instruction:
Explain what the following Python 3 code does
def init_c_overturn(step):
    rbot, rtop = misc.get_rbounds(step)
    xieut = step.sdat.par['tracersin']['fe_eut']
    k_fe = step.sdat.par['tracersin']['k_fe']
    xi0l = step.sdat.par['tracersin']['fe_cont']
    xi0s = k_fe * xi0l
    xired = xi0l / xieut
    rsup = (rtop**3 - xired**(1 / (1 - k_fe)) *
            (rtop**3 - rbot**3))**(1 / 3)

    def initprof(rpos):
        """Theoretical initial profile."""
        if rpos < rsup:
            return xi0s * ((rtop**3 - rbot**3) /
                           (rtop**3 - rpos**3))**(1 - k_fe)
        return xieut

    rad = np.linspace(rbot, rtop, 500)
    initprof = np.vectorize(initprof)
    return initprof(rad), rad

Response: This function computes the initial concentration of a single object.


Instruction:
How would you implement a function in Python 3 that
streams function for the current object.

Response:
def stream_function(step):
    """Stream function.

    Args:
        step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
            instance.
    Returns:
        :class:`numpy.array`: the stream function field, with four dimensions:
        x-direction, y-direction, z-direction and block.
    """
    if step.geom.twod_yz:
        x_coord = step.geom.y_coord
        v_x = step.fields['v2'][0, :, :, 0]
        v_z = step.fields['v3'][0, :, :, 0]
        shape = (1, v_x.shape[0], v_x.shape[1], 1)
    elif step.geom.twod_xz and step.geom.cartesian:
        x_coord = step.geom.x_coord
        v_x = step.fields['v1'][:, 0, :, 0]
        v_z = step.fields['v3'][:, 0, :, 0]
        shape = (v_x.shape[0], 1, v_x.shape[1], 1)
    else:
        raise NotAvailableError('Stream function only implemented in '
                                '2D cartesian and spherical annulus')
    psi = np.zeros_like(v_x)
    if step.geom.spherical:  # YZ annulus
        # positions
        r_nc = step.geom.r_coord + step.geom.rcmb  # numerical centers
        r_pc = step.geom.r_mesh[0, 0, :]  # physical centers
        r_nw = r_edges(step)[0][:2]  # numerical walls of first cell
        # vz at center of bottom cells
        vz0 = ((r_nw[1] - r_nc[0]) * v_z[:, 0] +
               (r_nc[0] - r_nw[0]) * v_z[:, 1]) / (r_nw[1] - r_nw[0])
        psi[1:, 0] = -integrate.cumtrapz(r_pc[0]**2 * vz0, x=x_coord)
        # vx at center
        vxc = (v_x + np.roll(v_x, -1, axis=0)) / 2
        for i_x in range(len(x_coord)):
            psi[i_x, 1:] = psi[i_x, 0] + \
                integrate.cumtrapz(r_pc * vxc[i_x], x=r_nc)
    else:  # assume cartesian geometry
        z_nc = step.geom.z_coord
        z_nw = r_edges(step)[0][:2]
        vz0 = ((z_nw[1] - z_nc[0]) * v_z[:, 0] +
               (z_nc[0] - z_nw[0]) * v_z[:, 1]) / (z_nw[1] - z_nw[0])
        psi[1:, 0] = -integrate.cumtrapz(vz0, x=x_coord)
        # vx at center
        vxc = (v_x + np.roll(v_x, -1, axis=0)) / 2
        for i_x in range(len(x_coord)):
            psi[i_x, 1:] = psi[i_x, 0] + \
                integrate.cumtrapz(vxc[i_x], x=z_nc)
    if step.geom.twod_xz:
        psi = - psi
    psi = np.reshape(psi, shape)
    return psi


Instruction:
Explain what the following Python 3 code does
def last(self):
        if self._last is UNDETERMINED:
            # not necessarily the last one...
            self._last = self.sdat.tseries.index[-1]
        return self[self._last]

Response: Return the last available entry in the sequence.


Instruction:
Given the following Python 3 function, write the documentation
def bind(self, isnap, istep):
        self._isteps[isnap] = istep
        self.sdat.steps[istep].isnap = isnap

Response: Bind the isnap and istep to the object.


Instruction:
Here you have a function in Python 3, explain what it does
def _pass(self, step):
        okf = True
        okf = okf and (not self._flt['snap'] or step.isnap is not None)
        okf = okf and (not self._flt['rprof'] or step.rprof is not None)
        okf = okf and all(f in step.fields for f in self._flt['fields'])
        okf = okf and bool(self._flt['func'](step))
        return okf

Response: Check whether a step passes the filters.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def filter(self, **filters):
        for flt, val in self._flt.items():
            self._flt[flt] = filters.pop(flt, val)
        if filters:
            raise error.UnknownFiltersError(filters.keys())
        return self

Response: Update the relevant filters with provided arguments.


Instruction:
Here you have a function in Python 3, explain what it does
def tseries(self):
        if self._stagdat['tseries'] is UNDETERMINED:
            timefile = self.filename('TimeSeries.h5')
            self._stagdat['tseries'] = stagyyparsers.time_series_h5(
                timefile, list(phyvars.TIME.keys()))
            if self._stagdat['tseries'] is not None:
                return self._stagdat['tseries']
            timefile = self.filename('time.dat')
            if self.hdf5 and not timefile.is_file():
                # check legacy folder as well
                timefile = self.filename('time.dat', force_legacy=True)
            self._stagdat['tseries'] = stagyyparsers.time_series(
                timefile, list(phyvars.TIME.keys()))
        return self._stagdat['tseries']

Response: Return the time series data.


Instruction:
Given the following Python 3 function, write the documentation
def files(self):
        if self._rundir['ls'] is UNDETERMINED:
            out_stem = pathlib.Path(self.par['ioin']['output_file_stem'] + '_')
            out_dir = self.path / out_stem.parent
            if out_dir.is_dir():
                self._rundir['ls'] = set(out_dir.iterdir())
            else:
                self._rundir['ls'] = set()
        return self._rundir['ls']

Response: Set of found binary files output by StagYY.


Instruction:
Write a Python 3 script for
returning view on configured steps slice.

Response:
def walk(self):
        """Return view on configured steps slice.

        Other Parameters:
            conf.core.snapshots: the slice of snapshots.
            conf.core.timesteps: the slice of timesteps.
        """
        if conf.core.snapshots is not None:
            return self.snaps[conf.core.snapshots]
        elif conf.core.timesteps is not None:
            return self.steps[conf.core.timesteps]
        return self.snaps[-1:]


Instruction:
Implement a Python 3 function for
scaling the data array to obtain dimensionful quantity.

Response:
def scale(self, data, unit):
        """Scales quantity to obtain dimensionful quantity.

        Args:
            data (numpy.array): the quantity that should be scaled.
            dim (str): the dimension of data as defined in phyvars.
        Return:
            (float, str): scaling factor and unit string.
        Other Parameters:
            conf.scaling.dimensional: if set to False (default), the factor is
                always 1.
        """
        if self.par['switches']['dimensional_units'] or \
           not conf.scaling.dimensional or \
           unit == '1':
            return data, ''
        scaling = phyvars.SCALES[unit](self.scales)
        factor = conf.scaling.factors.get(unit, ' ')
        if conf.scaling.time_in_y and unit == 's':
            scaling /= conf.scaling.yearins
            unit = 'yr'
        elif conf.scaling.vel_in_cmpy and unit == 'm/s':
            scaling *= 100 * conf.scaling.yearins
            unit = 'cm/y'
        if factor in phyvars.PREFIXES:
            scaling *= 10**(-3 * (phyvars.PREFIXES.index(factor) + 1))
            unit = factor + unit
        return data * scaling, unit


Instruction:
Can you generate a brief explanation for the following Python 3 code
def tseries_between(self, tstart=None, tend=None):
        if self.tseries is None:
            return None

        ndat = self.tseries.shape[0]

        if tstart is None:
            istart = 0
        else:
            igm = 0
            igp = ndat - 1
            while igp - igm > 1:
                istart = igm + (igp - igm) // 2
                if self.tseries.iloc[istart]['t'] >= tstart:
                    igp = istart
                else:
                    igm = istart
            istart = igp

        if tend is None:
            iend = None
        else:
            igm = 0
            igp = ndat - 1
            while igp - igm > 1:
                iend = igm + (igp - igm) // 2
                if self.tseries.iloc[iend]['t'] > tend:
                    igp = iend
                else:
                    igm = iend
            iend = igm + 1

        return self.tseries.iloc[istart:iend]

Response: Return a pandas. DataFrame containing the time series data between the requested times.


Instruction:
Explain what the following Python 3 code does
def filename(self, fname, timestep=None, suffix='', force_legacy=False):
        if timestep is not None:
            fname += '{:05d}'.format(timestep)
        fname += suffix
        if not force_legacy and self.hdf5:
            fpath = self.hdf5 / fname
        else:
            fpath = self.par['ioin']['output_file_stem'] + '_' + fname
            fpath = self.path / fpath
        return fpath

Response: Return the name of the StagYY output file.


Instruction:
Write a Python 3 function that can
return a set of existing binary files at a given snapshot number.

Response:
def binfiles_set(self, isnap):
        """Set of existing binary files at a given snap.

        Args:
            isnap (int): snapshot index.
        Returns:
            set of pathlib.Path: the set of output files available for this
            snapshot number.
        """
        possible_files = set(self.filename(fstem, isnap, force_legacy=True)
                             for fstem in phyvars.FIELD_FILES)
        return possible_files & self.files


Instruction:
Write a Python 3 function for
truncating or extend names so that its len is nnames.

Response:
def _tidy_names(names, nnames, extra_names=None):
    """Truncate or extend names so that its len is nnames.

    The list is modified, this function returns nothing.

    Args:
        names (list): list of names.
        nnames (int): desired number of names.
        extra_names (list of str): list of names to be used to extend the list
            if needed. If this list isn't provided, a range is used instead.
    """
    if len(names) < nnames and extra_names is not None:
        names.extend(extra_names)
    names.extend(range(nnames - len(names)))
    del names[nnames:]


Instruction:
Here you have a function in Python 3, explain what it does
def time_series(timefile, colnames):
    if not timefile.is_file():
        return None
    data = pd.read_csv(timefile, delim_whitespace=True, dtype=str,
                       header=None, skiprows=1, index_col=0,
                       engine='c', memory_map=True,
                       error_bad_lines=False, warn_bad_lines=False)
    data = data.apply(pd.to_numeric, raw=True, errors='coerce')

    # detect useless lines produced when run is restarted
    rows_to_del = []
    irow = len(data) - 1
    while irow > 0:
        iprev = irow - 1
        while iprev >= 0 and data.index[irow] <= data.index[iprev]:
            rows_to_del.append(iprev)
            iprev -= 1
        irow = iprev
    if rows_to_del:
        rows_to_keep = set(range(len(data))) - set(rows_to_del)
        data = data.take(list(rows_to_keep), convert=False)

    ncols = data.shape[1]
    _tidy_names(colnames, ncols)
    data.columns = colnames

    return data

Response: Read temporal series text file.


Instruction:
Can you generate the documentation for the following Python 3 function
def time_series_h5(timefile, colnames):
    if not timefile.is_file():
        return None
    with h5py.File(timefile, 'r') as h5f:
        dset = h5f['tseries']
        _, ncols = dset.shape
        ncols -= 1  # first is istep
        h5names = map(bytes.decode, h5f['names'][len(colnames) + 1:])
        _tidy_names(colnames, ncols, h5names)
        data = dset[()]
    return pd.DataFrame(data[:, 1:],
                        index=np.int_(data[:, 0]), columns=colnames)

Response: Read temporal series HDF5 file.


Instruction:
Explain what the following Python 3 code does
def _extract_rsnap_isteps(rproffile):
    step_regex = re.compile(r'^\*+step:\s*(\d+) ; time =\s*(\S+)')
    isteps = []  # list of (istep, time, nz)
    rows_to_del = set()
    line = ' '
    with rproffile.open() as stream:
        while line[0] != '*':
            line = stream.readline()
        match = step_regex.match(line)
        istep = int(match.group(1))
        time = float(match.group(2))
        nlines = 0
        iline = 0
        for line in stream:
            if line[0] == '*':
                isteps.append((istep, time, nlines))
                match = step_regex.match(line)
                istep = int(match.group(1))
                time = float(match.group(2))
                nlines = 0
                # remove useless lines produced when run is restarted
                nrows_to_del = 0
                while isteps and istep <= isteps[-1][0]:
                    nrows_to_del += isteps.pop()[-1]
                rows_to_del = rows_to_del.union(
                    range(iline - nrows_to_del, iline))
            else:
                nlines += 1
                iline += 1
        isteps.append((istep, time, nlines))
    return isteps, rows_to_del

Response: Extract istep and compute list of rows to delete


Instruction:
Implement a function in Python 3 to
extract radial profiles data from a. rprof file.

Response:
def rprof(rproffile, colnames):
    """Extract radial profiles data

    If :data:`colnames` is too long, it will be truncated. If it is too short,
    additional numeric column names from 0 to N-1 will be attributed to the N
    extra columns present in :data:`timefile`.

    Args:
        rproffile (:class:`pathlib.Path`): path of the rprof.dat file.
        colnames (list of names): names of the variables expected in
            :data:`rproffile` (may be modified).

    Returns:
        tuple of :class:`pandas.DataFrame`: (profs, times)
            :data:`profs` are the radial profiles, with the variables in
            columns and rows double-indexed with the time step and the radial
            index of numerical cells.

            :data:`times` is the dimensionless time indexed by time steps.
    """
    if not rproffile.is_file():
        return None, None
    data = pd.read_csv(rproffile, delim_whitespace=True, dtype=str,
                       header=None, comment='*', skiprows=1,
                       engine='c', memory_map=True,
                       error_bad_lines=False, warn_bad_lines=False)
    data = data.apply(pd.to_numeric, raw=True, errors='coerce')

    isteps, rows_to_del = _extract_rsnap_isteps(rproffile)
    if rows_to_del:
        rows_to_keep = set(range(len(data))) - rows_to_del
        data = data.take(list(rows_to_keep), convert=False)

    id_arr = [[], []]
    for istep, _, n_z in isteps:
        id_arr[0].extend(repeat(istep, n_z))
        id_arr[1].extend(range(n_z))

    data.index = id_arr

    ncols = data.shape[1]
    _tidy_names(colnames, ncols)
    data.columns = colnames

    df_times = pd.DataFrame(list(map(itemgetter(1), isteps)),
                            index=map(itemgetter(0), isteps))
    return data, df_times


Instruction:
Make a summary of the following Python 3 code
def rprof_h5(rproffile, colnames):
    if not rproffile.is_file():
        return None, None
    isteps = []
    with h5py.File(rproffile) as h5f:
        dnames = sorted(dname for dname in h5f.keys()
                        if dname.startswith('rprof_'))
        ncols = h5f['names'].shape[0]
        h5names = map(bytes.decode, h5f['names'][len(colnames):])
        _tidy_names(colnames, ncols, h5names)
        data = np.zeros((0, ncols))
        for dname in dnames:
            dset = h5f[dname]
            data = np.concatenate((data, dset[()]))
            isteps.append((dset.attrs['istep'], dset.attrs['time'],
                           dset.shape[0]))

    id_arr = [[], []]
    for istep, _, n_z in isteps:
        id_arr[0].extend(repeat(istep, n_z))
        id_arr[1].extend(range(n_z))

    df_data = pd.DataFrame(data, index=id_arr, columns=colnames)
    df_times = pd.DataFrame(list(map(itemgetter(1), isteps)),
                            index=map(itemgetter(0), isteps))
    return df_data, df_times

Response: Extract radial profiles data from a hdf5 file.