def getUsersWithCompetencies(categories, usercompetencies):
    """
    Lists competences and their corresponding user IDs and returns the user ID
    matching the needed competence

    :param categories: Needed competence category
    :type categories: list
    :param usercompetencies: User IDs and their competences
    :type usercompetencies: dict
    """
    competencies = {}
    for user in usercompetencies:
        for competence in usercompetencies[user]:
            if competence not in competencies:
                competencies[competence] = []
                competencies[competence].append(user)
            else:
                competencies[competence].append(user)
    for competence in categories:
        if competence in competencies:
            return {'competence': competence, 'users': competencies[competence]
                }
    return None


def _write_experiment_archive(exp_id, data):
    """ Write experiment archive contained in 'data' to 'exp_id.tar.gz' """
    with open('%s.tar.gz' % exp_id, 'wb') as archive:
        archive.write(data)


def add():
    """Add a new workspace by duplicating the current one or appending one from the user configuration

    """
    pass


def zerocopy_from_numpy(np_array):
    """Create a tensor that shares the numpy array.

    Parameters
    ----------
    np_array : numpy.ndarray
        The numpy ndarray.

    Returns
    -------
    Tensor
        A framework-specific tensor.
    """
    pass


def grand_parent(node):
    """
        | Get grand-parent-node

        :param  lxml.etree._Element node:
            lxml-etree-element
        :return lxml.etree._Element:
            grand-parent-node
    """
    return node.getparent().getparent()


def load_asyncio(finder, module):
    """the asyncio must be loaded as a package."""
    finder.IncludePackage('asyncio')


def parse_arguments(argv, verbose=0):
    """
    Old command-line parser (this is currently unused and
    it's not clear if it will be useful in the future).

    This function is in ``utils.py``.
    """
    list = []
    unproc_list = []
    if verbose > 1:
        print('Number of arguments:', len(argv), 'arguments.')
        print('Argument List:', str(argv))
    ix = 1
    while ix < len(argv):
        if verbose > 1:
            print('Processing index', ix, 'with value', argv[ix], '.')
        initial_ix_done = 0
        while initial_ix_done == 0:
            if ix == len(argv):
                initial_ix_done = 1
            elif argv[ix][0] == '-':
                initial_ix_done = 1
            else:
                if verbose > 1:
                    print('Adding', argv[ix], ' to unprocessed list.')
                unproc_list.append(argv[ix])
                ix = ix + 1
        if ix < len(argv):
            list_one = []
            cmd_name = argv[ix][1:]
            if cmd_name[0] == '-':
                cmd_name = cmd_name[1:]
            list_one.append(cmd_name)
            if verbose > 1:
                print('Found option', cmd_name, 'at index', ix)
            ix_next = ix + 1
            ix_next_done = 0
            while ix_next_done == 0:
                if ix_next == len(argv):
                    ix_next_done = 1
                elif argv[ix_next][0] == '-':
                    ix_next_done = 1
                else:
                    if verbose > 1:
                        print('Adding ' + argv[ix_next] + ' with index ' +
                            str(ix_next) + ' to list for ' + cmd_name)
                    list_one.append(argv[ix_next])
                    ix_next = ix_next + 1
            list.append(list_one)
            ix = ix_next
    return list, unproc_list


def current_ideal(P, V, phase=3, PF=1):
    """Returns the current drawn by a motor of power `P` operating at voltage
    `V`, with line AC of phase `phase` and power factor `PF` according to [1]_.

    Single-phase power:

    .. math::
        I = \\frac{P}{V \\cdot \\text{PF}}

    3-phase power:

    .. math::
        I = \\frac{P}{V \\cdot \\text{PF} \\sqrt{3}}

    Parameters
    ----------
    P : float
        Power, [W]
    V : float
        Voltage, [V]
    phase : int, optional
        Line AC phase, either 1 or 3
    PF : float, optional
        Power factor of motor

    Returns
    -------
    I : float
        Power drawn by motor, [A]

    Notes
    -----
    Does not include power used by the motor's fan, or startor, or internal
    losses. These are all significant.

    Examples
    --------
    >>> current_ideal(V=120, P=1E4, PF=1, phase=1)
    83.33333333333333

    References
    ----------
    .. [1] Electrical Construction, and Maintenance. "Calculating Single- and
       3-Phase Parameters." April 1, 2008.
       http://ecmweb.com/basics/calculating-single-and-3-phase-parameters.
    """
    if phase not in [1, 3]:
        raise Exception('Only 1 and 3 phase power supported')
    if phase == 3:
        return P / (V * 3 ** 0.5 * PF)
    else:
        return P / (V * PF)


def get_github_link(owner, repo):
    """
	This will be used to get gitub link
	"""
    return 'https://github.com/{owner}/{repo}'.format(owner=owner, repo=repo)


def get_related_schema(schema, field):
    """Retrieve the related schema of a relationship field

    :param Schema schema: the schema to retrieve le relationship field from
    :param field: the relationship field
    :return Schema: the related schema
    """
    return schema._declared_fields[field].__dict__['_Relationship__schema']


def addrevision(revisiondata, transaction, linkrev, p1, p2, node=None,
    flags=0, cachedelta=None):
    """Add a new revision to the store.

        This is similar to ``add()`` except it operates at a lower level.

        The data passed in already contains a metadata header, if any.

        ``node`` and ``flags`` can be used to define the expected node and
        the flags to use with storage. ``flags`` is a bitwise value composed
        of the various ``REVISION_FLAG_*`` constants.

        ``add()`` is usually called when adding files from e.g. the working
        directory. ``addrevision()`` is often called by ``add()`` and for
        scenarios where revision data has already been computed, such as when
        applying raw data from a peer repo.
        """


@classmethod
def _cmpUtil(cls, a, b):
    """ Utility function that compares strings
        in the following manner:
        - if both string represent numbers, perform an integer comparison
        - otherwise consider both as strings..."""
    if a.isdigit() and b.isdigit():
        return int(a) - int(b)
    if a < b:
        return -1
    elif a == b:
        return 0
    else:
        return 1


def normalise_band_name(band_name: str) ->str:
    """
    Normalise band names by our norms.

    Numeric bands have a 'band' prefix, others are lowercase with

    >>> normalise_band_name('4')
    'band04'
    >>> normalise_band_name('QUALITY')
    'quality'
    >>> normalise_band_name('Azimuthal-Angles')
    'azimuthal_angles'
    """
    try:
        number = int(band_name)
        band_name = f'band{number:02}'
    except ValueError:
        pass
    return band_name.lower().replace('-', '_')


def confluence_link_to_anchor(anchor: str, caption: str) ->str:
    """
    Temporary function that returns hardcoded link to confluence anchor.
    When confluence backend support will be fully added, this will be replaced.
    """
    template = """<raw_confluence><ac:link ac:anchor="{anchor}">
    <ac:plain-text-link-body><![CDATA[{caption}]]></ac:plain-text-link-body>
  </ac:link>
</raw_confluence>"""
    return template.format(anchor=anchor, caption=caption)


def styledict(s):
    """
    *Sehr einfacher* Parser für HTML-Style-Attribute;
    versucht *nicht*, alle erlaubten Deklarationen korrekt zu parsen,
    insbesondere nicht solche, die evtl. ein Semikolon enthalten.

    >>> styledict('width:180px;')
    {'width': '180px'}

    Spätere Angaben überschreiben frühere:
    >>> styledict('width:180px;width : 100px')
    {'width': '100px'}

    Es findet keinerlei Konversion in Zahlen o.ä. statt; dimensionslose
    Angaben sind ohnehin nicht erlaubt.
    """
    res = {}
    for chunk in s.split(';'):
        if not chunk.strip():
            continue
        try:
            key, val = tuple([s.strip() for s in chunk.split(':', 1)])
        except IndexError:
            try:
                key, val = tuple([s.strip() for s in chunk.split('=', 1)])
            except IndexError:
                continue
        res[key] = val
    return res


def forwards(apps, schema_editor):
    """
    Set the venue_name field of all Events that have a Venue.
    """
    Event = apps.get_model('spectator_events', 'Event')
    for event in Event.objects.all():
        if event.venue is not None:
            event.venue_name = event.venue.name
            event.save()


def double_center(mat):
    """Double center a 2d array.

    Args:
        mat (ndarray): 2d numpy array

    Returns:
        mat (ndarray): double-centered version of input

    """
    if len(mat.shape) != 2:
        raise ValueError('Array should be 2d')
    row_mean = mat.mean(axis=0, keepdims=True)
    col_mean = mat.mean(axis=1, keepdims=True)
    grand_mean = mat.mean()
    return mat - row_mean - col_mean + grand_mean


def features_of(geojson):
    """ Find all Features in a valid GeoJSON object. """
    features = []
    if geojson['type'] == 'Feature':
        features.append(geojson)
    elif geojson['type'] == 'FeatureCollection':
        features += geojson['features']
    return features


def assert_string_data(value: str) ->None:
    """Asserts value is string type."""
    assert isinstance(value, str
        ), f'Input value type must be string. Actual type: {type(value)}, value: {value}'


def process_special_annotation(v, lin):
    """
    If the user wants a fancy annotation, like 'add middle column',
    this gets processed here. it's potentially the place where the
    user could add entropy score, or something like that.
    """
    if v.lower() not in ['i', 'index', 'm', 'scheme', 't', 'q']:
        return v
    if v == 'index':
        return lin.name
    elif v in ['m', 't']:
        return str(lin[v])
    else:
        return v


def define(hub):
    """
    Return the definition used by the runtime to insert the conditions of the
    given requisite
    """
    return {'prereq': 'changes', 'resolver': 'any'}


def add_signaling_arguments(parser):
    """
    Add signaling method arguments to an argparse.ArgumentParser.
    """
    parser.add_argument('--signaling', '-s', choices=['copy-and-paste',
        'tcp-socket', 'unix-socket', 'websocket'])
    parser.add_argument('--signaling-host', default='127.0.0.1', help=
        'Signaling host (tcp-socket and websocket only)')
    parser.add_argument('--signaling-port', default=1234, help=
        'Signaling port (tcp-socket only)')
    parser.add_argument('--signaling-path', default='aiortcdc.socket', help
        ='Signaling socket path (unix-socket only)')


def shape_key_mirror(use_topology: bool=False):
    """Mirror the current shape key along the local X axis

    :param use_topology: Topology Mirror, Use topology based mirroring (for when both sides of mesh have matching, unique topology)
    :type use_topology: bool
    """
    pass


def _check_cell_tags(ntbk):
    """Perform some checks on cell tags to make sure they're correct."""
    for cell in ntbk.cells:
        cell['metadata'].get('tags', [])


def drivers_add_selected():
    """Add drivers to selected items

    """
    pass


@classmethod
def SetProfileName(cls, pname):
    """Set the name of the current profile
        @param cls: Class Object
        @param pname: name to set profile to

        """
    cls.cprofile = pname


def shape(x):
    """Returns the shape of a tensor.

    Warning: type returned will be different for
    Theano backend (Theano tensor type) and TF backend (TF TensorShape).
    """
    return x.shape


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def read_file(file_path):
    """Read initial program"""
    with open(file_path, 'r') as program:
        program = open(file_path, 'r')
        program = str(program.read())
        return program.split('\n')


def chunkReader(file_reference, chunk_size=1024):
    """
    A generator that reads a file chunk by chunk
    :param file_reference: Reference to the file object
    :param chunk_size: The size of chunk that needs to be read
    :return: The chunk of the file read
    """
    while True:
        chunk = file_reference.read(chunk_size)
        if not chunk:
            return
        yield chunk


def momentcondquant(distfn, params, mom2, quantile=None, shape=None):
    """moment conditions for estimating distribution parameters by matching
    quantiles, defines as many moment conditions as quantiles.

    Returns
    -------
    difference : array
        difference between theoretical and empirical quantiles

    Notes
    -----
    This can be used for method of moments or for generalized method of
    moments.

    """
    if len(params) == 2:
        loc, scale = params
    elif len(params) == 3:
        shape, loc, scale = params
    else:
        pass
    pq, xq = quantile
    cdfdiff = distfn.cdf(xq, *params) - pq
    return cdfdiff


def envmap_clear_all():
    """Discard all environment maps in the .blend file and free them from memory

    """
    pass


@staticmethod
def from_reference(flow: 'Flow'):
    """Creates a fake exact copy of a Flow by usurpating its hash

        Parameters
        ==========
        flow: Flow
            Reference to the flow you want to create an exact copy of
        """
    new_flow = flow.copy()
    new_flow.inject_reference(flow)
    return new_flow


def get_all_narrative_points(switches, enduse):
    """Get all narrative points of an enduse

    Arguments
    ---------
    switches : list
        All switches
    enduse : str
        Enduse

    Returns
    -------
    switch_yrs : list
        All sorted defined timesteps from narrative
    """
    switch_yrs = set([])
    for switch in switches:
        if switch.enduse == enduse:
            switch_yrs.add(switch.switch_yr)
    list(switch_yrs).sort()
    return switch_yrs


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


@classmethod
def parse(cls, obj, **kwargs):
    """Attempt to parse `obj` as a type description defined in the
        Mongotron mini-language. If `obj` is unrecognizable, return ``None``,
        otherwise return a :py:class:`Field` instance describing it.

            `obj`:
                The mini-language object to attempt to parse.

            `kwargs`:
                Extra keyword arguments passed to Field's constructor on
                success.
        """
    if obj is None:
        return cls(**kwargs)


@staticmethod
def find_issue_type_by_name(project, name):
    """
            Return a Redmine tracker matching name ('Bug').

            .. note::

                If there is no match then return the first one!
        """
    for trk in project.trackers:
        if str(trk).lower() == name.lower():
            return trk
    return project.trackers[0]


def affine_bkg(x, lin_bkg=0, const_bkg=0):
    """
    An affine/linear background.
    :param x:
    :param lin_bkg:
    :param const_bkg:
    :return:
    """
    return lin_bkg * x + const_bkg


def generate_attributes(tokens, attribute_lemmas=attribute_lemmas):
    """
    Given a list of spaCy tokens and a dict of lemma attributes, return an
    AnnoSpan metadata dict with the appropriate attributes object.

    The attribute_lemmas dict should contain keys in the following form:
    {
        "pos_": {
            "attribute_tag": ["lemmas", "to", "match"]
        }
    }

    Multiple attribute tags may be supplied for a given part of speech.
    Possessive nouns are excluded, because they cause problems with
    assumptions elsewhere. This isn't the most elegant solution. A more
    elegant solution might, say, provide a set of conditions (e.g. noun, not
    possessive) and a set of indicator lemmas.
    """
    metadata = {}
    attributes = []
    if not hasattr(tokens, '__iter__'):
        tokens = [tokens]
    for t in tokens:
        if t.pos_ == 'NOUN' and t.dep_ == 'poss':
            continue
        for category, lemmas in attribute_lemmas.get(t.pos_, {}).items():
            if t.lemma_ in lemmas:
                attributes.append(category)
    metadata['attributes'] = attributes
    return metadata


def render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def createMainWidget(argv):
    """
    Function to create the main widget.

    @param argv list of commandline parameters (list of strings)
    @return reference to the main widget (QWidget)
    """
    from Preferences.ConfigurationDialog import ConfigurationWindow
    w = ConfigurationWindow()
    w.show()
    w.showConfigurationPageByName('empty')
    return w


def scroll_right(deltax: int=0, deltay: int=0):
    """Scroll the view right

    :param deltax: Delta X
    :type deltax: int
    :param deltay: Delta Y
    :type deltay: int
    """
    pass


def describe_fleet_attributes(FleetIds=None, Limit=None, NextToken=None):
    """
    Retrieves fleet properties, including metadata, status, and configuration, for one or more fleets. You can request attributes for all fleets, or specify a list of one or more fleet IDs. When requesting multiple fleets, use the pagination parameters to retrieve results as a set of sequential pages. If successful, a  FleetAttributes object is returned for each requested fleet ID. When specifying a list of fleet IDs, attribute objects are returned only for fleets that currently exist.
    See also: AWS API Documentation

    :example: response = client.describe_fleet_attributes(
        FleetIds=[
            'string',
        ],
        Limit=123,
        NextToken='string'
    )

    :type FleetIds: list
    :param FleetIds: Unique identifier for a fleet(s) to retrieve attributes for. To request attributes for all fleets, leave this parameter empty.
            (string) --

    :type Limit: integer
    :param Limit: Maximum number of results to return. Use this parameter with NextToken to get results as a set of sequential pages. This parameter is ignored when the request specifies one or a list of fleet IDs.

    :type NextToken: string
    :param NextToken: Token that indicates the start of the next sequential page of results. Use the token that is returned with a previous call to this action. To specify the start of the result set, do not specify a value. This parameter is ignored when the request specifies one or a list of fleet IDs.

    :rtype: dict
    :return: {
        'FleetAttributes': [
            {
                'FleetId': 'string',
                'FleetArn': 'string',
                'Description': 'string',
                'Name': 'string',
                'CreationTime': datetime(2015, 1, 1),
                'TerminationTime': datetime(2015, 1, 1),
                'Status': 'NEW'|'DOWNLOADING'|'VALIDATING'|'BUILDING'|'ACTIVATING'|'ACTIVE'|'DELETING'|'ERROR'|'TERMINATED',
                'BuildId': 'string',
                'ServerLaunchPath': 'string',
                'ServerLaunchParameters': 'string',
                'LogPaths': [
                    'string',
                ],
                'NewGameSessionProtectionPolicy': 'NoProtection'|'FullProtection',
                'OperatingSystem': 'WINDOWS_2012'|'AMAZON_LINUX',
                'ResourceCreationLimitPolicy': {
                    'NewGameSessionsPerCreator': 123,
                    'PolicyPeriodInMinutes': 123
                },
                'MetricGroups': [
                    'string',
                ]
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    NEW  A new fleet has been defined and desired instances is set to 1.
    DOWNLOADING/VALIDATING/BUILDING/ACTIVATING  Amazon GameLift is setting up the new fleet, creating new instances with the game build and starting server processes.
    ACTIVE  Hosts can now accept game sessions.
    ERROR  An error occurred when downloading, validating, building, or activating the fleet.
    DELETING  Hosts are responding to a delete fleet request.
    TERMINATED  The fleet no longer exists.

    """
    pass


def add_directories(parser, nargs_in='+'):
    """
    Add a positional argument that is one or more directories.

    Parameters
    ----------

    parser : `ArgumentParser`

    """
    parser.add_argument('dir', metavar='dir', nargs=nargs_in, help=
        'Directory to process')


def read_bytes(buf, size):
    """
    Reads bytes from a buffer.

    Returns a tuple with buffer less the read bytes, and the bytes.
    """
    b = buf[0:size]
    return buf[size:], b


def zip_pairs(xs, ys, key=lambda x: x):
    """Generate pairs that match a cmp function"""
    xs = list(reversed(sorted(xs, key=key)))
    ys = list(reversed(sorted(ys, key=key)))
    while xs or ys:
        if xs and not ys:
            yield xs.pop(), None
        elif ys and not xs:
            yield None, ys.pop()
        elif key(xs[-1]) == key(ys[-1]):
            yield xs.pop(), ys.pop()
        elif key(xs[-1]) < key(ys[-1]):
            yield xs.pop(), None
        else:
            yield None, ys.pop()


def p_track_flag_four_channels(t):
    """track_flag : FOUR_CHANNEL_AUDIO"""
    from audiotools.toc import TOCFlag_CHANNELS
    t[0] = TOCFlag_CHANNELS(4)


def p_quantifier_never_or_more(p):
    """quantifier : K_NEVER K_OR K_MORE"""
    p[0] = [('never_or_more', ())]


def parse_bed_to_bin(filename, bin_size, bin_dict, input_dir):
    """ parse the bed files into bin """
    infile = open(input_dir + filename, 'r')
    num = 0
    for line in infile:
        num += 1
        if num % 10000000 == 0:
            print('{0:,} lines processed in {1}'.format(num, filename))
        chr, start, end, col3, col4, strand = line.strip().split()
        pos = int(start)
        try:
            bin_dict[chr][int(pos / bin_size)] += 1
        except (IndexError, KeyError) as e:
            pass
    return bin_dict


def evaluator_options_from_eval_config(eval_config):
    """Produces a dictionary of evaluation options for each eval metric.

  Args:
    eval_config: An `eval_pb2.EvalConfig`.

  Returns:
    evaluator_options: A dictionary of metric names (see
      EVAL_METRICS_CLASS_DICT) to `DetectionEvaluator` initialization
      keyword arguments. For example:
      evalator_options = {
        'coco_detection_metrics': {'include_metrics_per_category': True}
      }
  """
    eval_metric_fn_keys = eval_config.metrics_set
    evaluator_options = {}
    for eval_metric_fn_key in eval_metric_fn_keys:
        if eval_metric_fn_key in ('coco_detection_metrics', 'coco_mask_metrics'
            ):
            evaluator_options[eval_metric_fn_key] = {
                'include_metrics_per_category': eval_config.
                include_metrics_per_category}
        elif eval_metric_fn_key == 'precision_at_recall_detection_metrics':
            evaluator_options[eval_metric_fn_key] = {'recall_lower_bound':
                eval_config.recall_lower_bound, 'recall_upper_bound':
                eval_config.recall_upper_bound}
    return evaluator_options


def get_percentile_like(xs, min_amount):
    """
    Get the minimum value so that the sum of bigger values makes min_amount.

    Parameters
    ----------
    xs : list of float
    min_amount : float

    Returns
    -------
    float
    """
    xs = sorted(xs, reverse=True)
    sum_ = 0
    i = 0
    while sum_ < min_amount:
        sum_ += xs[i]
        i += 1
    return xs[i - 1]


def extract_capsule_satellite_installer_command(text):
    """Extract satellite installer command from capsule-certs-generate command
    output
    """
    cmd_start_with = 'satellite-installer'
    cmd_lines = []
    if text:
        if isinstance(text, (list, tuple)):
            lines = text
        else:
            lines = text.split('\n')
        cmd_start_found = False
        cmd_end_found = False
        for line in lines:
            if line.lstrip().startswith(cmd_start_with):
                cmd_start_found = True
            if cmd_start_found and not cmd_end_found:
                cmd_lines.append(line.strip('\\'))
                if not line.endswith('\\'):
                    cmd_end_found = True
    if cmd_lines:
        cmd = ' '.join(cmd_lines)
        while '  ' in cmd:
            cmd = cmd.replace('  ', ' ')
        return cmd
    return None


@staticmethod
def __formatOptionalFilters(name, isAvailable):
    """Utils to format availability of features"""
    if isAvailable:
        template = '%s is available'
    else:
        template = '%s is not available'
    return template % name


def get_request_url_for_custom_drf_requests(request_url, full_path):
    """
    Function to dealing with custom (non standard DRF requests such as read, list, partial_update etc) requests.

    >>> request_url = '/root/'
    >>> full_path = 'root_my_function'
    >>>
    >>> get_request_url_for_custom_drf_requests(request_url, full_path)
    '/root/my_function/'

    :param str request_url: The current request url
    :param str full_path: The full path of the url
    :return:
    """
    root_url = full_path.split('_')[0]
    request_url += full_path.replace(root_url, '', 1)[1:] + '/'
    return request_url


@classmethod
def set_password(cls, val):
    """
        Create an instance of this class set to the ``set_password`` tag with
        value ``val``.

        :param str val:
        :rtype: LinkPassword
        """
    return cls('set_password', val)


def transformed_potential_energy(potential_energy, inv_transform, z):
    """
    Given a potential energy `p(x)`, compute potential energy of `p(z)`
    with `z = transform(x)` (i.e. `x = inv_transform(z)`).

    :param potential_energy: a callable to compute potential energy of original
        variable `x`.
    :param ~numpyro.distributions.constraints.Transform inv_transform: a
        transform from the new variable `z` to `x`.
    :param z: new variable to compute potential energy
    :return: potential energy of `z`.
    """
    x, intermediates = inv_transform.call_with_intermediates(z)
    logdet = inv_transform.log_abs_det_jacobian(z, x, intermediates=
        intermediates)
    return potential_energy(x) - logdet


def is_publicly_trusted(domain):
    """
    A domain has a "Publicly Trusted" certificate if its canonical
    endpoint has a publicly trusted certificate.
    """
    canonical, https, httpswww = (domain.canonical, domain.https, domain.
        httpswww)
    if canonical.host == 'root':
        evaluate = https
    else:
        evaluate = httpswww
    return evaluate.live and evaluate.https_public_trusted


@staticmethod
def _check_issuer(issuer):
    """
        check that issuer doesn't contain chars forbidden by KeyURI spec
        """
    if issuer and ':' in issuer:
        raise ValueError("issuer may not contain ':'")


def calc_dynamic_range_threshold(imax, dynamic_range_dr):
    """
    Calculates the dynamic range threshold
    imax (float): the maximum in the input image
    dynamic_range_dr (float): the dynamic range you want to calculate the threshold for
    returns (float): the dynamic range threshold
    """
    dynamic_range_threshold = imax / dynamic_range_dr
    return dynamic_range_threshold


def list_traffic_policy_instances_by_policy(TrafficPolicyId=None,
    TrafficPolicyVersion=None, HostedZoneIdMarker=None,
    TrafficPolicyInstanceNameMarker=None, TrafficPolicyInstanceTypeMarker=
    None, MaxItems=None):
    """
    Gets information about the traffic policy instances that you created by using a specify traffic policy version.
    Amazon Route 53 returns a maximum of 100 items in each response. If you have a lot of traffic policy instances, you can use the MaxItems parameter to list them in groups of up to 100.
    See also: AWS API Documentation

    :example: response = client.list_traffic_policy_instances_by_policy(
        TrafficPolicyId='string',
        TrafficPolicyVersion=123,
        HostedZoneIdMarker='string',
        TrafficPolicyInstanceNameMarker='string',
        TrafficPolicyInstanceTypeMarker='SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA',
        MaxItems='string'
    )

    :type TrafficPolicyId: string
    :param TrafficPolicyId: [REQUIRED]
            The ID of the traffic policy for which you want to list traffic policy instances.

    :type TrafficPolicyVersion: integer
    :param TrafficPolicyVersion: [REQUIRED]
            The version of the traffic policy for which you want to list traffic policy instances. The version must be associated with the traffic policy that is specified by TrafficPolicyId .

    :type HostedZoneIdMarker: string
    :param HostedZoneIdMarker: If the value of IsTruncated in the previous response was true , you have more traffic policy instances. To get more traffic policy instances, submit another ListTrafficPolicyInstancesByPolicy request.
            For the value of hostedzoneid , specify the value of HostedZoneIdMarker from the previous response, which is the hosted zone ID of the first traffic policy instance that Amazon Route 53 will return if you submit another request.
            If the value of IsTruncated in the previous response was false , there are no more traffic policy instances to get.

    :type TrafficPolicyInstanceNameMarker: string
    :param TrafficPolicyInstanceNameMarker: If the value of IsTruncated in the previous response was true , you have more traffic policy instances. To get more traffic policy instances, submit another ListTrafficPolicyInstancesByPolicy request.
            For the value of trafficpolicyinstancename , specify the value of TrafficPolicyInstanceNameMarker from the previous response, which is the name of the first traffic policy instance that Amazon Route 53 will return if you submit another request.
            If the value of IsTruncated in the previous response was false , there are no more traffic policy instances to get.

    :type TrafficPolicyInstanceTypeMarker: string
    :param TrafficPolicyInstanceTypeMarker: If the value of IsTruncated in the previous response was true , you have more traffic policy instances. To get more traffic policy instances, submit another ListTrafficPolicyInstancesByPolicy request.
            For the value of trafficpolicyinstancetype , specify the value of TrafficPolicyInstanceTypeMarker from the previous response, which is the name of the first traffic policy instance that Amazon Route 53 will return if you submit another request.
            If the value of IsTruncated in the previous response was false , there are no more traffic policy instances to get.

    :type MaxItems: string
    :param MaxItems: The maximum number of traffic policy instances to be included in the response body for this request. If you have more than MaxItems traffic policy instances, the value of the IsTruncated element in the response is true , and the values of HostedZoneIdMarker , TrafficPolicyInstanceNameMarker , and TrafficPolicyInstanceTypeMarker represent the first traffic policy instance that Amazon Route 53 will return if you submit another request.

    :rtype: dict
    :return: {
        'TrafficPolicyInstances': [
            {
                'Id': 'string',
                'HostedZoneId': 'string',
                'Name': 'string',
                'TTL': 123,
                'State': 'string',
                'Message': 'string',
                'TrafficPolicyId': 'string',
                'TrafficPolicyVersion': 123,
                'TrafficPolicyType': 'SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA'
            },
        ],
        'HostedZoneIdMarker': 'string',
        'TrafficPolicyInstanceNameMarker': 'string',
        'TrafficPolicyInstanceTypeMarker': 'SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA',
        'IsTruncated': True|False,
        'MaxItems': 'string'
    }

    """
    pass


def same_value(v):
    """return the value unchanged"""
    return v


def copy():
    """Copy selected text to clipboard

    """
    pass


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def removeNullTerminator(bytestring):
    """Remove null terminator from bytestring"""
    bytesOut = bytestring.rstrip(b'\x00')
    return bytesOut


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


def set_viewport_background():
    """Set current movie clip as a camera background in 3D view-port (works only when a 3D view-port is visible)

    """
    pass


def run():
    """
        Fire 'startup' System Events, move the reactor to the 'running'
        state, then run the main loop until it is stopped with C{stop()} or
        C{crash()}.
        """


def parse_kwargs(kwargs, *keys, **keyvalues):
    """Return dict with keys from keys|keyvals and values from kwargs|keyvals.

    Existing keys are deleted from kwargs.

    >>> kwargs = {'one': 1, 'two': 2, 'four': 4}
    >>> kwargs2 = parse_kwargs(kwargs, 'two', 'three', four=None, five=5)
    >>> kwargs == {'one': 1}
    True
    >>> kwargs2 == {'two': 2, 'four': 4, 'five': 5}
    True

    """
    result = {}
    for key in keys:
        if key in kwargs:
            result[key] = kwargs[key]
            del kwargs[key]
    for key, value in keyvalues.items():
        if key in kwargs:
            result[key] = kwargs[key]
            del kwargs[key]
        else:
            result[key] = value
    return result


def Latentc(tempc):
    """Latent heat of condensation (vapourisation)

    INPUTS:
    tempc (C)

    OUTPUTS:
    L_w (J/kg)

    SOURCE:
    http://en.wikipedia.org/wiki/Latent_heat#Latent_heat_for_condensation_of_water
    """
    return 1000 * (2500.8 - 2.36 * tempc + 0.0016 * tempc ** 2 - 6e-05 *
        tempc ** 3)


def to_bytes(url):
    """to_bytes(u"URL") --> 'URL'."""
    if isinstance(url, str):
        try:
            url = url.encode('ASCII').decode()
        except UnicodeError:
            raise UnicodeError('URL ' + repr(url) +
                ' contains non-ASCII characters')
    return url


@classmethod
def user_exists(cls, *args, **kwargs):
    """
        Return True/False if a User instance exists with the given arguments.
        Arguments are directly passed to filter() manager method.
        """
    raise NotImplementedError('Implement in subclass')


def load_Xlib_display(finder, module):
    """the Xlib.display module implicitly loads a number of extension modules;
       make sure this happens."""
    finder.IncludeModule('Xlib.ext.xtest')
    finder.IncludeModule('Xlib.ext.shape')
    finder.IncludeModule('Xlib.ext.xinerama')
    finder.IncludeModule('Xlib.ext.record')
    finder.IncludeModule('Xlib.ext.composite')
    finder.IncludeModule('Xlib.ext.randr')


def metric_set_min(key, value):
    """Sets metric value if it is less that the current one.

    :param str|unicode key:

    :param int|long value:

    :rtype: bool
    """
    return False


def _unsquish_command_name(identifier):
    """Gets a command name given its identifier.

    :param identifier: Command identifier.
    :rtype: str
    """
    return identifier[4:].replace('_', '-')


def _raiseExceptionIfHookFailed(file_, exitStatus):
    """
    Will raise an exception with the hook file and the exit status in the
    error message if the exit status is not zero.
    """
    if exitStatus is not 0:
        raise Exception('Hook {0} failed with status {1}'.format(file_, int
            (exitStatus / 256)))


@classmethod
def _generate_text(cls, documented_cls, method_name):
    """ text that will be appended to the result """
    raise NotImplementedError


@classmethod
def search(cls, **kwargs):
    """
        Search for customers matching supplied query

        Args:
           q: Text to search for customers ("q" is short for query)
           f: Filters to apply to customers ("f" is short for query)
           page: Page to show (default: 1)
           limit: Maximum number of results to show (default: 50, maximum: 250)
        Returns:
           An array of customers.
        """
    return cls._build_list(cls.get('search', **kwargs))


def point(lat, lon):
    """
    Creates an API-ready point from the given latitude and longitue.
    """
    return {'$point': [lat, lon]}


def generate_jekyll_config(path, site_title):
    """Builds a jekyll site configuration file."""
    cf = open(path + '/_config.yml', 'w')
    cf.write('name: ' + site_title + '\n')
    cf.write('paginate: 7\n')
    cf.close()


def _air_pressure(elev, method='asce'):
    """Mean atmospheric pressure at station elevation (Eqs. 3 & 34)

    Parameters
    ----------
    elev : ee.Image or ee.Number
        Elevation [m].
    method : {'asce' (default), 'refet'}, optional
        Calculation method:
        * 'asce' -- Calculations will follow ASCE-EWRI 2005 [1] equations.
        * 'refet' -- Calculations will follow RefET software.

    Returns
    -------
    pair : ee.Image or ee.Number
        Air pressure [kPa].

    Notes
    -----
    The current calculation in Ref-ET:
        101.3 * (((293 - 0.0065 * elev) / 293) ** (9.8 / (0.0065 * 286.9)))
    Equation 3 in ASCE-EWRI 2005:
        101.3 * (((293 - 0.0065 * elev) / 293) ** 5.26)
    Per Dr. Allen, the calculation with full precision:
        101.3 * (((293.15 - 0.0065 * elev) / 293.15) ** (9.80665 / (0.0065 * 286.9)))

    """
    if method == 'asce':
        return elev.multiply(-0.0065).add(293).divide(293).pow(5.26).multiply(
            101.3)
    elif method == 'refet':
        return elev.multiply(-0.0065).add(293).divide(293).pow(9.8 / (
            0.0065 * 286.9)).multiply(101.3)


def config_read_prefixed_options(conf, prefix_name, defaults):
    """
    Read prefixed options from configuration

    :param conf: the configuration
    :param prefix_name: the prefix (including, if needed, an underscore)
    :param defaults: a dict of default values. The dict supplies the
                     option name and type (string or comma separated string)
    :return: a dict containing the options
    """
    params = {}
    for option_name in defaults.keys():
        value = conf.get('%s%s' % (prefix_name, option_name))
        if value:
            if isinstance(defaults.get(option_name), list):
                params[option_name] = []
                for role in value.lower().split(','):
                    params[option_name].append(role.strip())
            else:
                params[option_name] = value.strip()
    return params


def scan_offsets(handle):
    """
    Scan a PGN file opened in text mode for game offsets.

    Yields the starting offsets of all the games, so that they can be seeked
    later. This is just like :func:`~chess.pgn.scan_headers()` but more
    efficient if you do not actually need the header information.

    The PGN standard requires each game to start with an *Event*-tag. So does
    this scanner.
    """
    in_comment = False
    last_pos = handle.tell()
    line = handle.readline()
    while line:
        if not in_comment and line.startswith('[Event "'):
            yield last_pos
        elif not in_comment and '{' in line or in_comment and '}' in line:
            in_comment = line.rfind('{') > line.rfind('}')
        last_pos = handle.tell()
        line = handle.readline()


def extract_aaf(var):
    """
    Extract the AAF directly from the INFO field.
    """
    return var.INFO.get('AF')


def get_shortest_path_to_point(controller, initial_position, target_position):
    """
    Computes the shortest path to a point from an initial position using an agent controller
    :param controller: agent controller
    :param initial_position: dict(x=float, y=float, z=float) with the desired initial rotation
    :param target_position: dict(x=float, y=float, z=float) representing target position
    :return:
    """
    event = controller.step(action='GetShortestPathToPoint', position=
        initial_position, x=target_position['x'], y=target_position['y'], z
        =target_position['z'])
    if event.metadata['lastActionSuccess']:
        return event.metadata['actionReturn']['corners']
    else:
        raise ValueError("Unable to find shortest path to point '{}'".
            format(target_position))


def new_deposit_address():
    """
     Create a new deposit address
    """
    raise NotImplemented


def logical_xor(attrs, inputs, proto_obj):
    """Logical xor of two input arrays."""
    return 'broadcast_logical_xor', attrs, inputs


@classmethod
def scratch_pad(cls):
    """ A class method to use the Components intent methods as a scratch pad"""
    return cls.from_env(task_name='scratch_pad', default_save=False,
        default_save_intent=False, reset_templates=False, align_connectors=
        False).intent_model


@staticmethod
def _sanityCheckKeySizes(other):
    """Check if key size limits are sane"""
    if other.minKeySize < 512:
        raise ValueError('minKeySize too small')
    if other.minKeySize > 16384:
        raise ValueError('minKeySize too large')
    if other.maxKeySize < 512:
        raise ValueError('maxKeySize too small')
    if other.maxKeySize > 16384:
        raise ValueError('maxKeySize too large')
    if other.maxKeySize < other.minKeySize:
        raise ValueError('maxKeySize smaller than minKeySize')


def disable_pydicom_read_force():
    """
    Enable the pydicom read force to try to read non conform dicom data
    """
    global pydicom_read_force
    pydicom_read_force = False


@classmethod
def _form_media_range(cls, type_subtype, media_type_params):
    """
        Combine `type_subtype` and `media_type_params` to form a media range.

        `type_subtype` is a ``str``, and `media_type_params` is an iterable of
        (parameter name, parameter value) tuples.
        """
    media_type_params_segment = ''
    for param_name, param_value in media_type_params:
        param_value = cls._escape_and_quote_parameter_value(param_value=
            param_value)
        media_type_params_segment += ';' + param_name + '=' + param_value
    return type_subtype + media_type_params_segment


def update_pbeam_negative_integer(pname_fid):
    """
    Converts the negative PBEAM value to a positive one

    Parameters
    ----------
    pname_fid : int
        for a PBEAM this should be between [-5, -167]
        the negative values correspond to the numbers in the MPT OP2 table

    Returns
    -------
    pname_fid : str
        a pname is of 'J(3)' is far more clear than -37

    TODO: only handles istation=0 for now (e.g., 'J(1)')
    """
    if not -167 <= pname_fid <= -6:
        msg = (
            "A-property_type='PBEAM' has not implemented %r in pname_map" %
            pname_fid)
        raise NotImplementedError(msg)
    ioffset = -pname_fid - 6
    istation = ioffset // 16
    iterm = ioffset % 16
    assert istation == 0, istation
    if iterm == 2:
        word = 'A'
    elif iterm == 3:
        word = 'I1'
    elif iterm == 4:
        word = 'I2'
    elif iterm == 5:
        word = 'I12'
    elif iterm == 6:
        word = 'J'
    elif iterm == 8:
        word = 'C1'
    elif iterm == 9:
        word = 'C2'
    elif iterm == 10:
        word = 'D1'
    elif iterm == 11:
        word = 'D2'
    elif iterm == 12:
        word = 'E1'
    elif iterm == 13:
        word = 'E2'
    elif iterm == 14:
        word = 'F1'
    elif iterm == 15:
        word = 'F2'
    else:
        msg = (
            "property_type='PBEAM' has not implemented %r (istation=%r, iterm=%r) in pname_map"
             % (pname_fid, istation, iterm))
        raise NotImplementedError(msg)
    word = '%s(%i)' % (word, istation + 1)
    return word


def lambd_H3PO4_H2PO4_PS76(T, P):
    """n-a: phosphoric-acid dihydrogen-phosphate [PS76]."""
    lambd = -0.4
    valid = T == 298.15
    return lambd, valid


def getDmin(peaks):
    """needs a doc string"""
    return peaks[-1][-2]


def edge(i, j, v):
    """Determines if a point at i, j in a boolean grid v is on the boundary."""
    try:
        if v[i - 1, j] and v[i + 1, j] and v[i, j - 1] and v[i, j + 1]:
            return False
        else:
            return True
    except:
        return True


def _lg_attr_filter(container, node, condition, candidate_list):
    """
    Filter on attributes larger than requested value.
    """
    for candidate in list(candidate_list.keys()):
        attrn = condition[0]
        attrv = condition[1]
        for src, trg in candidate_list[candidate]:
            if src == node and attrn not in container.nodes[trg]:
                candidate_list.pop(candidate)
                break
            if src == node and attrn in container.nodes[trg
                ] and container.nodes[trg][attrn] <= attrv:
                candidate_list.pop(candidate)
                break


def render_changed():
    """Render current scene, when input node’s layer has been changed

    """
    pass


def simple_compression(string):
    """ Simple way to compress string. """
    symbol = ''
    compressed_string = ''
    n = 1
    for cha in string:
        if cha == symbol:
            n += 1
        else:
            if n > 1:
                compressed_string += str(n)
            compressed_string += cha
            symbol = cha
            n = 1
    return compressed_string


@staticmethod
def _get_disk_level(lsblk_disk_line):
    """ Helper to parse disk hierarchy returned by 'lsblk' """
    level = 0
    for c in lsblk_disk_line:
        if c in ['`', '|', '-', ' ']:
            level = level + 1
        else:
            break
    return level, lsblk_disk_line[level:]


@classmethod
def from_wfs_element(cls, feature, namespace):
    """Build an instance from a WFS feature element.

        Parameters
        ----------
        feature : etree.Element
            XML element representing a single record of the WFS layer.
        namespace : str
            Namespace associated with this WFS featuretype.

        Returns
        -------
        instance of this class
            An instance of this class populated with the data from the WFS
            element.

        """
    instance = cls(feature.findtext('./{{{}}}Interpretatiefiche'.format(
        namespace)))
    for field in cls.get_fields(source=('wfs',)).values():
        instance.data[field['name']] = cls._parse(func=feature.findtext,
            xpath=field['sourcefield'], namespace=namespace, returntype=
            field.get('type', None))
    return instance


def get_weight_by_name(module_weights, name):
    """
    Retrieve parameter weight values from result of Module.get_weights()
    :param module_weights: all weights of a module, returned by Module.get_weights()
    :param name:
    :return:
    """
    for w, w_name in module_weights:
        if name == w_name:
            return w
    return None


def _dataset_file_id_migration(client):
    """Ensure dataset files have a fully qualified url."""
    for dataset in client.datasets.values():
        for file_ in dataset.files:
            if not file_._id.startswith('https'):
                file_._id = file_.default_id()
        dataset.to_yaml()


def p_statements(p):
    """statements : statement statements
                  | statement """


@classmethod
def from_system(cls, **kwargs):
    """Constructor that returns Environ instance pre-populated with values
        from the process environment.
        """
    env = cls(**kwargs)
    env.inherit()
    return env


@classmethod
def create(cls, data=None):
    """
        Build an instance of this Model using the given data.
        """
    if not data:
        data = {}
    return cls(**data)


def get_axes_bounds(fig):
    """Return the entire axes space for figure.

    An axes object in mpl is specified by its relation to the figure where
    (0,0) corresponds to the bottom-left part of the figure and (1,1)
    corresponds to the top-right. Margins exist in matplotlib because axes
    objects normally don't go to the edges of the figure.

    In plotly, the axes area (where all subplots go) is always specified with
    the domain [0,1] for both x and y. This function finds the smallest box,
    specified by two points, that all of the mpl axes objects fit into. This
    box is then used to map mpl axes domains to plotly axes domains.

    """
    x_min, x_max, y_min, y_max = [], [], [], []
    for axes_obj in fig.get_axes():
        bounds = axes_obj.get_position().bounds
        x_min.append(bounds[0])
        x_max.append(bounds[0] + bounds[2])
        y_min.append(bounds[1])
        y_max.append(bounds[1] + bounds[3])
    x_min, y_min, x_max, y_max = min(x_min), min(y_min), max(x_max), max(y_max)
    return (x_min, x_max), (y_min, y_max)


@classmethod
def log_error(cls, *args, **kwargs):
    """ Write error message into log """
    pass


@staticmethod
def _set_raw(target, raw_value, bitarray):
    """ put value into bit array """
    offset = int(target['offset'])
    size = int(target['size'])
    for digit in range(size):
        bitarray[offset + digit] = raw_value >> size - digit - 1 & 1 != 0
    return bitarray


def handle_code(code):
    """Handle to just prints the received code."""
    print(code)


def p_bloque_simp(p):
    """bloque_simp : '{' bloqueE '}'
    """


@classmethod
def get_default_config(cls) ->dict:
    """Default config getter."""
    return {'num_dup': 1, 'bin_size': 30, 'hist_mode': 'LCH',
        'compress_ratio_left': 1.0, 'compress_ratio_right': 1.0,
        'embedding_output_dim': 100}


def graph_to_d3_json(graph, attrs=True, node_attrs_to_attach=None,
    edge_attrs_to_attach=None, nodes=None):
    """Create a JSON representation of a graph."""
    j_data = graph.to_d3_json()
    return j_data


def distro_uri(distro_name):
    """
    Get distro URI of main ROS distribution files.

    :param distro_name: name of distro, e.g. 'diamondback'
    :returns: the SVN/HTTP URL of the specified distro.  This function should only be used
      with the main distros.
    """
    return (
        'http://svn.code.sf.net/p/ros-dry-releases/code/trunk/distros/%s.rosdistro'
         % distro_name)


@classmethod
def set_ROI(cls, s, shape='circle', color='r', interactive=False):
    """ Selects an interactive region of interst (ROI) to the signal

        :type  s: hyperspy signal
        :param s: the signal of interest

        :type  shape: string
        :param shape: the description of the ROI; circle, ring, rectangle

        :type  interactive: boolean
        :param interactive: interactive if True, False if left blank

        :returns: hyperspy roi, hyperspy signal
        """
    import hyperspy.api as hs
    if s.axes_manager.navigation_dimension < 2:
        axes = 'sig'
        x_axis = s.axes_manager[s.axes_manager.signal_indices_in_array[1]]
        y_axis = s.axes_manager[s.axes_manager.signal_indices_in_array[0]]
    else:
        axes = 'nav'
        x_axis = s.axes_manager[s.axes_manager.navigation_indices_in_array[1]]
        y_axis = s.axes_manager[s.axes_manager.navigation_indices_in_array[0]]
    if shape == 'circle':
        x = x_axis.axis[round(x_axis.size / 2)]
        y = y_axis.axis[round(y_axis.size / 2)]
        r_outer = x_axis.axis[round(3 * x_axis.size / 4)]
        sroi = hs.roi.CircleROI(x, y, r=r_outer, color=color)
        """
            s.plot()
            sroi= sroi.interactive(s)
            ss = hs.interactive(f=sroi.sum, event=sroi.events.data_changed)
            """
    elif shape == 'ring':
        x = x_axis.axis[round(x_axis.size / 2)]
        y = y_axis.axis[round(y_axis.size / 2)]
        r_outer = x_axis.axis[round(4 * x_axis.size / 5)]
        r_inner = x_axis.axis[round(3 * x_axis.size / 4)]
        sroi = hs.roi.CircleROI(x, y, r=r_outer, r_inner=r_inner, color=color)
        """
            s.plot()
            sroi= sroi.interactive(s)
            ss = hs.interactive(f=sroi.sum, event=sroi.events.data_changed)
            """
    else:
        if not shape == 'rectangle':
            print('Did not recognize shape, using rectangle')
        x1 = x_axis.axis[1]
        x2 = x_axis.axis[round(x_axis.size / 10)]
        y1 = y_axis.axis[1]
        y2 = y_axis.axis[round(y_axis.size / 10)]
        sroi = hs.roi.RectangularROI(x1, y1, x2, y2)
    if interactive:
        s.plot()
        roi_signal = sroi.interactive(s)
        ss = hs.interactive(f=roi_signal.sum, event=roi_signal.events.
            data_changed)
    else:
        roi_signal = sroi(s)
        ss = roi_signal.sum()
    return sroi, ss


@classmethod
def validate_url(cls, url):
    """Strip and trailing slash to validate a url

        :param url: the url address
        :return: the valid url address
        :rtype: string
        """
    if url is None:
        return None
    url = url.strip()
    while url.endswith('/'):
        url = url[:-1]
    return url


def adu2electrons(adu, ccd_gain):
    """
    converts analog-to-digital units into electron counts

    :param adu: counts in analog-to-digital unit
    :return: counts in electrons
    """
    return adu * ccd_gain


def firn_permittivity(rhof, rhoi=917.0, epsi_real=3.12, epsi_imag=-9.5):
    """
    Calculate the dielectric permittivity of firn with the DECOMP mixing model
    Wilhelms (2005), GRL

    Parameters
    ---------
    rhof:           firn density       (kg/m3)
    rhoi:           ice density       (kg/m3)
    epsi_real:      real permittivity of ice (relative)
    epsi_imag:      imaginary permittivity of ice (relative)

    Output
    ---------
    eps_f:          firn permittivity   (relative)
    """
    lhs = 1.0 + rhof / rhoi * ((epsi_real - 1.0j * epsi_imag) ** (1 / 3.0) - 1)
    eps_f = lhs ** 3.0
    return eps_f


@classmethod
def _parse_args(cls, args, kwargs):
    """
        Parse kwargs and return a dict.
        :param kwargs: dict to parse
        :return:
        """
    if len(args) > 2:
        raise ValueError(
            'a maximum of 2 optional argument may be given ({} were given.)'
            .format(len(args)))
    for k in kwargs.keys():
        if k not in cls.default_config:
            raise TypeError('unknown option {}'.format(k))
    return kwargs


def remove_expired_contacts(contact_graph, time):
    """Remove expired and thus obsolete contacts from the contact graphself.

    Helps reducing complexity and thus boost route finding performance.

    Args:
        contact_graph (ContactGraph): A ContactGraph object for topology
            information.
        time (type): The current time. All contacts that expired before that
            time will be removed.

    """
    graph_nodes = list(contact_graph.graph.keys())
    for node in graph_nodes:
        if node.to_time < time:
            contact_graph.remove_contact_node(node)
    del graph_nodes


def _set_random_seeds():
    """Set new random seeds for the process.
    """
    try:
        import numpy as np
        np.random.seed()
    except:
        pass
    try:
        import scipy as sp
        sp.random.seed()
    except:
        pass
    import random
    random.seed()


def convert_to_list(data):
    """Convert a value into a list.

    :param data: The value to convert.
    :return: A new list wrapped around 'data' whereupon the list is empty
        if 'data' is None.
    """
    if data is None:
        return []
    elif hasattr(data, '__iter__') and not isinstance(data, str):
        return list(data)
    else:
        return [data]


def vertices_smooth(factor: float=0.5, repeat: int=1, xaxis: bool=True,
    yaxis: bool=True, zaxis: bool=True):
    """Flatten angles of selected vertices

    :param factor: Smoothing, Smoothing factor
    :type factor: float
    :param repeat: Repeat, Number of times to smooth the mesh
    :type repeat: int
    :param xaxis: X-Axis, Smooth along the X axis
    :type xaxis: bool
    :param yaxis: Y-Axis, Smooth along the Y axis
    :type yaxis: bool
    :param zaxis: Z-Axis, Smooth along the Z axis
    :type zaxis: bool
    """
    pass


def srcpath(base, pth):
    """Return an absolute path based on the relative path `pth`.
       Useful in tests, where we don't know what the absolute path is,
       and we can't use relative paths since we don't know which folder
       the tests are run from.

       In a test file xxxxxxx/foo/test/test_foo.py::

          path = 'foo/test'
          fp = open(srcpath(path, 'data/testdata.txt'))

    """
    raise EnvironmentError('dk.utils.srcpath no longer does anything useful.')


@classmethod
def from_pos(cls, pos: int, text: str, message: str=None, filename: str=None):
    """Instantiate from a full *text* and a file position *pos*"""
    try:
        start = text.rindex('\n', 0, pos) + 1
    except ValueError:
        start = 0
    try:
        end = text.index('\n', start)
    except ValueError:
        end = len(text)
    lineno = text.count('\n', 0, start)
    line = text[start:end]
    return cls(message, filename=filename, lineno=lineno, offset=pos -
        start, text=line)


def encoder_linelength(msg):
    """
    RFC1341 mandates that base64 encoded data may not be longer than 76 characters per line
    https://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html section 5.2
    """
    orig = msg.get_payload(decode=True).replace(b'\n', b'').replace(b'\r', b'')
    max_length = 76
    pieces = []
    for i in range(0, len(orig), max_length):
        chunk = orig[i:i + max_length]
        pieces.append(chunk)
    msg.set_payload(b'\r\n'.join(pieces))


def _sklearn_numpy_warning_fix():
    """Fixes unecessary warnings emitted by sklearns use of numpy.

    Sklearn will fix the warnings in their next release in ~ August 2018.

    based on https://stackoverflow.com/questions/49545947/sklearn-deprecationwarning-truth-value-of-an-array"""
    import warnings
    warnings.filterwarnings(module='sklearn*', action='ignore', category=
        DeprecationWarning)


def basic_state():
    """The state of nodes in :func:`~pyphi.examples.basic_network`."""
    return 1, 0, 0


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def for_loop(function, argument_list):
    """Apply a multivariate function to a list of arguments in a serial fashion.

    Uses Python's built-in for statement.

    Args:
        function: A callable object that accepts more than one argument
        argument_list: An iterable object of input argument collections

    Returns:
        List of output results

    Example:
        >>> def add(x, y, z):
        ...     return x+y+z
        ...
        >>> for_loop(add, [(1, 2, 3), (10, 20, 30)])
        [6, 60]

    References:
        - https://docs.python.org/3/reference/compound_stmts.html#the-for-statement
        - https://docs.python.org/3/tutorial/controlflow.html#for-statements
    """
    result_list = []
    for args in argument_list:
        result_list.append(function(*args))
    return result_list


def escapeCMLTextValue(src):
    """Escapes the string before inserting it to the code (CML value)"""
    dst = ''
    for char in src:
        if char == '\n':
            dst += '\\n'
        elif char in ('"', '\\'):
            dst += '\\' + char
        else:
            dst += char
    return dst


def _separate_keyword(line):
    """Split the line, and return (first_word, the_rest)."""
    try:
        first, rest = line.split(None, 1)
    except ValueError:
        first = line.strip()
        rest = ''
    return first, rest


def assign_synthase_indices(groups):
    """Assign hidden y indices to synthases.

    The indices are staggered by synthase subtype group for visual separation in the
    plot.
    """
    index = 0
    for group in groups:
        for synthase in group:
            setattr(synthase, '_index', index)
            index += 1
        index += 1


def __lt__(i1, i2):
    """ Test if i1.sup < i2.inf
        """
    return i1.sup < i2.inf


def _create_template(zmat, memory_size):
    """ wrapper for the template creation
    this is the most flexible way in case it needs to be changed in the future
    """
    template = zmat.get()
    template += '*ACES2( BASIS={basis:s},'
    template += '\n\t' + 'CALC={theory:s},'
    template += '\n\t' + 'MEMORY_SIZE={:d}GB,'.format(memory_size)
    template += '\n\t' + 'IP_CALC=IP_EOMCC,'
    template += '\n\t' + 'PREP_VIBRON=ON,'
    template += '\n\t' + 'GRID_VIBRON={gridVibron:d},'
    template += '\n\t' + 'CC_CONV={ccConv:d},'
    template += '\n\t' + 'SCF_CONV={scfConv:d},'
    template += '\n\t' + 'ESTATE_TOL={estateTol:d},'
    template += '\n\t' + ')'
    template += '\n'
    template += '\n' + '*mrcc_gen'
    template += '\n\t' + 'nip={nip:d}'
    template += '\n' + '*ip_eom'
    template += '\n\t' + 'diabatize=on'
    template += '\n\t' + 'heff_low=0'
    template += '\n\t' + 'heff_high=200'
    template += '\n' + '*end'
    template += '\n'
    return


def get_col_stat(me, xid):
    """get_col_stat with transparent index mapping."""
    xid = me._colmap.map(xid) if xid else xid
    if xid > 0:
        return me._get_col_stat(xid)


def theta_H_K_PK74(T, P):
    """c-c': hydrogen potassium [PK74]."""
    theta = 0.005
    valid = T == 298.15
    return theta, valid


def service_model(service):
    """Produce the model for a service"""
    return {'name': service.name, 'admin': service.admin, 'url': service.
        url, 'prefix': service.server.base_url if service.server else '',
        'command': service.command, 'pid': service.proc.pid if service.proc
         else 0}


def _calc_resolelement(w, fcol, r, A):
    """Calculate the resolution element using dw=r*w/A/fcol

       returns resolution element in mm
    """
    return r * w / A / fcol


def logout(request):
    """Performs a logout by delegating to its authenticator plugins."""


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def df_compiler(d: list, m: str='all', dist: str='') ->list:
    """    Collect essential information for transferring samples to the destination folder
    on AWS.

    :param d:
        Sample ids
    :param m:
        Mode of operation, one of `all`, or `hashtags`
    :param dist:
        Target folder destination for transfer, which is the parent directory where
        projects and samples are stored, for a particular sample.

    :return:
        Statement results
    """
    statement = {'all':
        "SELECT a.id, a.Sample, a.request_id, a.projectData_id, b.projectShortName AS project, a.processed, c.PI_email, a.AWS_storage, '{}' AS destination, 'sample_data stats_data' AS `table`, s.Run_Name, a.processed FROM sample_data AS a JOIN project_data AS b ON a.projectData_id=b.id JOIN lab AS c ON b.lab_id=c.id JOIN genome_index AS g ON g.id=a.genomeIndex_id JOIN sc_tech AS s ON s.id=g.scTech_id WHERE a.id='{}'"
        , 'hashtags':
        "SELECT a.id, d.Sample, a.request_id, a.projectData_id, b.projectShortName AS project, a.processed, c.PI_email, d.AWS_storage, '{}' AS destination, 'hashtag_lib' AS `table`, s.Run_Name, d.`status` FROM sample_data AS a JOIN project_data AS b ON a.projectData_id=b.id JOIN lab AS c ON b.lab_id=c.id JOIN hashtag_lib AS d ON d.sampleData_id=a.id JOIN genome_index AS g ON g.id=d.genomeIndex_id JOIN sc_tech AS s ON s.id=g.scTech_id WHERE a.id='{}'"
        }
    statements = []
    for i in d:
        statements.append(statement[m].format(dist, i))
    return statements


def wait(zelf, sec=180.0):
    """ wait for the task to be ready. """
    zelf._ready.wait()


def update_callback(request, cbString, **kwargs):
    """Update a callback handle with  key/value pairs"""
    for key, value in kwargs.items():
        request.session['callback'][cbString][key] = value


def _get_port_definitions(app):
    """
    Get the ``portDefinitions`` field for the app if present.
    """
    if 'portDefinitions' in app:
        return app['portDefinitions']
    if 'ports' in app:
        return app['ports']
    return None


def _dummy(*args, **kw):
    """A method not available function."""
    raise Exception('methods not available')


def get_object_from_string(object_path):
    """
    Return python object from string
    :param object_path: e.g os.path.join
    :return: python object
    """
    try:
        module_name, object_name = object_path.rsplit('.', maxsplit=1)
        module_ = __import__(module_name, globals(), locals(), ['App'], 0)
        variable_ = getattr(module_, object_name)
    except Exception:
        variable_ = None
    return variable_


def cplx01_f(z, n, a):
    """z**n-a:  Use to find the n-th root of a"""
    return z ** n - a


@classmethod
def get_default_config(cls) ->dict:
    """Default config getter."""
    return {'num_dup': 1, 'batch_size': 8, 'stage': 'train', 'resample':
        True, 'shuffle': False, 'sort': True, 'bin_size': 30, 'hist_mode':
        'LCH', 'compress_ratio_left': 1.0, 'compress_ratio_right': 1.0,
        'embedding_output_dim': 100}


@classmethod
def fromXmlString(ownclass, string, context, template=None):
    """Loads the array from a comma-separated string.

        Note: this is not actually used in XML values files, because array elements are stored in individual
        XML elements through the load/save methods. However, this method is used by scripts that take data
        values from strings (command line arguments, environmental variables). Hence its existence, but the
        name is far from perfect...
        """
    strings = string.split(',')
    if template is not None and template.hasAttribute('shape'):
        shape = template.getAttribute('shape').split(',')
        assert len(shape
            ) == 1, 'Cannot assign values to arrays with more than 1 dimension through a comma-separated string.'
        if shape[0] != ':':
            n = int(shape[0])
            if len(strings) < n:
                strings += [None] * (n - len(strings))
            strings = strings[:n]
    data = []
    for item in strings:
        if item == '':
            item = None
        elif item is not None:
            item = ownclass.elementclass.fromXmlString(item, context, template)
        data.append(item)
    return ownclass(data, template=template)


def setAllowedGroupsForEdit(groups):
    """
        This method assigns the groups that have edit permission to the tile
        """


def _get_ax_freq(ax):
    """
    Get the freq attribute of the ax object if set.
    Also checks shared axes (eg when using secondary yaxis, sharex=True
    or twinx)
    """
    ax_freq = getattr(ax, 'freq', None)
    if ax_freq is None:
        if hasattr(ax, 'left_ax'):
            ax_freq = getattr(ax.left_ax, 'freq', None)
        elif hasattr(ax, 'right_ax'):
            ax_freq = getattr(ax.right_ax, 'freq', None)
    if ax_freq is None:
        shared_axes = ax.get_shared_x_axes().get_siblings(ax)
        if len(shared_axes) > 1:
            for shared_ax in shared_axes:
                ax_freq = getattr(shared_ax, 'freq', None)
                if ax_freq is not None:
                    break
    return ax_freq


def get_code(fullname):
    """ Return the code object for the module identified by 'fullname'.

        Return 'None' if it's a built-in or extension module.

        If the loader doesn't have the code object but it does have the source
        code, return the compiled source code.

        Raise ImportError if the module can't be found by the importer at all.
        """


@staticmethod
def seconds_toperiods(total_seconds):
    """
        Ontleedt een getal in seconden naar lijst met vaste periodes: days, hours, minutes, seconds
        waarbij day    =          24 * 60 * 60 =     86,400 seconden
                hour   =               60 * 60 =      3,600 seconden
                minute =                    60 =         60 seconden

        Parameters
        --------------
        total_seconds : float or int
            bijvoorbeeld Timedelta.total_seconds() van Pandas dataframe bv index[1]-index[0]

        Returns
        -------------
        list : list of integer values [days, hours, minutes, seconds]
        """
    days, remainder = divmod(total_seconds, 24 * 3600)
    hours, remainder = divmod(remainder, 3600)
    minutes, seconds = divmod(remainder, 60)
    return [int(days), int(hours), int(minutes), int(seconds)]


def get_col_names_and_indices(sqlite_description, ignore_gt_cols=False):
    """Return a list of column namanes and a list of the row indices.
       Optionally exclude gt_* columns.
    """
    col_indices = []
    col_names = []
    for idx, col_tup in enumerate(sqlite_description):
        col_name = col_tup[0]
        if not ignore_gt_cols or ignore_gt_cols and not col_name.startswith(
            'gt'):
            col_indices.append(idx)
            col_names.append(col_name)
    return col_names, col_indices


def list_from_level(field, level):
    """
    extract list from field in level of item
    """
    return level[field] if field in level else []


def drivers_editor_show():
    """Show drivers editor in a separate window

    """
    pass


def remove_vdmx_table(tt):
    """Removes TTFA table from a fontTools.ttLib.TTFont object"""
    try:
        del tt['VDMX']
    except KeyError:
        pass


def emptyArray(key, add_label=None):
    """An array that starts empty"""
    result = {'key': key, 'startEmpty': True}
    if add_label is not None:
        result['add'] = add_label
        result['style'] = {'add': 'btn-success'}
    return result


def mass_to_volume_mixing_ratio(mass_mixing_ratio, molecular_weight=None,
    molecular_weight_air=28.964):
    """
    g/g or g/kg to mole/mole

    Converts from mass mixing ratio (mass per unit mass) to volume
    mixing ratio (volume per unit volume)

    Args:

        mass_mixing_ratio (array):
            The quantity to be transformed in units of :math:`g/g`.

        molecular_weight (float):
            The molecular weight of the gas in :math:`g/mol`.

        molecular_weight_air (float,optional):
            The molecular weight of dry air.
            If it is not provided, the value for dry air on earth (28.964 g/mol)
            is used.

    Returns:

        volume_mixing_ratio (array):
            The volume mixing ratio of the gas.

    Raises:

        ValueError:
            if the molecular weight is not provided.

    """
    if molecular_weight is None:
        raise ValueError('The molecular weight must be provided')
    volume_mixing_ratio = (mass_mixing_ratio * molecular_weight_air /
        molecular_weight)
    return volume_mixing_ratio


def fix_float(att):
    """ Python 2/3 compatibility fix for str(float). Reference:
    https://github.com/unified-font-object/ufoLib/issues/19
    """
    try:
        att = list(att)
        if isinstance(eval(str(att[1])), float):
            att[1] = repr(att[1])
    except:
        pass
    return att


def make_int(text: str, default: int=-1) ->int:
    """Converts text into integer."""
    try:
        return int(text)
    except (TypeError, ValueError):
        return default


def CheckEdAndObjectVariables(programIR):
    """Check all of the object variables and make sure that Ed variables are allowed ones,
       and others are data members in classes"""
    pass


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


def get(property):
    """
        Получить значение свойства домена.

        Если текущий домен не содержит информацию о данном свойстве, будет
        предпринято обращение к предку домена за данным свойством.

        @param property: имя свойства
        @type property: C{str}
        @return: значение свойства
        """


def process(proc_data):
    """
    Final processing to conform to the schema.

    Parameters:

        proc_data:   (dictionary) raw structured data to process

    Returns:

        Dictionary. Structured data with the following schema:

        {
          "local_time":                        string,
          "universal_time":                    string,
          "rtc_time":                          string,
          "time_zone":                         string,
          "ntp_enabled":                       boolean,
          "ntp_synchronized":                  boolean,
          "system_clock_synchronized":         boolean,
          "systemd-timesyncd.service_active":  boolean,
          "rtc_in_local_tz":                   boolean,
          "dst_active":                        boolean
        }
    """
    bool_list = ['ntp_enabled', 'ntp_synchronized', 'rtc_in_local_tz',
        'dst_active', 'system_clock_synchronized',
        'systemd-timesyncd.service_active']
    for key in proc_data:
        if key in bool_list:
            try:
                proc_data[key] = True if proc_data[key] == 'yes' else False
            except ValueError:
                proc_data[key] = None
    return proc_data


def create_project(name=None, defaultJobTimeoutMinutes=None):
    """
    Creates a new project.
    See also: AWS API Documentation

    Examples
    The following example creates a new project named MyProject.
    Expected Output:

    :example: response = client.create_project(
        name='string',
        defaultJobTimeoutMinutes=123
    )

    :type name: string
    :param name: [REQUIRED]
            The project's name.

    :type defaultJobTimeoutMinutes: integer
    :param defaultJobTimeoutMinutes: Sets the execution timeout value (in minutes) for a project. All test runs in this project will use the specified execution timeout value unless overridden when scheduling a run.

    :rtype: dict
    :return: {
        'project': {
            'arn': 'string',
            'name': 'string',
            'defaultJobTimeoutMinutes': 123,
            'created': datetime(2015, 1, 1)
        }
    }

    """
    pass


@classmethod
def get_provider_choice(cls):
    """
        Should return a two-element tuple of the short and long name of the
        provider type. This should be what the choices attribute on a
        model field is expected (e.g., ('db_value', 'Label') )
        """
    if not hasattr(cls, 'SHORT_NAME') or not cls.SHORT_NAME:
        raise AttributeError('SHORT_NAME must exist and be a string.')
    if not hasattr(cls, 'LONG_NAME') or not cls.LONG_NAME:
        raise AttributeError('LONG_NAME must exist and be a string.')
    return cls.SHORT_NAME, cls.LONG_NAME


def _allow_join(statement):
    """
    Tests if a join should be suggested

    We need this to avoid bad suggestions when entering e.g.
        select * from tbl1 a join tbl2 b <cursor>
    So check that the preceding token is a JOIN keyword

    :param statement: an sqlparse.sql.Statement
    :return: boolean
    """
    if not statement or not statement.tokens:
        return False
    last_tok = statement.token_prev(len(statement.tokens))[1]
    return last_tok.value.lower().endswith('join') and last_tok.value.lower(
        ) not in ('cross join', 'natural join')


@classmethod
def is_applicable(cls) ->bool:
    """
        Checks if this procedure is applicable to the current system
        :return: True if applicable, else False
        """
    raise NotImplementedError()


def keymax(d):
    """Return key in dictionary containing maximum value"""
    vmax = max(d.values())
    for k, v in d.items():
        if v == vmax:
            return k


def auto_positions_factor_tag_from_auto_positions_factor(auto_positions_factor
    ):
    """Generate an auto positions factor tag, to customize phase names based on the factor automated positions are
    required to trace within one another.

    This changes the phase name 'phase_name' as follows:

    auto_positions_factor = None -> phase_name
    auto_positions_factor = 2.0 -> phase_name__auto_pos_x2.00
    auto_positions_factor = 3.0 -> phase_name__auto_pos_x3.00
    """
    if auto_positions_factor is None:
        return ''
    return '__auto_pos_x{0:.2f}'.format(auto_positions_factor)


def set(object, value):
    """Set the value of the field for the object

        Raises a type error if the field is a read-only field.
        """


@staticmethod
def _check_key_valid(key):
    """_check_key_valid.

        Internal method to check if an input key to the dictionary is valid.
        Checks to see if ``key`` is a tuple.

        Parameters
        ----------
        key : anything, but must be a tuple to be valid.

        Returns
        -------
        None.

        Raises
        ------
        KeyError if the key is invalid.

        """
    if not isinstance(key, tuple):
        raise KeyError('Key formatted incorrectly, must be tuple')


def _select_other_window(history):
    """ Toggle focus between left/right window. """
    current_buffer = history.app.current_buffer
    layout = history.history_layout.layout
    if current_buffer == history.history_buffer:
        layout.current_control = history.history_layout.default_buffer_control
    elif current_buffer == history.default_buffer:
        layout.current_control = history.history_layout.history_buffer_control


def _indent_str(indent):
    """
    Return a MOF indent pad unicode string from the indent integer variable
    that defines number of spaces to indent. Used to format MOF output.
    """
    return u''.ljust(indent, u' ')


@classmethod
def replaceURL(cls, match):
    """Replace hyperlinks with clickable  tags
        """
    url = match.groups()[0]
    linktext = cls.abbreviateUrl(url)
    end = ''
    if url.endswith('>'):
        url = url[:-len('>')]
        linktext = linktext[:-len('>')]
        end = '>'
    elif url.endswith('.') or url.endswith('?') or url.endswith('!'):
        end = url[-1]
        url = url[:-1]
        linktext = linktext[:-1]
    return '%s%s' % (url, linktext, end)


@classmethod
def get_user_thread(cls, request, thread_id, user, return_default=False):
    """Gets user thread while creating pool if necessary."""
    request = cls._extract_django_request(request)
    user_threads_pool = cls._get_user_threads_pool(request, thread_id)
    if user.pk in user_threads_pool:
        return user_threads_pool[user.pk]
    elif return_default:
        from chat_api.chat.models import UserThread
        thread = cls.get_thread(request, thread_id)
        return UserThread(user=user, thread=thread, created=thread.created,
            updated=thread.updated, notifications=0, permissions=UserThread
            .PERMISSION_MESSAGES_READ | UserThread.PERMISSION_THREAD_READ,
            state=UserThread.STATE_CLOSED, last_message=thread.last_message)
    return None


@classmethod
def build_const_args(cls, spec_dict):
    """ Build constructor arguments for this Spec class from a dictionary """
    ret = super().build_const_args(spec_dict)
    if 'doc' not in ret:
        msg = "'doc' missing: %s" % str(spec_dict)
        raise ValueError(msg)
    return ret


def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox', '.env', 'env', 'venv',
        'node_modules', 'bower_components']
    prefs['save_objectdb'] = True
    prefs['compress_objectdb'] = False
    prefs['automatic_soa'] = True
    prefs['soa_followed_calls'] = 0
    prefs['perform_doa'] = True
    prefs['validate_objectdb'] = True
    prefs['max_history_items'] = 32
    prefs['save_history'] = True
    prefs['compress_history'] = False
    prefs['indent_size'] = 4
    prefs['extension_modules'] = []
    prefs['import_dynload_stdmods'] = True
    prefs['ignore_syntax_errors'] = False
    prefs['ignore_bad_imports'] = False
    prefs['prefer_module_from_imports'] = False
    prefs['split_imports'] = False
    prefs['pull_imports_to_top'] = True
    prefs['sort_imports_alphabetically'] = False
    prefs['type_hinting_factory'
        ] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'


def obs_pred_mse(obs, pred):
    """Calculate the mean squared error of the prediction given observation."""
    return sum((obs - pred) ** 2) / len(obs)


def check_lonlat(lon, lat):
    """
    Raise a ``ValueError`` if ``lon`` and ``lat`` do not represent a valid
    longitude-latitude pair.
    Otherwise, return nothing.
    """
    if not -180 <= lon <= 180:
        raise ValueError('Longitude {!s} is out of bounds'.format(lon))
    if not -90 <= lat <= 90:
        raise ValueError('Latitude {!s} is out of bounds'.format(lat))


@classmethod
def cmsd(cls, *args):
    """
        executes cm with the given arguments
        :param args:
        :return:
        """
    return cls.execute('cmsd', args)


def reverse_complement(table, seq):
    """Return the reverse complement of a DNA sequence."""
    return seq.translate(str.maketrans('ATGC', 'TACG'))[::-1]


def make_missing_ntiid():
    """
        Call this when the reference is clear to produce an NTIID
        that refers to the object that was referenced.

        Calling this before the reference is clear is not defined.
        """


def gram_schmidt(data):
    """
    Calculate Gram-Schmidt orthogonalization parameters.
    """
    C = (data.real * data.imag).sum()
    R = (data.real * data.real).sum()
    idata = data.imag - C / R * data.real
    S = (idata * idata).sum()
    return R / S, -C / S


def append_vcf_header(main_curr, chunk_db):
    """
    Append the vcf_header from a chunk_db
    to the main database.
    """
    cmd = 'attach ? as toMerge'
    main_curr.execute(cmd, (chunk_db,))
    cmd = 'INSERT INTO vcf_header SELECT * FROM toMerge.vcf_header'
    main_curr.execute(cmd)
    cmd = 'detach toMerge'
    main_curr.execute(cmd)


def shape(seq, strict=False, types=(list, tuple)):
    """
    Return the shape of a list of lists.

    Examples:
        >>> L = [[0, 1, 2],
        ...      [3, 4, 5]]
        >>> shape(L,)
        (2, 3)
    """
    shape = []
    curr = seq
    if not strict:
        while isinstance(curr, types):
            shape.append(len(curr))
            try:
                curr = curr[0]
            except IndexError:
                break
    else:
        return NotImplemented
    return tuple(shape)


def exps_by_states_dict(api, states):
    """ Return current experiment in `states` as a per state dict """
    exps = api.get_experiments(state=','.join(states))['items']
    exp_states_d = {}
    for exp in exps:
        exp_states_d.setdefault(str(exp['state']), []).append(exp['id'])
    return exp_states_d


def str_to_datetime(date: str, format='%Y-%m-%d %H:%M:%S'):
    """
    Convert string back to datetime

    @Args:
    * [date] str, the input string in some date format
    * [format] str, default is YYYY-mm-dd HH:MM:SS

    @Returns:
    * [datetime] returning is a datetime type
    """
    from datetime import datetime
    if date is not None:
        return datetime.strptime(date, format)
    else:
        return datetime.strptime('1970-01-01 00:00:00', format)


def Merge(xml, message):
    """Merges an xml representation of a protocol message into a message object.

  Args:
    text: Message xml representation.
    message: A protocol buffer message to merge into.

  Raises:
    ParseError: On xml parsing problems.
  """
    raise NotImplementedError(
        'Protobuf message creation from xml messages not implemented.')


def cal_RPKM(input_counts, input_length, total_counts):
    """
	calculate the RPKM value
	"""
    return 10 ** 9 * input_counts / (total_counts * input_length)


@staticmethod
def _process_match_index(match, match_index):
    """
        Process match index from this pattern process state.

        :param match:
        :return:
        """
    match.match_index = match_index


def idealized_arc_curve(width, index):
    """
    Returns the value at x for the parabola of width n and height n / 2.
    Formula taken from https://www.desmos.com/calculator/awtnrxh6rk.

    Parameters
    ----------
    width : int
        Length of the time series to calculate the parabola for.
    index : int
        location to compute the parabola value at.

    Returns
    -------
    float : y
        The value at index for the parabola.

    """
    height = width / 2
    c = width / 2
    b = height
    a = height / (width / 2) ** 2
    y = -(a * (index - c) ** 2) + b
    return y


def p_nowdoc_text_content(p):
    """nowdoc_text_content : nowdoc_text_content ENCAPSED_AND_WHITESPACE
                           | empty"""
    if len(p) == 3:
        p[0] = p[1] + p[2]
    else:
        p[0] = ''


def event_log_formatter(events):
    """Return the events in log format."""
    event_log = []
    log_format = (
        '%(event_time)s [%(rsrc_name)s]: %(rsrc_status)s  %(rsrc_status_reason)s'
        )
    for event in events:
        event_time = getattr(event, 'event_time', '')
        log = log_format % {'event_time': event_time.replace('T', ' '),
            'rsrc_name': getattr(event, 'resource_name', ''), 'rsrc_status':
            getattr(event, 'resource_status', ''), 'rsrc_status_reason':
            getattr(event, 'resource_status_reason', '')}
        event_log.append(log)
    return '\n'.join(event_log)


def append_to_nrow_ncol_based_on_shape(sh, nrow, ncol):
    """
    Append to list based on shape of array

    Args:
        * **sh** (:py:class:`tuple`): Shape of array.
        * **nrow** (:py:class:`list`): List of number of rows
        * **ncol** (:py:class:`list`): List of number of columns

    Returns:
        * **nrow** (:py:class:`list`): List of number of rows
        * **ncol** (:py:class:`list`): List of number of columns
    """
    if len(sh) == 1:
        nrow.append(sh[0])
        ncol.append(1)
    else:
        nrow.append(sh[0])
        ncol.append(sh[1])
    return nrow, ncol


def arg_parser():
    """
    Create an empty argparse.ArgumentParser.

    :return: (ArgumentParser)
    """
    import argparse
    return argparse.ArgumentParser(formatter_class=argparse.
        ArgumentDefaultsHelpFormatter)


def _dotted_dict_to_nested_dicts(dotted_dict, delimiter_nested='.'):
    """Convert dotted keys in the state point dict to a nested dict.

    :param dotted_dict: A mapping with dots/delimiter_nested in its keys, e.g. {'a.b': 'c'}.
    :param delimiter_nested: A string delimiter between keys, defaults to '.'.
    :returns: A mapping instance with nested dicts, e.g. {'a': {'b': 'c'}}.
    """
    nested_dict = dict()
    for key, value in dotted_dict.items():
        tokens = key.split(delimiter_nested)
        if len(tokens) > 1:
            tmp = nested_dict.setdefault(tokens[0], dict())
            for token in tokens[1:-1]:
                tmp = tmp.setdefault(token, dict())
            tmp[tokens[-1]] = value
        else:
            nested_dict[tokens[0]] = value
    return nested_dict


def unquote(value):
    """ remove quotes if needed """
    if isinstance(value, str) and len(value) > 1 and value[0] == '"' and value[
        -1] == '"':
        return value[1:-1]
    return value


def parse_spec(spec: str) ->dict:
    """
    Return a map of {"positive": [<examples>], "negative": [<examples>]}

    Examples:
        >>> parse_spec('''
        ... POSITIVE:
        ... ab
        ... abab
        ...
        ... NEGATIVE:
        ... ba
        ... baba
        ... ''')
        {'positive': ['ab', 'abab'], 'negative': ['ba', 'baba']}
    """
    _, sep1, spec = spec.strip().partition('POSITIVE:\n')
    positive, sep2, negative = spec.strip().partition('NEGATIVE:\n')
    if not sep1 or not sep2:
        raise ValueError(
            'Spec does not contain a POSITIVE: and NEGATIVE: sections.')
    return {'positive': positive.strip().splitlines(), 'negative': negative
        .strip().splitlines()}


def __init__(request):
    """Initialize context."""


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


@classmethod
def from_existing(cls, klass):
    """Build a new `_CivisBackend` from an existing one."""
    return cls(setup_cmd=klass.setup_cmd, from_template_id=klass.
        from_template_id, max_submit_retries=klass.max_submit_retries,
        client=klass.client, remote_backend=klass.remote_backend, **klass.
        executor_kwargs)


def one_of_k_encoding(x, allowable_set):
    """Maps inputs not in the allowable set to the last element."""
    if x not in allowable_set:
        x = allowable_set[-1]
    return list(map(lambda s: x == s, allowable_set))


def count(gen):
    """Simple function to count the number of elements returned by a generator."""
    i = 0
    for s in gen:
        i += 1
    return i


def _p_setattr(name, value):
    """Save persistent meta data

        This method should be called by subclass __setattr__ implementations
        before doing anything else.  If it returns true, then the attribute
        was handled by the base class.

        The method unghostifies the object, if necessary.
        The method records the object access, if necessary.
        """


def round_down(x, decimal_places):
    """
    Round a float down to decimal_places.

    Parameters
    ----------
    x : float
    decimal_places : int

    Returns
    -------
    rounded_float : float

    Examples
    --------
    >>> round_down(1.23456, 3)
    1.234
    >>> round_down(1.23456, 2)
    1.23
    """
    from math import floor
    d = int('1' + '0' * decimal_places)
    return floor(x * d) / d


def acquireCred(name, ttl=0, mechs=None, cred_usage=None):
    """
    Acquires GSSAPI Credentials

    This method acquires credentials for the given
    name (imported with :func:`importName`) for the desired
    mechanims, with permissions to either initiate security
    contexts, accept them, or both.

    :param name: the name object for which to get credentials
    :param int input_ttl: the requested TTL for these credentials
    :param mechs: the mechanims types with which these credentials
                  are to be used, or None for the default set
    :type mechs: [:class:`gssapi.base.types.MechType`] or None
    :param cred_usage: How these credentials are going to be used:
                       To accept a context (True), to initiate a
                       context (False), or both (None)
    :type cred_usage: bool or None
    :returns: a tuple containing the actual credentials, the mechanisms
              for which these credentials are valid, and the actual TTL
              (which may be 0)
              (i.e. (creds, [MechType], ttl))
    """


@staticmethod
def count(timeseries):
    """Extract good_count, bad_count tuple from Stackdriver Monitoring API
        response.

        Args:
            timeseries (list): List of timeseries objects.

        Returns:
            tuple: A tuple (good_event_count, bad_event_count).
        """
    good_event_count, bad_event_count = 0, 0
    for timeserie in timeseries:
        event_type = timeserie.metric.labels['event_type']
        value = timeserie.points[0].value.double_value
        if event_type == 'bad':
            bad_event_count = value
        elif event_type == 'good':
            good_event_count = value
    return good_event_count, bad_event_count


def duplicate_move(ACTION_OT_duplicate=None, TRANSFORM_OT_transform=None):
    """Make a copy of all selected keyframes and move them

    :param ACTION_OT_duplicate: Duplicate Keyframes, Make a copy of all selected keyframes
    :param TRANSFORM_OT_transform: Transform, Transform selected items by mode type
    """
    pass


@classmethod
def find(cls):
    """
        Check if system statisfy dependencies.
        """
    pass


def tidy_split(df, column, sep=' ', keep=False):
    """Split values of column and expand into new rows.

    Note
    ----
    Taken from https://stackoverflow.com/a/39946744

    Parameters
    ----------
    df : pandas.DataFrame
        Data frame with the column to split and expand.
    column : str
        Name of column to split and expand.
    sep : str
        The string used to split the column's values.
    keep : bool
        Retain the presplit value as it's own row.

    Returns
    -------
    pandas.DataFrame
        Data frame with the same columns as `df`. Rows lacking
        `column` are filtered.

    Example
    -------
    >>> df = pd.DataFrame({'col1': ['A', 'B', 'C'],
    ...                    'col2': ['d e', float('nan'), 'f']})
    >>> tidy_split(df, 'col2')
      col1 col2
    0    A    d
    0    A    e
    2    C    f

    """
    indexes = []
    new_values = []
    df = df.dropna(subset=[column])
    for i, presplit in enumerate(df[column].astype(str)):
        values = presplit.split(sep)
        if keep and len(values) > 1:
            indexes.append(i)
            new_values.append(presplit)
        for value in values:
            indexes.append(i)
            new_values.append(value)
    new_df = df.iloc[(indexes), :].copy()
    new_df[column] = new_values
    return new_df


def equalsignore(s1, s2):
    """Equals 2 string parameters is true or false without word upper or lower

    :param s1:
    :param s2:
    :return:
    """
    return s2 is None if s1 is None else s1.lower() == s2.lower()


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


@classmethod
def rewind_folder(cls, val):
    """
        Create an instance of this class set to the ``rewind_folder`` tag with
        value ``val``.

        :param RewindFolderType val:
        :rtype: EventType
        """
    return cls('rewind_folder', val)


def time_string(seconds):
    """Returns time in seconds as a string formatted HHHH:MM:SS."""
    s = int(round(seconds))
    h, s = divmod(s, 3600)
    m, s = divmod(s, 60)
    return '%4i:%02i:%02i' % (h, m, s)