@classmethod
def _do_register(cls, code, name, hash_name=None, hash_new=None):
    """Add hash function data to the registry without checks."""
    cls._func_from_name[name.replace('-', '_')] = code
    cls._func_from_name[name.replace('_', '-')] = code
    if hash_name:
        cls._func_from_hash[hash_name] = code
    cls._func_hash[code] = cls._hash(hash_name, hash_new)


def _override(schema_name, schema, overrides):
    """Override default values in the schema if necessary."""
    if schema_name in overrides:
        defaults = overrides[schema_name]
        for key in defaults:
            if key in schema['properties']:
                schema['properties'][key]['default'] = defaults[key]
            else:
                schema['properties'][key] = dict(default=defaults[key])
    return schema


def fill_coords(img, fn, color):
    """
    Fill pixels of an image with coordinates matching a filter function
    """
    for y in range(img.shape[0]):
        for x in range(img.shape[1]):
            yf = (y + 0.5) / img.shape[0]
            xf = (x + 0.5) / img.shape[1]
            if fn(xf, yf):
                img[y, x] = color
    return img


def evalUnits(unitStr):
    """
    Evaluate a unit string into ([numerators,...], [denominators,...])
    Examples:
        N m/s^2   =>  ([N, m], [s, s])
        A*s / V   =>  ([A, s], [V,])
    """
    pass


def delete():
    """Delete selected files

    """
    pass


def sequence_difference(nth, first_term, term_number):
    """Usage: Find the difference in a sequence"""
    return (nth - first_term) / (term_number - 1)


def round_to_hh_mm(ts, round_down=False):
    """ Round a timestamp to a (h, m, s) tuple of the form hh:mm:00 """
    h, m, s = ts.hour, ts.minute, ts.second
    if round_down:
        s = 0
    elif s > 30 or s == 30 and m % 2:
        s = 0
        m += 1
        if m >= 60:
            m -= 60
            h += 1
            if h >= 24:
                h -= 24
    return h, m, s


def InterpolateOne(phi, phiK, a):
    """
    Interpolation function used when there is only one phase present more degenerate
    """
    return phi[0] * phi[0] * a[0]


def i2r(interval):
    """
    Interval to ratio
    """
    return 2 ** (interval / 12.0)


def correct_gag_residue_names_messed_up_by_moe(molstruct):
    """Rename messed up GAG residue names from MOE files.

    1. Undo capitalization (e.g. `02U` --> `02u`).
    2. Remove leading `Q` (e.g. `Q42u` --> `42u`).

    """
    REP_TABLE = {'02U': '02u', '03U': '03u', '07U': '07u', '0UA': '0uA',
        '42U': '42u', '47U': '47u', '4UA': '4uA'}
    for residue in molstruct.residues():
        if residue.name is not None and residue.name[0] == 'Q':
            residue.name = residue.name[1:]
        if residue.name is not None and residue.name in REP_TABLE:
            residue.name = REP_TABLE[residue.name]
    return True


def parse_magic_word(current_project, word):
    """ parses words in format of either:
            word
        or
            project.word

        reduces to a pair of project and word.

        TODO: not beeing used currently.
    """
    project, word = word.split('.') if '.' in word else current_project, word
    return project, word


@classmethod
def from_data(cls, data, name=None, start_idx=0, stop_idx=None):
    """Construct CorrelatedStack from image stack object

        Parameters
        ----------
        data : TiffStack
            TiffStack object.
        name : str
            Plot label of the correlated stack
        start_idx : int
            Index at the first frame.
        stop_idx: int
            Index beyond the last frame.
        """
    new_correlated_stack = cls.__new__(cls)
    new_correlated_stack.src = data
    new_correlated_stack.name = name
    new_correlated_stack.start_idx = start_idx
    new_correlated_stack.stop_idx = (new_correlated_stack.src.num_frames if
        stop_idx is None else stop_idx)
    return new_correlated_stack


def p_expression_parentheses(p):
    """expression : LPAREN expression_list RPAREN
                  | LFLOOR expression_list RFLOOR
                  | LCEIL expression_list RCEIL
                  | VERT expression_list VERT
                  """
    tokenToFunc = {'\\lceil': 'ceil', '\\lfloor': 'floor', '\\vert': 'abs',
        '(': ''}
    p[0] = '%s(%s)' % (tokenToFunc[p[1]], p[2])


def import_item(name):
    """Import and return ``bar`` given the string ``foo.bar``.

    Calling ``bar = import_item("foo.bar")`` is the functional equivalent of
    executing the code ``from foo import bar``.

    Parameters
    ----------
    name : string
      The fully qualified name of the module/package being imported.

    Returns
    -------
    mod : module object
       The module that was imported.
    """
    parts = name.rsplit('.', 1)
    if len(parts) == 2:
        package, obj = parts
        module = __import__(package, fromlist=[obj])
        try:
            pak = module.__dict__[obj]
        except KeyError:
            raise ImportError('No module named %s' % obj)
        return pak
    else:
        return __import__(parts[0])


def yes_no_response(query: str, default_response: bool=True) ->bool:
    """Prompt user with a yes / no response for a given query string.

    :param query: query string
    :param default_response: default return value if user input invalid
    :return:
    """
    default_string = 'Y/n' if default_response else 'y/N'
    response = input(f'{query} [{default_string}] ').lower().strip()
    if response in ('y', 'yes'):
        return True
    elif response in ('n', 'no'):
        return False
    return default_response


def safe_check(start, end):
    """Validate existence of files and directories for a move/copy."""
    if not start.exists():
        raise SystemExit(f'{start} does not exist')
    if end.exists():
        raise SystemExit(f'{end} already exists')
    if not end.parent.is_dir():
        end.parent.mkdir(parents=True)


@classmethod
def factory(cls, global_config, **local_config):
    """Used for paste app factories in paste.deploy config files.

        Any local configuration (that is, values under the [app:APPNAME]
        section of the paste config) will be passed into the `__init__` method
        as kwargs.

        A hypothetical configuration would look like:

            [app:wadl]
            latest_version = 1.3
            paste.app_factory = karbor.api.fancy_api:Wadl.factory

        which would result in a call to the `Wadl` class as

            import karbor.api.fancy_api
            fancy_api.Wadl(latest_version='1.3')

        You could of course re-implement the `factory` method in subclasses,
        but using the kwarg passing it shouldn't be necessary.

        """
    return cls(**local_config)


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


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

        :param PaperDefaultFolderPolicyChangedType val:
        :rtype: EventType
        """
    return cls('paper_default_folder_policy_changed', val)


def _get_hover_text(df, snpname=None, genename=None, annotationname=None):
    """Format the hover text used in Manhattan and Volcano plots.
    :param (dataFrame) df: A pandas dataframe.
    :param (string) snpname: A string denoting the column name for the SNP
    names (e.g., rs number). More generally, this column could be anything
    that identifies each point being plotted. For example,
    in an Epigenomewide association study (EWAS), this could be the probe
    name or cg number. This column should be a character. This argument is
    optional, however it is necessary to specify it if you want to
    highlight points on the plot using the highlight argument in the
    figure method.
    :param (string) genename: A string denoting the column name for the
    GENE names.
    :param (string) annotationname: A string denoting the column name for
    annotations. This could be any annotation information that you
    want to include in the plot (e.g., zscore, effect size, minor allele
    frequency).
    """
    hover_text = ''
    if snpname is not None and snpname in df.columns:
        hover_text = 'SNP: ' + df[snpname].astype(str)
    if genename is not None and genename in df.columns:
        hover_text = hover_text + '
GENE: ' + df[genename].astype(str)
    if annotationname is not None and annotationname in df.columns:
        hover_text = hover_text + '
' + df[annotationname].astype(str)
    return hover_text


def _make_cache_key(url, permanent=False):
    """
    Make a unique cache key from a url
    """
    return 'WebTemplate:%s:%s' % (url, {(True): 'p', (False): 't'}[permanent])


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


@property
def registered_hooks(cls):
    """
        A generator of all registered hooks.
        """
    if not cls.abstract:
        raise TypeError(
            'registered_hooks property accessed on a non-abstract hook')
    for hook in cls._registered_hooks.values():
        yield hook


def _update_attr(attr_name, old_obj, new_obj):
    """ Update an object if necessary. Return True if updated. """
    old_value = getattr(old_obj, attr_name)
    new_value = getattr(new_obj, attr_name)
    if new_value != old_value and new_value is not None:
        setattr(old_obj, attr_name, new_value)
        return True


@staticmethod
def __populateClassesAndFunctions(infoObj, combo):
    """Populates the combo with classes and functions from the infoObj"""
    for klass in infoObj.classes:
        combo.addItem('class ' + klass.name, klass.line)
    for func in infoObj.functions:
        combo.addItem('def ' + func.name, func.line)


def open_file(filename, create=False):
    """Open the file name.  Return its handle."""
    try:
        return open(filename, 'rb+')
    except FileNotFoundError:
        if create:
            return open(filename, 'wb+')
        raise


@classmethod
def status_open(cls, number: int):
    """
        Get the status enum attribute for an earthing stick number.

        :param number: the earthing stick (1..6)
        :return: the status enum
        """
    return getattr(cls, 'status_{}_open'.format(number))


def is_reply(tweet):
    """ Assume a tweet is a reply if in_reply_to_screen_name
    or in_reply_to_status_id are not None

    """
    return tweet.get('in_reply_to_screen_name') or tweet.get(
        'in_reply_to_status_id')


def parse_host_genus(data_dict):
    """Retrieve host_genus from PhagesDB.

    :param data_dict: Dictionary of data retrieved from PhagesDB.
    :type data_dict: dict
    :returns: Host genus of the phage.
    :rtype: str
    """
    try:
        host_genus = data_dict['isolation_host']['genus']
    except:
        host_genus = ''
    return host_genus


def is_build_step(step):
    """Return true iff the given step is the "build" step."""
    return step._funcname == 'build'


def collection_disable():
    """Disable viewport drawing in the view layers

    """
    pass


def single_fscore(tp, fp, fn, beta):
    """ Computes a single F-score given all the required values """
    betasq = beta ** 2
    return (1 + betasq) * tp / ((1 + betasq) * tp + betasq * fn + fp)


def queryset_to_sql(queryset):
    """
    Transform a queryset into pretty sql that can be copy-pasted directly
    into pg-admin
    """
    import sqlparse
    from django.db import connection
    sql, sql_params = queryset.query.get_compiler(using=queryset.db).as_sql()
    with connection.cursor() as cur:
        query = cur.mogrify(sql, sql_params)
    query = sqlparse.format(query, reindent=True, keyword_case='upper')
    return query


def amean(nums):
    """Return arithmetic mean.

    The arithmetic mean is defined as

        .. math::

            \\frac{\\sum{nums}}{|nums|}

    Cf. https://en.wikipedia.org/wiki/Arithmetic_mean

    Parameters
    ----------
    nums : list
        A series of numbers

    Returns
    -------
    float
        The arithmetric mean of nums

    Examples
    --------
    >>> amean([1, 2, 3, 4])
    2.5
    >>> amean([1, 2])
    1.5
    >>> amean([0, 5, 1000])
    335.0

    .. versionadded:: 0.1.0

    """
    return sum(nums) / len(nums)


def seek(offset, whence=None):
    """Seek the file. See Python documentation for :class:`io.IOBase` for
        details.
        """


@staticmethod
def _apply_vpp_tcp(node):
    """
        Apply the VPP Unix config

        :param node: Node dictionary with cpuinfo.
        :type node: dict
        """
    active_open_sessions = node['tcp']['active_open_sessions']
    aos = int(active_open_sessions)
    passive_open_sessions = node['tcp']['passive_open_sessions']
    pos = int(passive_open_sessions)
    if aos + pos == 0:
        tcp = '\n'.join(['api-segment {', '  gid vpp', '}'])
        return tcp.rstrip('\n')
    tcp = '\n'.join(['# TCP stack-related configuration parameters',
        """# expecting {:d} client sessions, {:d} server sessions
""".
        format(aos, pos), 'heapsize 4g\n', 'api-segment {',
        '  global-size 2000M', '  api-size 1G', '}\n', 'session {',
        '  event-queue-length {:d}'.format(aos + pos),
        '  preallocated-sessions {:d}'.format(aos + pos),
        '  v4-session-table-buckets {:d}'.format((aos + pos) // 4),
        """  v4-session-table-memory 3g
"""])
    if aos > 0:
        tcp = tcp + '  v4-halfopen-table-buckets {:d}'.format((aos + pos) // 4
            ) + '\n'
        tcp = tcp + '  v4-halfopen-table-memory 3g\n'
        tcp = tcp + '  local-endpoints-table-buckets {:d}'.format((aos +
            pos) // 4) + '\n'
        tcp = tcp + '  local-endpoints-table-memory 3g\n'
    tcp = tcp + '}\n\n'
    tcp = tcp + 'tcp {\n'
    tcp = tcp + '  preallocated-connections {:d}'.format(aos + pos) + '\n'
    if aos > 0:
        tcp = tcp + '  preallocated-half-open-connections {:d}'.format(aos
            ) + '\n'
    tcp = tcp + '}\n\n'
    return tcp.rstrip('\n')


def kwargs_to_string(kwargs):
    """
    Given a set of kwargs, turns them into a string which can then be passed to a command.
    :param kwargs: kwargs from a function call.
    :return: outstr: A string, which is '' if no kwargs were given, and the kwargs in string format otherwise.
    """
    outstr = ''
    for arg in kwargs:
        outstr += ' {}={}'.format(arg, kwargs[arg])
    return outstr


def filter2query(filter):
    """
    http://docs.mongodb.org/manual/reference/operator/query/
    """
    query = {}
    filter = filter or {}
    for k, v in filter.items():
        if isinstance(v, tuple):
            operator, v = v
            mop = '$%s' % operator
            value = {mop: v}
        elif isinstance(v, list):
            value = {'$in': v}
        else:
            value = v
        query[k] = value
    """
    if keyword:
        #filter = {'description':{"$regex": keyword}}
        mongokeywordfilter = {"$or": [
            {"description": {"$regex": keyword,'$options':'i'}},
            {"title": {"$regex": keyword,'$options':'i'}}
        ]}
        query = {
            "$and": [ query, mongokeywordfilter ]
        }
    """
    return query


def assert_type(value, class_or_type_or_tuple):
    """
    Ensure the type of the value is as expected, then return the value.

    :param value: value of any type
    :param class_or_type_or_tuple: expected type
    :return: value of expected type
    """
    s = '%r must be %r, not %s.'
    if not isinstance(value, class_or_type_or_tuple):
        raise TypeError(s % (value, class_or_type_or_tuple, type(value)))
    return value


def split_dcm_ahdr(ahdr):
    """ Return the protocol meta data and the ascconv part separately
    in list of lines.

    Parameters
    ----------
    ahdr: str

    Returns
    -------
    meta: list of str

    ascconv: list of str

    References
    ----------
    https://groups.google.com/forum/#!msg/pydicom/-CmY-yK8Y7A/XaR4cUpizvgJ

    Note
    ----
    This only works for Siemens DICOM files.
    """
    parts = ahdr.split('### ASCCONV BEGIN ###')
    meta = parts[0].split('\n')
    ascconv = parts[1].split('### ASCCONV END ###')[0].split('\n')
    return meta, ascconv


def is_complete_dos(pdos):
    """Determine whether the object is a pymatgen CompleteDos object"""
    densities_fn = getattr(pdos, 'get_densities', None)
    return callable(densities_fn)


def psi_Ca_K_SO4_HMW84(T, P):
    """c-c'-a: calcium potassium sulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@classmethod
def from_dict(cls, client, soap_dict):
    """
        Alternative constructor, builds entity object from a dictionary representation of
        a SOAP response created by the SOAP client.
        """
    return cls(client=client, weight=soap_dict.get('Weight', None), length=
        soap_dict.get('Length', None), width=soap_dict.get('Width', None),
        height=soap_dict.get('Height', None), contents=soap_dict.get(
        'Contents', None), value=soap_dict.get('Value', None),
        tracking_number=soap_dict.get('TrackingNumber', None))


def is_valid_resource_representation(resource, create=False):
    """
    Checks if resource is a valid *resource object* or *resource identifier*.

    Only checks the member properties, **not** the values assigned to
    the properties.

    Args:
        resource: The resource object checked
        create: If set to ``True``, denotes the resource is part of a
            create operation, which means the ``id`` members is not required
            as it may be generated by the server.

    Returns
        bool: ``True`` if it follows the JSON API resource format.
            ``False`` otherwise.
    """
    if create:
        return True if 'type' in resource else False
    else:
        members = 'id', 'type'
        for member in members:
            if member not in resource:
                return False
        return True


def solve_matrix(A):
    """Solve a system of equations using gauss-jordan elimination."""
    n = len(A)
    for i in range(0, n):
        max_cell = abs(A[i][i])
        max_row = i
        for k in range(i + 1, n):
            if abs(A[k][i]) > max_cell:
                max_cell = abs(A[k][i])
                max_row = k
        for k in range(i, n + 1):
            tmp = A[max_row][k]
            A[max_row][k] = A[i][k]
            A[i][k] = tmp
        for k in range(i + 1, n):
            c = -A[k][i] / A[i][i]
            for j in range(i, n + 1):
                if i == j:
                    A[k][j] = 0
                else:
                    A[k][j] += c * A[i][j]
    x = [(0) for i in range(n)]
    for i in range(n - 1, -1, -1):
        x[i] = A[i][n] / A[i][i]
        for k in range(i - 1, -1, -1):
            A[k][n] -= A[k][i] * x[i]
    return x


def encode_timestamp(timestamp):
    """
    Encodes a timestamp as an ISO 8601 string.

    :param timestamp: A datetime object.
    :return: An ISO 8601 string.
    """
    return timestamp.strftime('%Y-%m-%dT%H:%M:%S.%f')


def first(t):
    """Return first item in array or None."""
    return t[0] if t else None


def conv_output_length(input_length, filter_size, stride, autopad=True,
    dilation=1):
    """Determines output length of a convolution given input length.

  Arguments:
      input_length: integer.
      filter_size: integer.
      padding: one of "same", "valid", "full", "causal"
      stride: integer.
      dilation: dilation rate, integer.

  Returns:
      The output length (integer).
  """
    if input_length is None:
        return None
    dilated_filter_size = (filter_size - 1) * dilation + 1
    if autopad:
        output_length = input_length
    else:
        output_length = input_length - dilated_filter_size + 1
    return (output_length + stride - 1) // stride


@staticmethod
def _replace_examples_in_sentence(sentence, examples):
    """
            Replaces the given examples in the given sentece

            :param string sentence: the step sentence in which to replace the examples
            :param dict examples: the examples

            :returns: the new step sentence
            :rtype: string
        """
    for key, value in examples.items():
        sentence = sentence.replace('<{0}>'.format(key), value)
    return sentence


def reconstructor(fn):
    """Decorate a method as the 'reconstructor' hook.

    Designates a method as the "reconstructor", an ``__init__``-like
    method that will be called by the ORM after the instance has been
    loaded from the database or otherwise reconstituted.

    The reconstructor will be invoked with no arguments.  Scalar
    (non-collection) database-mapped attributes of the instance will
    be available for use within the function.  Eagerly-loaded
    collections are generally not yet available and will usually only
    contain the first element.  ORM state changes made to objects at
    this stage will not be recorded for the next flush() operation, so
    the activity within a reconstructor should be conservative.

    .. seealso::

        :ref:`mapping_constructors`

        :meth:`.InstanceEvents.load`

    """
    fn.__sa_reconstructor__ = True
    return fn


def numericise(value, empty2zero=False):
    """Returns a value that depends on the input string:
        - Float if input can be converted to Float
        - Integer if input can be converted to integer
        - Zero if the input string is empty and empty2zero flag is set
        - The same input string, empty or not, otherwise.

    Executable examples:

    >>> numericise("faa")
    'faa'
    >>> numericise("3")
    3
    >>> numericise("3.1")
    3.1
    >>> numericise("", empty2zero=True)
    0
    >>> numericise("", empty2zero=False)
    ''
    >>> numericise("")
    ''
    >>> numericise(None)
    >>>
    """
    if value is not None:
        try:
            value = int(value)
        except ValueError:
            try:
                value = float(value)
            except ValueError:
                if value == '' and empty2zero:
                    value = 0
    return value


def convert_data_integer(data):
    """
    convert data to integer
    """
    if data is not None:
        return data.astype(int)
    else:
        return data


def elemwise_add(lhs=None, rhs=None, name=None, attr=None, out=None, **kwargs):
    """Adds arguments element-wise.

    The storage type of ``elemwise_add`` output depends on storage types of inputs

       - elemwise_add(row_sparse, row_sparse) = row_sparse
       - elemwise_add(csr, csr) = csr
       - elemwise_add(default, csr) = default
       - elemwise_add(csr, default) = default
       - elemwise_add(default, rsp) = default
       - elemwise_add(rsp, default) = default
       - otherwise, ``elemwise_add`` generates output with default storage

    Parameters
    ----------
    lhs : Symbol
        first input
    rhs : Symbol
        second input

    name : string, optional.
        Name of the resulting symbol.

    Returns
    -------
    Symbol
        The result symbol.
    """
    return 0,


def skin_radii_equalize():
    """Make skin radii of selected vertices equal on each axis

    """
    pass


def encode_string(v, encoding='utf-8'):
    """ Returns the given value as a Python byte string (if possible).
    """
    if isinstance(encoding, str):
        encoding = ((encoding,),) + (('windows-1252',), ('utf-8', 'ignore'))
    if isinstance(v, str):
        for e in encoding:
            try:
                return v.encode(*e)
            except:
                pass
        return v
    return bytes(v)


def source_adapter(obj, request):
    """
    Adapter for rendering a :class:`skosprovider.skos.Source` to json.

    :param skosprovider.skos.Source obj: The source to be rendered.
    :rtype: :class:`dict`
    """
    return {'citation': obj.citation, 'markup': obj.markup}


@staticmethod
def _filter_inputs(key):
    """Perform any necessary filtering of input keys for PySAM.

        Parameters
        ----------
        key : str
            SAM input key.

        Returns
        -------
        key : str
            Filtered SAM input key.
        """
    if '.' in key:
        key = key.replace('.', '_')
    if ':constant' in key and 'adjust:' in key:
        key = key.replace('adjust:', '')
    return key


def configure_configure_name():
    """This name is used as configuration key for prasticus.configure"""
    return 'configure_prasticus_configure'


def merge_overlapping_in_list(l):
    """Sorts list, merges any overlapping intervals, and also adjacent intervals. e.g.
       [0,1], [1,2] would be merge to [0,.2]."""
    i = 0
    l.sort()
    while i < len(l) - 1:
        u = l[i].union(l[i + 1])
        if u is not None:
            l[i] = u
            l.pop(i + 1)
        else:
            i += 1


def deserialize_date(string):
    """
    Deserializes string to date.

    :param string: str.
    :type string: str
    :return: date.
    :rtype: date
    """
    try:
        from dateutil.parser import parse
        return parse(string).date()
    except ImportError:
        return string


@classmethod
def get_corresponding_property(cls, entity_table, given_property, mapper):
    """
        This method returns an updated property for a given a property.
        If there is no update for the property, the given property is returned.
        """
    try:
        property_mapping = mapper[entity_table]
        try:
            return property_mapping[given_property]
        except KeyError:
            return given_property
    except KeyError:
        return given_property


def cycles2perm(n, g):
    """
    Idempotent function for converting a list of disjoint cycles
    into a permutation.
    """
    if len(g) == 0:
        return tuple(range(n))
    elif hasattr(g[0], '__iter__'):
        perm = list(range(n))
        for cyc in g:
            for i in range(len(cyc)):
                perm[cyc[i - 1]] = cyc[i]
        return tuple(perm)
    elif set(g) == set(range(n)):
        return tuple(g)
    else:
        raise ValueError('%s is not in S_%d' % (g, n))


def get(isamAppliance, check_mode=False, force=False):
    """
    Retrieve runtime component status
    """
    return isamAppliance.invoke_get('Retrieving web runtime component status',
        '/isam/runtime_components/')


def session_queued(method):
    """Apply this decorator to a method of class :class:`.HermesSnipsComponent`
    to register it as a callback to be triggered when the dialogue manager
    queues the current session.
    """
    method.session_queued = True
    return method


def bool_to_str(boolean):
    """Convert ``boolean`` to string like PHP.

    :param boolean: boolean value
    :type boolean: bool
    :return: string representation
    :rtype: str
    """
    return '1' if boolean else ''


def _parsepref_old(preffile):
    """ Parse parameter file of old type (using exec of Python commands)
    """
    pars = {}
    with open(preffile, 'r') as fp:
        for line in fp.readlines():
            line_clean = line.rstrip('\n').split('#')[0]
            if line_clean and '=' in line:
                attribute, value = line_clean.split('=')
                try:
                    value_eval = eval(value.strip())
                except NameError:
                    value_eval = value.strip()
                finally:
                    pars[attribute.strip()] = value_eval
    return pars


def defaultModel(t, alpha=3.0, beta=None):
    """Convert recall probability prior's raw parameters into a model object. 🍗

  `t` is your guess as to the half-life of any given fact, in units that you
  must be consistent with throughout your use of Ebisu.

  `alpha` and `beta` are the parameters of the Beta distribution that describe
  your beliefs about the recall probability of a fact `t` time units after that
  fact has been studied/reviewed/quizzed. If they are the same, `t` is a true
  half-life, and this is a recommended way to create a default model for all
  newly-learned facts. If `beta` is omitted, it is taken to be the same as
  `alpha`.
  """
    return alpha, beta or alpha, t


@staticmethod
def can_unpack_value(value):
    """
        Function that confirms / determines if the input data is compatible with this class.
        If so, unpack_value should be used afterwards.

        Example::

            def parse_item(self, item):
                for parser in self.get_parsers():
                    if parser.can_unpack_value(item):
                        key, source_time, value = parser.unpack_value(item)
                        self.send_datachange(key, source_time, value)

        """
    return False


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

        :param TeamMergeRequestRejectedShownToPrimaryTeamType val:
        :rtype: EventType
        """
    return cls('team_merge_request_rejected_shown_to_primary_team', val)


def activate():
    """Activate an inactive object"""


@classmethod
def from_insight_connect(cls, input_message):
    """Creates a Workflow object from Insight Connect"""
    return cls(shortOrgId=input_message.get('shortOrgId', None),
        orgProductToken=input_message.get('orgProductToken', None),
        uiHostUrl=input_message.get('uiHostUrl', None), jobId=input_message
        .get('jobId', None), stepId=input_message.get('stepId', None),
        versionId=input_message.get('versionId', None), nextStepId=
        input_message.get('nextStepId', None), nextEdgeId=input_message.get
        ('nextEdgeId', None), triggerId=input_message.get('triggerId', None
        ), jobExecutionContextId=input_message.get('jobExecutionContextId',
        None), time=input_message.get('time', None), connectionTestId=
        input_message.get('connectionTestId', None), connectionTestTimeout=
        input_message.get('connectionTestTimeout', None))


def __call__(cls, value, names=None, module=None, type=None):
    """Either returns an existing member, or creates a new enum class.

        This method is used both when an enum class is given a value to match
        to an enumeration member (i.e. Color(3)) and for the functional API
        (i.e. Color = Enum('Color', names='red green blue')).

        When used for the functional API: `module`, if set, will be stored in
        the new class' __module__ attribute; `type`, if set, will be mixed in
        as the first base class.

        Note: if `module` is not set this routine will attempt to discover the
        calling module by walking the frame stack; if this is unsuccessful
        the resulting class will not be pickleable.

        """
    if names is None:
        return cls.__new__(cls, value)
    return cls._create_(value, names, module=module, type=type)


@classmethod
def get_by_name(cls, context, name):
    """Find a node based on name and return a Node object.

        :param cls: the :class:`Node`
        :param context: Security context
        :param name: the logical name of a node.
        :returns: a :class:`Node` object.
        """
    db_node = cls.dbapi.get_node_by_name(name)
    node = cls._from_db_object(context, cls(), db_node)
    return node


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

        :param PaperExternalViewForbidType val:
        :rtype: EventType
        """
    return cls('paper_external_view_forbid', val)


def findFEATImage(overlayList, overlay):
    """Searches the given :class:`.OverlayList` to see if there is a
    :class:`.FEATImage` associated with the given ``overlay``. Returns the
    ``FEATImage`` if found, otherwise returns ``None``.
    """
    import fsl.data.featanalysis as featanalysis
    import fsl.data.featimage as featimage
    if isinstance(overlay, featimage.FEATImage):
        return overlay
    if overlay is None:
        return None
    if overlay.dataSource is None:
        return None
    featPath = featanalysis.getAnalysisDir(overlay.dataSource)
    if featPath is None:
        return None
    dataPath = featanalysis.getDataFile(featPath)
    featImage = overlayList.find(dataPath)
    return featImage


def unicode_is_ascii(u_string):
    """Determine if unicode string only contains ASCII characters.

    :param str u_string: unicode string to check. Must be unicode
        and not Python 2 `str`.
    :rtype: bool
    """
    assert isinstance(u_string, str)
    try:
        u_string.encode('ascii')
        return True
    except UnicodeEncodeError:
        return False


@classmethod
def up(cls):
    """Sample up migration code"""
    """
        SpannerDb.execute_ddl_query('''
        CREATE TABLE sample (
            id STRING(64) NOT NULL,
            address STRING(MAX),
            is_active BOOL NOT NULL,
            join_date DATE,
            modified_at TIMESTAMP,
            name STRING(100) NOT NULL,
            points INT64 NOT NULL,
        ) PRIMARY KEY (id)
        ''')

        SpannerDb.insert_data('sample',
                              ['id', 'address', 'is_active', 'name', 'points'],
                              [
                                  ('5ba641c0-1630-420a-bc77-79722bece827', 'address-1', True, 'name-1', 1000),
                                  ('a9f6ef63-882b-4d0c-a791-209506f936c0', 'address-1', True, 'name-1', 1000)
                              ])
        """


def changeWidgetOptions(pageIndex, columnIndex, widgetIndex, names=[],
    retJson=True, **kw):
    """ Change options of widget.

        @param pageIndex
        index of page the widget lies on( start from 0 )

        @param columnIndex
        index of column the widget lies on( start from 0 )

        @param widgetIndex
        index of the widget, count from top to bottom( start from 0 )

        @param names
        list contains widget options name

        @param retJson
        format return value to json format or not( default True )

        @param **kw
        widget options( default is request )

        @return
        a dict contains state of process, format like:
        {
            'success': True,
            'msg': 'Change widget options success.',
            'options': {...}
        }

        """


def xapi_to_module_vm_power_state(power_state):
    """Maps XAPI VM power states to module VM power states."""
    module_power_state_map = {'running': 'poweredon', 'halted':
        'poweredoff', 'suspended': 'suspended', 'paused': 'paused'}
    return module_power_state_map.get(power_state)


@classmethod
def delete(cls, keys, pipe=None):
    """
        Delete one or more keys from the Struct namespace.

        This is a class method and unlike the `clear` method,
        can be invoked without instantiating a Struct.

        :param keys: the names of the keys to remove from the keyspace
        :param pipe: Pipeline, NestedPipeline, or None
        :return: None
        """
    with cls._pipe(pipe) as pipe:
        core = cls.core(pipe)
        core.delete(*keys)


def Froude_densimetric(V, L, rho1, rho2, heavy=True, g=g):
    """Calculates the densimetric Froude number :math:`Fr_{den}` for velocity
    `V` geometric length `L`, heavier fluid density `rho1`, and lighter fluid
    density `rho2`. If desired, gravity can be specified as well. Depending on
    the application, this dimensionless number may be defined with the heavy
    phase or the light phase density in the numerator of the square root.
    For some applications, both need to be calculated. The default is to
    calculate with the heavy liquid ensity on top; set `heavy` to False
    to reverse this.

    .. math::
        Fr = \\frac{V}{\\sqrt{gL}} \\sqrt{\\frac{\\rho_\\text{(1 or 2)}}
        {\\rho_1 - \\rho_2}}

    Parameters
    ----------
    V : float
        Velocity of the specified phase, [m/s]
    L : float
        Characteristic length, no typical definition [m]
    rho1 : float
        Density of the heavier phase, [kg/m^3]
    rho2 : float
        Density of the lighter phase, [kg/m^3]
    heavy : bool, optional
        Whether or not the density used in the numerator is the heavy phase or
        the light phase, [-]
    g : float, optional
        Acceleration due to gravity, [m/s^2]

    Returns
    -------
    Fr_den : float
        Densimetric Froude number, [-]

    Notes
    -----
    Many alternate definitions including density ratios have been used.

    .. math::
        Fr = \\frac{\\text{Inertial Force}}{\\text{Gravity Force}}

    Where the gravity force is reduced by the relative densities of one fluid
    in another.

    Note that an Exception will be raised if rho1 > rho2, as the square root
    becomes negative.

    Examples
    --------
    >>> Froude_densimetric(1.83, L=2., rho1=800, rho2=1.2, g=9.81)
    0.4134543386272418
    >>> Froude_densimetric(1.83, L=2., rho1=800, rho2=1.2, g=9.81, heavy=False)
    0.016013017679205096

    References
    ----------
    .. [1] Hall, A, G Stobie, and R Steven. "Further Evaluation of the
       Performance of Horizontally Installed Orifice Plate and Cone
       Differential Pressure Meters with Wet Gas Flows." In International
       SouthEast Asia Hydrocarbon Flow Measurement Workshop, KualaLumpur,
       Malaysia, 2008.
    """
    if heavy:
        rho3 = rho1
    else:
        rho3 = rho2
    return V / (g * L) ** 0.5 * (rho3 / (rho1 - rho2)) ** 0.5


def _fit(nums, date_format):
    """
    Pass date as an array of form [day,month,year]
    if position is set the number must go there
    """
    n = 0
    for num in nums:
        n += 1 if num != None else 0
    date = [None, None, None]
    if n == 3:
        form = date_format
        if date_format[0] != None:
            if date_format[0] == 'D':
                form = ['D', 'M', 'Y']
            elif date_format[0] == 'M':
                form = ['M', 'D', 'Y']
            elif date_format[0] == 'Y':
                form = ['Y', 'M', 'D']
        elif date_format[1] != None:
            if date_format[1] == 'M':
                if date_format[2] == 'Y':
                    form = ['D', 'M', 'Y']
                elif date_format[2] == 'D':
                    form = ['Y', 'M', 'D']
            elif date_format[1] == 'D':
                form = ['M', 'D', 'Y']
        elif date_format[2] != None:
            if date_format[2] == 'D':
                form = ['Y', 'M', 'D']
        for i, item in enumerate(form):
            if item == 'D':
                date[0] = nums[i]
            elif item == 'M':
                date[1] = nums[i]
            elif item == 'Y':
                date[2] = nums[i]
        if form[1] == 'M':
            if nums[0] <= 31:
                date[0] = nums[0]
                date[2] = nums[2]
            elif nums[2] <= 31:
                date[0] = nums[2]
                date[2] = nums[0]
        elif form[2] == 'Y':
            if nums[1] > 12:
                date[0] = nums[1]
                date[1] = nums[0]
            elif nums[0] <= 31:
                date[0] = nums[0]
                date[1] = nums[1]
        if form[0] == form[1] == form[2] == None:
            if nums[1] > 12:
                date[0] = nums[1]
                date[1] = nums[0]
                date[2] = nums[2]
            elif nums[0] <= 31:
                date[0] = nums[0]
                date[1] = nums[1]
                date[2] = nums[2]
            else:
                date[0] = nums[2]
                date[1] = nums[1]
                date[2] = nums[0]
    elif n == 2:
        form = date_format
        if date_format[0] == 'D' or date_format[1] == 'M':
            form = ['D', 'M', None]
        elif date_format[0] == 'M' or date_format[1] == 'D':
            form = ['M', 'D', None]
        for i, item in enumerate(form):
            if item == 'D':
                date[0] = nums[i]
            elif item == 'M':
                date[1] = nums[i]
        if form[0] == form[1] == None:
            if nums[1] > 12:
                date[0] = nums[1]
                date[1] = nums[0]
            elif 31 >= nums[0]:
                date[0] = nums[0]
                date[1] = nums[1]
    if date[2] != None and date[2] < 1000:
        date[2] += 2000
    return ['date', date]


@classmethod
def close_registry_entry(cls, value):
    """Close a registry entry."""
    return False


@staticmethod
def _sanitize_response(response):
    """
        Hook to allow subclasses to clean up response data
        """
    return response.content


def _children_prot(hog_off, hog_tab, cprot_buff):
    """
    simply collect the proteins of a HOG
    """
    hog_ent = hog_tab[hog_off]
    cprot_off = hog_ent['ChildrenProtOff']
    return cprot_buff[cprot_off:cprot_off + hog_ent['ChildrenProtNum']]


def build_frame_text(parts_dict):
    """
    Make a ConceptNet 5 surfaceText out of the ConceptNet 4 assertion's
    frame and surface texts.
    """
    frame_text = parts_dict['frame_text']
    if frame_text.find('{1}') > frame_text.find('{2}'):
        frame_text = '*' + frame_text
    polarity = parts_dict['polarity']
    if polarity > 0:
        frame_text = frame_text.replace('{%}', '')
    else:
        frame_text = frame_text.replace('{%}', 'not ')
    frame_text = frame_text.replace('{1}', '[[%s]]' % parts_dict['startText']
        ).replace('{2}', '[[%s]]' % parts_dict['endText'])
    return frame_text


@classmethod
def _add_public_directory(cls, config, relative_path):
    """Add a path to the :ref:`extra_public_paths` config setting.

        The path is relative to the file calling this function.

        """
    cls._add_served_directory(config, relative_path, 'extra_public_paths')


def p_testlist_star_2(p):
    """testlist_star : testlist_star COMMA test"""
    p[0] = p[1] + [p[3]]


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def requiredIfGroup(col_name, arg, dm, df, *args):
    """
    Col_name is required if other columns of
    the group arg are present.
    """
    group_name = arg
    groups = set()
    columns = df.columns
    for col in columns:
        if col not in dm.index:
            continue
        group = dm.loc[col]['group']
        groups.add(group)
    if group_name in groups:
        if col_name in columns:
            return None
        else:
            return '{} column is required if column group {} is used'.format(
                col_name, group_name)
    return None


def t_HEX_INTEGER(t):
    """[+-]?0x[A-F0-9]+"""
    t.value = int(t.value, 16)
    return t


def module_is_package(module, pkg, level):
    """Returns whether or not the module name refers to the package."""
    if level == 0:
        return module == pkg
    elif level == 1:
        return module is None
    else:
        return False


@staticmethod
def _write_h5_dict(h5_group, variables):
    """Writes a dictionary to a HDF5 file.

        The dictionary can store strings, which are represented as HDF5
        attributes, and lists of strings, which are represented as attributes of
        HDF5 subgroups.

        :type h5_group: h5py.Group
        :param h5_group: The HD5 group that will store a dictionary of strings
                         in its attributes

        :type variables: dict
        :param variables: a dictionary that may contain strings and lists of strings
        """
    for variable, values in variables.items():
        if isinstance(values, list):
            h5_values = h5_group.require_group(variable)
            for value_id, value in enumerate(values):
                h5_values.attrs[str(value_id)] = value
        else:
            h5_group.attrs[variable] = values


def swap_axes(a, axis1, axis2):
    """Swaps two axes of an array, expanding the array if necessary."""
    shape_pad_right = max(axis1 - a.ndim + 1, axis2 - a.ndim + 1, 0)
    shape_pad_left = max(-axis1 - a.ndim, -axis2 - a.ndim, 0)
    print('TODO')


@staticmethod
def get_test_method(name, prefix=''):
    """ adjusting final test method name. """
    final_name = name.strip('_').lower()
    if name == '__eq__':
        final_name = 'equal'
    elif name == '__lt__':
        final_name = 'less'
    elif name == '__gt__':
        final_name = 'greater'
    return 'test_' + prefix.lower() + final_name


@classmethod
def is_integrity_error(cls, exception):
    """Check if given exception flags an integrity error in the DB"""
    raise NotImplementedError('Implement in subclass')


def fCO2frompHCarb(pH, CARB, K0, K1, K2):
    """Calculate CO2 fugacity from pH and carbonate ion.

    Based on CalculatefCO2frompHCarb, version 01.0, 06-12-2019, by Denis Pierrot.
    """
    H = 10.0 ** -pH
    return CARB * H ** 2 / (K0 * K1 * K2)


def in_hm2(var):
    """
    Return whether the variant was part of HapMap2
    """
    return var.INFO.get('H2')


@classmethod
def get_site_names(cls):
    """
        Get list of names of observatories for use with
        `~astropy.coordinates.EarthLocation.of_site`.

        .. note::
            When this function is called, it will first attempt to
            download site information from the astropy data server.  If it
            cannot (i.e., an internet connection is not available), it will fall
            back on the list included with astropy (which is a limited and dated
            set of sites).  If you think a site should be added, issue a pull
            request to the
            `astropy-data repository <https://github.com/astropy/astropy-data>`_ .

        Returns
        -------
        names : list of str
            List of valid observatory names

        See Also
        --------
        of_site : Gets the actual location object for one of the sites names
                  this returns.
        """
    return cls._get_site_registry().names


def _older_than(number, unit):
    """
    Returns a query item matching messages older than a time period.

    Args:
        number (int): The number of units of time of the period.
        unit (str): The unit of time: "day", "month", or "year".

    Returns:
        The query string.

    """
    return f'older_than:{number}{unit[0]}'


def change_chrom_names(chrom):
    """
    Changes UCSC chromosome names to ensembl chromosome names
    and vice versa.

    >>> change_chrom_names("chr1")
    '1'
    >>> change_chrom_names("1")
    'chr1'
    """
    if chrom.startswith('chr'):
        chrom = chrom[3:]
    else:
        chrom = 'chr' + chrom
    return chrom


def try_parse(l):
    """
    Tries to TEST log messages. Returns 'pass' or 'fail' if `l` is a TEST log
    message or '' (an empty string) if it failed to parse.
    """
    try:
        test = l.split('TEST: ')[1]
        result = test.split(' ', 2)[0].lstrip('<').rstrip('>')
    except IndexError:
        result = ''
    return result


def _zbc_to_hgvs(i):
    """Convert zero-based coordinate to hgvs (1 based, missing zero)"""
    if i >= 0:
        i += 1
    return i


def _sanitize_path(path):
    """Remove path components which would allow traversing up a directory tree from a base path.

    Note: This method is currently very basic and should be expanded.
    """
    return path.lstrip('/.')


def pack_ipv4(ipv4address):
    """
    Packs an IPv4 address.
    """
    yield ipv4address.packed


@classmethod
def remove(cls, pid):
    """Remove a pool, closing all connections

        :param str pid: The pool ID

        """
    with cls._lock:
        cls._ensure_pool_exists(pid)
        cls._pools[pid].close()
        del cls._pools[pid]


@staticmethod
def normalize_cell(cell, col_width):
    """
        Given the text for a cell create a fixed length string to fit a column with width col_width.
        This is mostly an internal helper function  used by RSTTable.render but can be useful
        otherwise as well.

        :param cell: String with the text content for the cell
        :param col_width: Target width for the column
        :return: cell text string padded with spaces to fit the column width
        """
    return ' ' + cell + (col_width - len(cell) + 1) * ' '


def countdown_iter(start_at, decr=1):
    """Generator that decrements after each generation until <= zero.

    NOTE(harlowja): we can likely remove this when we can use an
    ``itertools.count`` that takes a step (on py2.6 which we still support
    that step parameter does **not** exist and therefore can't be used).
    """
    if decr <= 0:
        raise ValueError(
            'Decrement value must be greater than zero and not %s' % decr)
    while start_at > 0:
        yield start_at
        start_at -= decr


def invoke_sync_timeout(executor, timeout, result_fn, call_fn, *args):
    """
    invoke synchronously with timeout.  This method uses the given executor
    to submit call_fn/*args and then after result has been returned (with given timeout)
    the result_fn is optionally called with the returned result, executor, timeout, call_fn
    must not be None.
    """
    if not executor:
        raise Exception('cannot submit call_fn={0} without executor'.format
            (call_fn))
    call_result = executor.submit(call_fn, *args).result(timeout)
    if result_fn:
        return result_fn(call_result)
    return call_result


def p_small_stmt_2(p):
    """small_stmt : print_stmt"""
    p[0] = p[1]


def _check_mods(A, B, AB, S):
    """Check the 'same' graph for differences in attributes """
    for nid, attrs in S.get_nodes().iteritems():
        if attrs != A.get_node(nid) or attrs != B.get_node(nid):
            AB.set_node_attribute(nid, 'diffstatus', 'modified')
    for eid, attrs in S.get_edges().iteritems():
        if attrs != A.get_edge(eid) or attrs != B.get_edge(eid):
            AB.set_edge_attribute(eid, 'diffstatus', 'modified')


def _prepare_hunk(hunk):
    """Drop all information but the username and patch"""
    cleanhunk = []
    for line in hunk.splitlines():
        if line.startswith(b'# User') or not line.startswith(b'#'):
            if line.startswith(b'@@'):
                line = b'@@\n'
            cleanhunk.append(line)
    return cleanhunk


def globToWordIds(pattern):
    """Return a sequence of ids of words matching the pattern.

        The argument should be a single word using globbing syntax,
        e.g. 'foo*' meaning anything starting with 'foo'.

        Return the wids for all words in the lexicon that match the
        pattern.
        """


def lookup_object(key, lookup_type):
    """Returns a lookup button to inspect a selected object"""
    result = {'key': 'lookup_' + key, 'type': 'template', 'template':
        'Edit'}
    return result


@staticmethod
def set_root_namespace(context, node):
    """ Sets root namespace into context from node text"""
    context.root_namespace = node.text


def loadtwocol(infile):
    """
    load two columns file,
    save to a dict,
    with the first as keys the second as values
    """
    kvdict = {}
    with open(infile) as f:
        for nline, line in enumerate(f):
            line = line.strip()
            if line:
                k, v = line.split('\t')
                kvdict[k] = v
    return kvdict


def publish(service, nodeIdentifier, items=[]):
    """
        Publish to a node.

        Node that the C{items} parameter is optional, because so-called
        transient, notification-only nodes do not use items and publish
        actions only signify a change in some resource.

        @param service: The publish-subscribe service entity.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: Identifier of the node to publish to.
        @type nodeIdentifier: C{unicode}
        @param items: List of item elements.
        @type items: C{list} of L{Item}
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


@classmethod
def from_values(cls, p):
    """
        Return the shape of the moments for a fixed value.
        """
    return cls()


def mute_string(text):
    """Replace contents with 'xxx' to prevent syntax matching.

    >>> mute_string('"abc"')
    '"xxx"'
    >>> mute_string("'''abc'''")
    "'''xxx'''"
    >>> mute_string("r'abc'")
    "r'xxx'"
    """
    start = text.index(text[-1]) + 1
    end = len(text) - 1
    if text[-3:] in ('"""', "'''"):
        start += 2
        end -= 2
    return text[:start] + 'x' * (end - start) + text[end:]


@classmethod
def from_connections(cls, connections):
    """
        Alternate constructor accepting `.Connection` objects.

        .. versionadded:: 2.0
        """
    group = cls()
    group.extend(connections)
    return group


def _multi_override(flag, arg_val_list):
    """Return only the last argument specified for a flag"""
    return arg_val_list[-1]


def lif_linear_voltage_update(v_cur, v_rest, v_in, alpha_v, v_decay, dt,
    refrac_counts):
    """Calculate change in cell's voltage based on a linear relation between current and incoming voltage, with decay.

    Voltage updates are performed according to the following formula:

    .. math::

        voltage_{t+1} = rest_{t} + (voltage_{t} - rest_{t}) * decay + alpha * incoming_{t}

    :param v_cur: Current voltages
    :param v_rest: Resting voltages
    :param v_in: Incoming voltages
    :param alpha_v: Incoming voltage scaling factor
    :param v_decay: Voltage decay factor, should be < 1
    :param dt: Duration of single timestep
    :param refrac_counts: Number of timesteps left in refractory state for each :class:`Neuron`

    :return: New voltages
    """
    v_delta = (v_cur - v_rest) * v_decay + alpha_v * v_in
    non_refrac = refrac_counts == 0
    v_cur = v_rest + v_delta * non_refrac.to(v_delta.dtype)
    return v_cur


def strip_regex_metachars(pattern):
    """Strip ^ and $ from pattern begining and end.

    According to http://www.w3.org/TR/xmlschema-0/#regexAppendix XMLSchema
    expression language does not contain the metacharacters ^ and $.

    :returns: stripped pattern string

    """
    start = 0
    till = len(pattern)
    if pattern.startswith('^'):
        start = 1
    if pattern.endswith('$'):
        till -= 1
    return pattern[start:till]


def assert_not_null(attribute, value):
    """Asserts that the given object is non-null and returns it.

    :param attribute: Object to assert on
    :param value: Field name to display in exception message if null
    :return: Object if non null
    :raises: ValueError if object is null
    """
    if not attribute:
        raise ValueError('{} is null'.format(value))
    return attribute


def wait_for_updates_ex(vim, version, collector=None, max_wait=85,
    max_update_count=-1):
    """Polling mechanism for property collection

        args:
        :param vim: Vim object
        :param version: version string
        :param collector: PropertyCollector MOR
        :param max_wait: Max time in seconds before the call returns
                       (Default set to 85 as 90 is the http socket timeout)
        :param max_update_count: Max num of ObjectUpdates returned
                               in a single call. Not set if <= 0
    """
    client_factory = vim.client.factory
    waitopts = client_factory.create('ns0:WaitOptions')
    waitopts.maxWaitSeconds = max_wait
    if max_update_count > 0:
        waitopts.maxObjectUpdates = max_update_count
    if not collector:
        collector = vim.service_content.propertyCollector
    return vim.WaitForUpdatesEx(collector, version=version, options=waitopts)


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 truncate_seq_pair(tokens_a, tokens_b, max_num_tokens, rng):
    """Truncates a pair of sequences to a maximum sequence length."""
    while True:
        total_length = len(tokens_a) + len(tokens_b)
        if total_length <= max_num_tokens:
            break
        trunc_tokens = tokens_a if len(tokens_a) > len(tokens_b) else tokens_b
        assert len(trunc_tokens) >= 1
        if rng.random() < 0.5:
            del trunc_tokens[0]
        else:
            trunc_tokens.pop()


def wrap_state_dynamic(context, config_state, f, *args, **kwargs):
    """ Used internally by comp_config_dynamic() """
    config_state.restore()
    return f(context, *args, **kwargs)


def bone_primitive_add(name: str='Bone'):
    """Add a new bone located at the 3D-Cursor

    :param name: Name, Name of the newly created bone
    :type name: str
    """
    pass


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def save_obj(obj, file_name):
    """
    将对象持久化到本地, 方便直接调试
    :param obj:
    :param file_name:
    :return:
    """
    try:
        import cPickle as pickle
    except ImportError:
        import pickle
    pickle.dump(obj, open(file_name, 'w'))


@classmethod
def rotated(cls, other, angle, type_='radians'):
    """Returns a copy of a rotated vector"""
    vector = other.copy()
    vector.rotate(angle, type_)
    return vector


def abs_to_rel(target: str, namespace: str):
    """Convert absolute name relative to namespace

    number of dots: nslen - shared + 1
    number of names: tglen - shared

    >>> tg = "aaa.bbb.ddd"
    >>> ns = "aaa.bbb.ccc"
    >>> abs_to_rel(tg, ns)
    '..ddd'
    >>> tg == rel_to_abs(abs_to_rel(tg, ns), ns)
    True

    >>> tg = "aaa.bbb"
    >>> ns = "aaa.bbb.ccc"
    >>> abs_to_rel(tg, ns)
    '..'
    >>> tg == rel_to_abs(abs_to_rel(tg, ns), ns)
    True

    >>> tg = "aaa.bbb.ddd"
    >>> ns = "aaa.bbb"
    >>> abs_to_rel(tg, ns)
    '.ddd'
    >>> tg == rel_to_abs(abs_to_rel(tg, ns), ns)
    True

    >>> tg = "eee.fff"
    >>> ns = "aaa"
    >>> abs_to_rel(tg, ns)
    '..eee.fff'
    >>> tg == rel_to_abs(abs_to_rel(tg, ns), ns)
    True

    >>> tg = "aaa"
    >>> ns = "aaa.bbb.ccc.ddd"
    >>> abs_to_rel(tg, ns)
    '....'
    >>> tg == rel_to_abs(abs_to_rel(tg, ns), ns)
    True

    >>> tg = "ddd"
    >>> ns = "aaa.bbb.ccc"
    >>> abs_to_rel(tg, ns)
    '....ddd'
    >>> tg == rel_to_abs(abs_to_rel(tg, ns), ns)
    True
    """
    tg = target.split('.')
    ns = namespace.split('.')
    tglen = len(tg)
    nslen = len(ns)
    shared = 0
    while shared < min(tglen, nslen) and tg[shared] == ns[shared]:
        shared += 1
    dots = nslen - shared + 1
    names = tglen - shared
    return '.' * dots + '.'.join(tg[tglen - names:])


@classmethod
def unionIntervals(cls, intervals):
    """returns the smallest interval containing all intervals"""
    inter = cls(intervals[0].first, intervals[0].last)
    for i in intervals[1:]:
        inter = cls.union(inter, i)
    return inter


def readableInputHistory(inputHistory, names):
    """
    Given an inputHistory and a set of actions, names, as a NamedList, produces
    a human readable version of the inputHistory.
    """
    history = []
    for key, clock in inputHistory:
        if key in names:
            i = names.values.index(key)
            key = names.names[i]
        history.append((key, clock))
    return history


def _get_ps_strategy(job_name, ps_specs):
    """ Returns the param server strategy to use """
    if job_name != 'learner' or len(ps_specs) <= 1:
        return None
    from diplomacy_research.utils.tensorflow import GreedyLoadBalancingStrategy, byte_size_load_fn
    return GreedyLoadBalancingStrategy(num_tasks=len(ps_specs), load_fn=
        byte_size_load_fn)


def constraints_factory():
    """
        Creates a constraints factory for the type of query that is being built.
        This should be overridden by all derived query builders.

        Raises:
            NotImplementedError: This should be overridden by derived query builders.
        Returns:
            An appropriate `pygw.query.query_constraints_factory.QueryConstraintsFactory` for the query type.
        """
    raise NotImplementedError


def _transform_positioning(ha, va):
    """Converts matplotlib positioning to pgf node positioning.
    Not quite accurate but the results are equivalent more or less."""
    if ha == 'center' and va == 'center':
        return None
    ha_mpl_to_tikz = {'right': 'east', 'left': 'west', 'center': ''}
    va_mpl_to_tikz = {'top': 'north', 'bottom': 'south', 'center': '',
        'baseline': 'base'}
    return 'anchor={} {}'.format(va_mpl_to_tikz[va], ha_mpl_to_tikz[ha]).strip(
        )


def by_chrom(x):
    """
    Sort by chromosomes
    """
    chrom = x
    if x.startswith('chr'):
        chrom = chrom.strip('chr')
    try:
        chrom = int(chrom)
    except ValueError as e:
        pass
    return chrom


def _warning(msg, *a, **kwargs):
    """Improve the printing of user warnings."""
    return str(msg) + '\n'


@classmethod
def fromChdict(cls, master, chdict):
    """
        Class method to create a L{Change} from a dictionary as returned
        by L{ChangesConnectorComponent.getChange}.

        @param master: build master instance
        @param ssdict: change dictionary

        @returns: L{Change} via Deferred
        """
    cache = master.caches.get_cache('Changes', cls._make_ch)
    return cache.get(chdict['changeid'], chdict=chdict, master=master)


def get_requires_for_build_wheel(config_settings=None):
    """
    Returns an additional list of requirements for building, as PEP508 strings,
    above and beyond those specified in the pyproject.toml file.

    This implementation is optional. At the moment it only returns an empty list,
    which would be the same as if not define. So this is just for completeness
    for future implementation.
    """
    return []


def first_mismatch(str1, str2):
    """
    Returns the position of the first mismatch between 2 strings.

    :param str1: The first string
    :param str2: The second string
    :return: Position of the first mismatch else -1 if no mismatches

    >>> first_mismatch('abc', 'def')
    0
    >>> first_mismatch('abc', 'abe')
    2
    >>> first_mismatch('abc', 'abc')
    -1
    >>> first_mismatch('abc', 'abcde')
    -1
    """
    for i, j in enumerate(zip(str1, str2)):
        if j[0] != j[1]:
            return i
    else:
        return -1


def factor(n):
    """
    Returns a list of primes (excluding 1) which, when multiplied together,
    equal @n.
    NOTE: This is not the same as factors() below, which returns every whole
    number that can divide into @n evenly.
    NOTE: If @n is prime, this function returns an empty list.

    >>> factor(5)
    []
    >>> factor(34)
    [2, 17]
    >>> factor(132)
    [2, 2, 3, 11]

    AUTHORS:
    v1.0.4+             --> pydsigner
    """
    ceil = n // 2 + 1
    factors = []
    i = 2
    while i < ceil:
        nn, rem = divmod(n, i)
        if rem:
            i += 1
        else:
            n = nn
            factors.append(i)
    return factors


@classmethod
def different_attributes(cls, old, new):
    """
        Backwards-compat comparison that ignores orm. on the RHS and not the left
        and which knows django.db.models.fields.CharField = models.CharField.
        Has a whole load of tests in tests/autodetection.py.
        """
    if not cls.is_triple(old) or not cls.is_triple(new):
        return old != new
    old_field, old_pos, old_kwd = old
    new_field, new_pos, new_kwd = new
    old_pos, new_pos = old_pos[:], new_pos[:]
    old_kwd = dict(old_kwd.items())
    new_kwd = dict(new_kwd.items())
    if 'unique' in old_kwd:
        del old_kwd['unique']
    if 'unique' in new_kwd:
        del new_kwd['unique']
    if old_field != new_field:
        if old_field.startswith('models.') and (new_field.startswith(
            'django.db.models') or new_field.startswith('django.contrib.gis')):
            if old_field.split('.')[-1] != new_field.split('.')[-1]:
                return True
            else:
                old_field = new_field = ''
    if (old_pos and 'to' in new_kwd) and ('orm' in new_kwd['to'] and 'orm'
         not in old_pos[0]):
        try:
            if old_pos[0] != new_kwd['to'].split("'")[1].split('.')[1]:
                return True
        except IndexError:
            pass
        old_pos = old_pos[1:]
        del new_kwd['to']
    return old_field != new_field or old_pos != new_pos or old_kwd != new_kwd


def worst_level(level1, level2):
    """Given two int levels, return the larger.

    Args:
        level1 (int): exit code 1.
        level2 (int): exit code 2.

    Returns:
        int: the larger of the two levels.

    """
    return level1 if level1 > level2 else level2


@classmethod
def on_controller_mapped(cls, controller):
    """
    Callback function that is triggered, when the mapping of a controller was found

    :param controller:              the controller that should be mapped
    :type controller:               steuer.Controller
    """
    print('EVENT:' + 'controller {0}:{1} mapped'.format(controller.number,
        controller.name))


@classmethod
def send_cloud_message(cls, business_id=None, store_id=None, class_name=
    None, package_name=None, device_id=None, serial_number=None, data='{}',
    collapse_key=None, ttl=900):
    """
        Send a message from the cloud to your application running at a Poynt terminal.

        Keyword arguments:
        business_id (str): the business ID
        store_id (str): the store ID
        class_name (str): the class name of the receiver in your app
        package_name (str): the package name of your app
        device_id (str): the device ID
        serial_number (str): the serial number
        data (str, optional): the data to send. defaults to {}
        collapse_key (str, optional): dedupe messages on this key
        ttl (int, optional): how long until the cloud message expires. defaults
                             to 900 seconds
        """
    message = {'businessId': business_id, 'storeId': store_id, 'deviceId':
        device_id, 'recipient': {'className': class_name, 'packageName':
        package_name}}
    if serial_number is not None:
        message['serialNum'] = serial_number
    if collapse_key is not None:
        message['collapseKey'] = collapse_key
    if ttl is not None:
        message['ttl'] = ttl
    if data is not None:
        message['data'] = data
    return cls.send_raw_cloud_message(message)


def erf(data=None, out=None, name=None, **kwargs):
    """Returns element-wise gauss error function of the input.

    Example::

       erf([0, -1., 10.]) = [0., -0.8427, 1.]

    Defined in src/operator/tensor/elemwise_unary_op_basic.cc:L886

    Parameters
    ----------
    data : NDArray
        The input array.

    out : NDArray, optional
        The output NDArray to hold the result.

    Returns
    -------
    out : NDArray or list of NDArrays
        The output of this function.
    """
    return 0,


@staticmethod
def check_def(api_def):
    """
			Vérifie que la définition soit correcte.
			Lance une erreur spécifique le cas contraire.
		"""
    if ('url' not in api_def or 'name' not in api_def or 'requests' not in
        api_def):
        raise ValueError(
            '"url" and/or "requests" key missing in API definition')


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

    Uses the starmap() function from itertools in Python's standard library.

    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
        ...
        >>> starmap(add, [(1, 2, 3), (10, 20, 30)])
        [6, 60]

    References:
        - https://docs.python.org/3/library/itertools.html#itertools.starmap
    """
    from itertools import starmap as _starmap
    iterator = _starmap(function, argument_list)
    result_list = list(iterator)
    return result_list


def text(buffer, string, font, x0=0, y0=0, color=(255, 255, 255), bgcolor=(
    0, 0, 0), colors=None):
    """Simultate write on an oled display.

    Parameters
    ----------
    buffer : oled handler object
        The first parameter.
    string : str
        The message to write.
    font : str
        sss
    x0 : int
        X possition.
    y0 : int
        Y possition.
    color : tuple
        h
    bgcolor : tuple
        h
    colors : tuple
        h

    """
    if colors is None:
        colors = color, color, bgcolor, bgcolor
    x = x0
    for c in string:
        if not ord(c) in font.keys():
            c = '?'
        row = y0
        _w, *_font = font[ord(c)]
        for byte in _font:
            unsalted = byte
            for col in range(x, x + _w):
                color = colors[unsalted & 3]
                if color is not None:
                    buffer.pixel(col, row, color)
                unsalted >>= 2
            row += 1
        x += _w


def mult_by_scalar3(vector, scalar):
    """Return 3-dimension ``vector`` multiplied by ``scalar``."""
    return vector[0] * scalar, vector[1] * scalar, vector[2] * scalar


def extract_docstring(script_text):
    """ Extract the docstring from an example Enaml script. """
    return script_text.split('"""')[1]


@staticmethod
def _get_chassis_load_by_prios(chassis_info):
    """Retrieve the amount of ports by priorities hosted in the chassis.

        @param   chassis_info: list of (port, prio) hosted by this chassis
        @type    chassis_info: []
        @return: A list of (prio, number_of_ports) tuples.
        """
    chassis_load = {}
    for lrp, prio in chassis_info:
        chassis_load[prio] = chassis_load.get(prio, 0) + 1
    return chassis_load.items()


def calc_damped_vs_kramer_1996(vs, xi):
    """
    Calculates the damped shear wave velocity
    Ref: Eq 7.9 from Kramer (1996)

    :param vs:
    :param xi:
    :return:
    """
    return vs * (1.0 + 1.0j * xi)


def toNumber(str, default=None):
    """toNumber(str[, default]) -> integer | float | default

    Converts the given string to a numeric value.  The string may be a
    hexadecimal, integer, or floating number.  If string could not be
    converted, default (None) is returned.

    Examples:

    >>> n = toNumber("0x2A")
    >>> assert type(n) is int and n == 42

    >>> n = toNumber("42")
    >>> assert type(n) is int and n == 42

    >>> n = toNumber("42.0")
    >>> assert type(n) is float and n == 42.0

    >>> n = toNumber("Foo", 42)
    >>> assert type(n) is int and n == 42

    >>> n = toNumber("Foo")
    >>> assert n is None
    """
    value = default
    try:
        if str.startswith('0x'):
            value = int(str, 16)
        else:
            try:
                value = int(str)
            except ValueError:
                value = float(str)
    except ValueError:
        pass
    return value


def _default_key_normalizer(key_class, request_context):
    """
    Create a pool key out of a request context dictionary.

    According to RFC 3986, both the scheme and host are case-insensitive.
    Therefore, this function normalizes both before constructing the pool
    key for an HTTPS request. If you wish to change this behaviour, provide
    alternate callables to ``key_fn_by_scheme``.

    :param key_class:
        The class to use when constructing the key. This should be a namedtuple
        with the ``scheme`` and ``host`` keys at a minimum.
    :type  key_class: namedtuple
    :param request_context:
        A dictionary-like object that contain the context for a request.
    :type  request_context: dict

    :return: A namedtuple that can be used as a connection pool key.
    :rtype:  PoolKey
    """
    context = request_context.copy()
    context['scheme'] = context['scheme'].lower()
    context['host'] = context['host'].lower()
    for key in ('headers', '_proxy_headers', '_socks_options'):
        if key in context and context[key] is not None:
            context[key] = frozenset(context[key].items())
    socket_opts = context.get('socket_options')
    if socket_opts is not None:
        context['socket_options'] = tuple(socket_opts)
    for key in list(context.keys()):
        context['key_' + key] = context.pop(key)
    for field in key_class._fields:
        if field not in context:
            context[field] = None
    return key_class(**context)


def main():
    """Called when module is '__main__', after successful bootstrap."""


def auto_register(obj):
    """
    registers the mod when the files is loaded

    example:
    >>> from twitchbot import Message
    >>>
    >>> @auto_register
    >>> class MyMod(Mod):
    >>>     async def on_privmsg_received(self, msg: Message):
    >>>         print(f'MyMod got the message: {msg.content}')

    :param obj:
    :return:
    """
    from ..modloader import Mod, register_mod
    if issubclass(obj, Mod):
        register_mod(obj())
    elif isinstance(obj, Mod):
        register_mod(obj)
    else:
        raise ValueError(
            f'Unsupported auto_register class: {obj} type: {type(obj)}')
    return obj


def doppler_resolution(band_width, start_freq_const=77, ramp_end_time=62,
    idle_time_const=100, num_loops_per_frame=128, num_tx_antennas=3):
    """Calculate the doppler resolution for the given radar configuration.

    Args:
        start_freq_const (int): Frequency chirp starting point.
        ramp_end_time (int): Frequency chirp end point.
        idle_time_const (int): Idle time between chirps.
        band_width (float): Radar config bandwidth.
        num_loops_per_frame (int): The number of loops in each frame.
        num_tx_antennas (int): The number of transmitting antennas (tx) on the radar.

    Returns:
        doppler_resolution (float): The doppler resolution for the given radar configuration.

    """
    light_speed_meter_per_sec = 299792458
    center_frequency = start_freq_const * 1000000000.0 + band_width / 2
    chirp_interval = (ramp_end_time + idle_time_const) * 1e-06
    doppler_resolution = light_speed_meter_per_sec / (2 *
        num_loops_per_frame * num_tx_antennas * center_frequency *
        chirp_interval)
    return doppler_resolution


@staticmethod
def check_data(data=None):
    """
        Empty for fabioimage but may be populated by others classes,
        especially for format accepting only integers

        :param data: array like
        :return: numpy array or None
        """
    if data is None:
        return None
    else:
        return data


def OPTIMIZE(writer, segments):
    """This policy merges all existing segments.
    """
    from cylleneus.engine.reading import SegmentReader
    for seg in segments:
        reader = SegmentReader(writer.storage, writer.schema, seg)
        writer.add_reader(reader)
        reader.close()
    return []


def load_handlers(controllers):
    """
    Load the controllers handlers and assign them to the instance
    """
    handlers = {}
    for controller in controllers:
        for handler in controller.build_controller():
            if handler.type in handlers:
                handlers[handler.type].append(handler)
            else:
                handlers.setdefault(handler.type, [])
                handlers[handler.type].append(handler)
    return handlers


def pytest_addoption(parser):
    """Add options for interaction with Splunk this allows the tool to work in two modes
    1) docker mode which is typically used by developers on their workstation
        manages a single instance of splunk
    2) external interacts with a single instance of splunk that is lifecycle managed
        by another process such as a ci/cd pipeline
    """
    group = parser.getgroup('splunk-addon')
    group.addoption('--splunk-app', action='store', dest='splunk_app',
        default='package', help=
        'Path to Splunk app package. The package should have the configuration files in the default folder.'
        )
    group.addoption('--splunk-type', action='store', dest='splunk_type',
        default='external', help=
        'Type of the Splunk instance. supports external & docker as a value. Default is external.'
        )
    group.addoption('--splunk-host', action='store', dest='splunk_host',
        default='127.0.0.1', help=
        'Address of the Splunk Server. Do not provide http scheme in the host. default is 127.0.0.1'
        )
    group.addoption('--splunk-hec-scheme', action='store', dest=
        'splunk_hec_scheme', default='https', help=
        'Splunk HTTP event collector port. default is https.')
    group.addoption('--splunk-hec-port', action='store', dest='splunk_hec',
        default='8088', help=
        'Splunk HTTP event collector port. default is 8088.')
    group.addoption('--splunk-hec-token', action='store', dest=
        'splunk_hec_token', default='9b741d03-43e9-4164-908b-e09102327d22',
        help=
        'Splunk HTTP event collector token. default is "9b741d03-43e9-4164-908b-e09102327d22".'
        )
    group.addoption('--splunk-port', action='store', dest='splunkd_port',
        default='8089', help='Splunk Management port. default is 8089.')
    group.addoption('--splunk-s2s-port', action='store', dest='splunk_s2s',
        default='9997', help='Splunk s2s port. default is 9997.')
    group.addoption('--splunk-s2s-scheme', action='store', dest=
        'splunk_s2s_scheme', default='tcp', help=
        'Splunk s2s scheme. tls|tcp default is tcp.')
    group.addoption('--splunkweb-port', action='store', dest='splunk_web',
        default='8000', help='Splunk web port. default is 8000.')
    group.addoption('--splunk-user', action='store', dest='splunk_user',
        default='admin', help=
        'Splunk login user. The user should have search capabilities.')
    group.addoption('--splunk-password', action='store', dest=
        'splunk_password', default='Chang3d!', help=
        'Password of the Splunk user')
    group.addoption('--splunk-version', action='store', dest=
        'splunk_version', default='latest', help=
        'Splunk version to spin up with docker while splunk-type  is set to docker. Examples,  1) latest: latest Splunk Enterprise tagged by the https://github.com/splunk/docker-splunk 2) 8.0.0: GA release of 8.0.0.'
        )
    group.addoption('--splunk-dm-path', action='store', dest=
        'splunk_dm_path', help=
        'Path to the datamodels directoryRelative or absolute path can be provided.Json files are expected in the directory.Json files must follow the schema mentioned in DatamodelSchema.jsonpytest-splunk-addon\\pytest_splunk_addon\\standard_lib\\cim_tests\\DatamodelSchema.json'
        )


def make_paths_relative():
    """Make all paths to external files relative to current .blend

    """
    pass


def prob_acc(true_class=0, pred_prob=0.2):
    """
    return classification prediction accuracy

    :param true_class: integer containing true label 0 or 1
    :param pred_prob: float - predicted probability
    :return scalar - prediction accuracy
    :rtype float
    """
    return true_class * (1 - pred_prob) + (1 - true_class) * pred_prob


@staticmethod
def _validate(cls):
    """
        Hook for providing registry class level validation
        """
    return


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

        :param LegalHoldsExportAHoldDetails val:
        :rtype: EventDetails
        """
    return cls('legal_holds_export_a_hold_details', val)


def is_dictionary(obj):
    """Helper method for testing if the object is a dictionary.

    >>> is_dictionary({'key':'value'})
    True

    """
    return type(obj) is dict


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

        :param CreateTeamInviteLinkType val:
        :rtype: EventType
        """
    return cls('create_team_invite_link', val)


def square(target, pore_diameter='pore.diameter'):
    """
    Calculate pore volume from diameter assuming a cubic pore body

    Parameters
    ----------
    target : OpenPNM Object
        The object which this model is associated with. This controls
        the length of the calculated array, and also provides access to other
        necessary geometric properties.

    pore_diameter : string
        The dictionary key of the pore diameter values

    """
    return target[pore_diameter] ** 2


def handle_existing_construct(source, target):
    """Moves the item identifiers and reifier from `source` to
    `target`.

    If the `source` is reifier, `target`'s reifier is set to the
    source reifier unless `target_reifier` is not None. If `source`
    and `target` are reified, the reifiers are merged.

    :param source: the source Topic Maps construct
    :type source: `Construct`
    :param target: the target Topic Maps construct
    :type target: `Construct`
    :param target_reifier: the target's reifier
    :type target_reifier: `Topic` or None

    """
    for iid in source.get_item_identifiers():
        source.item_identifiers.remove(iid)
        target.item_identifiers.add(iid)
    source_reifier = source.get_reifier()
    if source_reifier is None:
        return
    target_reifier = target.get_reifier()
    if target_reifier is not None:
        source.set_reifier(None)
        target_reifier.merge_in(source_reifier)
    else:
        source.set_reifier(None)
        target.set_reifier(source_reifier)


def mil_to_gon(angle):
    """Convert degrees in mil (NATO) format to grade (gon) format."""
    return angle * 400 / 6400


def generateFinishedBuilds(branches=None, num_builds=None, max_buildnum=
    None, finished_before=None, max_search=200):
    """Return a generator that will produce IBuildStatus objects each
        time you invoke its .next() method, starting with the most recent
        finished build, then the previous build, and so on back to the oldest
        build available.

        @param branches: this is a list of branch names, and the generator
                         will only produce builds that involve the given
                         branches. If the list is empty, the generator will
                         produce all builds regardless of what branch they
                         used.

        @param num_builds: if provided, the generator will stop after
                           providing this many builds. The default of None
                           means to produce as many builds as possible.

        @param max_buildnum: if provided, the generator will start by
                             providing the build with this number, or the
                             highest-numbered preceding build (i.e. the
                             generator will not produce any build numbered
                             *higher* than max_buildnum). The default of None
                             means to start with the most recent finished
                             build. -1 means the same as None. -2 means to
                             start with the next-most-recent completed build,
                             etc.

        @type finished_before: int: a timestamp, seconds since the epoch
        @param finished_before: if provided, do not produce any builds that
                                finished after the given timestamp.

        @type max_search: int
        @param max_search: this method may have to examine a lot of builds
                           to find some that match the search parameters,
                           especially if there aren't any matching builds.
                           This argument imposes a hard limit on the number
                           of builds that will be examined.
        """


def p_default_declaration_(t):
    """default_declaration : DEFAULT COLON declaration SEMI"""
    t[0] = [t[3]]


def _0_9_6_compat_untranslate(module):
    """Provide compatibility for pickles created with jsonpickle 0.9.6 and
    earlier, remapping `exceptions` and `__builtin__` to `builtins`.
    """
    lookup = dict(__builtin__='builtins', exceptions='builtins')
    return lookup.get(module, module)


def receive_group_specific_query(group_state: 'GroupState',
    max_response_time: int):
    """
    Received IGMP Group Specific Query packet regarding group GroupState
    """
    group_state.group_state_logger.debug(
        'NonQuerier NoMembersPresent: receive_group_specific_query')
    return


@staticmethod
def _create_future():
    """Internal method for implementors of new actor types."""
    raise NotImplementedError('Use a subclass of Actor')


def add_vectors_xy(u, v):
    """Add two vectors, assuming they lie in the XY-plane.

    Parameters
    ----------
    u : sequence of float
        XY(Z) components of the first vector.
    v : sequence of float
        XY(Z) components of the second vector.

    Returns
    -------
    list
        Resulting vector in the XY-plane (Z = 0.0)

    Examples
    --------
    >>>

    """
    return [u[0] + v[0], u[1] + v[1], 0.0]


@staticmethod
def parse_netchop(netchop_output):
    """
        Parse netChop stdout.
        """
    line_iterator = iter(netchop_output.decode().split('\n'))
    scores = []
    for line in line_iterator:
        if 'pos' in line and 'AA' in line and 'score' in line:
            scores.append([])
            if '----' not in next(line_iterator):
                raise ValueError('Dashes expected')
            line = next(line_iterator)
            while '-------' not in line:
                score = float(line.split()[3])
                scores[-1].append(score)
                line = next(line_iterator)
    return scores


def atom_mass(atom, coef=0.01):
    """Get the mass of an atom and scale it.

    Parameters
    ----------
    atom : rdkit.Chem.rdchem.Atom
        RDKit atom instance.
    coef : float
        The mass will be multiplied by ``coef``.

    Returns
    -------
    list
        List containing one float only.
    """
    return [atom.GetMass() * coef]


def modifier_convert(modifier: str=''):
    """Convert particles to a mesh object

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


@staticmethod
def common_length(ts1, ts2):
    """
        This function trims the lengths of two timeseries and returns two
        timeseries with the same length.

        The idea is that in order to do array operations there must be a
        common length for each timeseries.

        Reflecting the bias for using timeseries sorted from latest info to
        earlier info, truncation takes place at the end of the array. That
        way older less important values are removed if necessary.

        Usage:
            ts1_new, ts2_new = self.common_length(ts1, ts2)

        """
    length1 = len(ts1.tseries)
    length2 = len(ts2.tseries)
    if length1 == length2:
        return ts1.clone(), ts2.clone()
    else:
        length = min(length1, length2)
        return ts1[:length], ts2[:length]


def _unit_conll_map(value, empty):
    """
    Map a unit value to its CoNLL-U format equivalent.

    Args:
        value: The value to convert to its CoNLL-U format.
        empty: The empty representation for a unit in CoNLL-U.

    Returns:
        empty if value is None and value otherwise.
    """
    return empty if value is None else value


def handle_extensions(extensions):
    """
    Organize multiple extensions that are separated with commas or passed by
    using --extension/-e multiple times.

    For example: running 'django-admin makemessages -e js,txt -e xhtml -a'
    would result in an extension list: ['.js', '.txt', '.xhtml']

    >>> handle_extensions(['.html', 'html,js,py,py,py,.py', 'py,.py'])
    {'.html', '.js', '.py'}
    >>> handle_extensions(['.html, txt,.tpl'])
    {'.html', '.tpl', '.txt'}
    """
    ext_list = []
    for ext in extensions:
        ext_list.extend(ext.replace(' ', '').split(','))
    for i, ext in enumerate(ext_list):
        if not ext.startswith('.'):
            ext_list[i] = '.%s' % ext_list[i]
    return set(ext_list)


def select_more():
    """Select keyframes beside already selected ones

    """
    pass


def is_object(swagger_spec, object_spec, no_default_type=False):
    """
    A schema definition is of type object if its type is object or if it uses
    model composition (i.e. it has an allOf property).
    :param swagger_spec: :class:`bravado_core.spec.Spec`
    :param object_spec: specification for a swagger object
    :type object_spec: dict
    :param no_default_type: ignore bravado-core 'default_type_to_object' configuration
    :type no_default_type: bool
    :return: True if the spec describes an object, False otherwise.
    """
    deref = swagger_spec.deref
    default_type = 'object' if not no_default_type and swagger_spec.config[
        'default_type_to_object'] else None
    object_type = deref(deref(object_spec).get('type', default_type))
    return (object_type == 'object' or object_type is None and 'allOf' in
        object_spec)


@staticmethod
def area_center(area):
    """
        Calculates the center point of a given area tuple. The center will be returned as a tuple of two FLOAT
        values, the first element being the x coordinate and the second the y coordinate.

        CHANGELOG

        Added 05.12.2018

        :param Tuple(Tuple(int,int)) area:  THe tuple describing the two dimensional are in a x y plane
        :return: Tuple(int, int)
        """
    center = area[0][0] + (area[0][1] - area[0][0]) / 2, area[1][0] + (area
        [1][1] - area[1][0]) / 2
    return center


def find_integer(f):
    """Finds a (hopefully large) integer such that f(n) is True and f(n + 1) is
    False.

    f(0) is assumed to be True and will not be checked.
    """
    for i in range(1, 5):
        if not f(i):
            return i - 1
    lo = 4
    hi = 5
    while f(hi):
        lo = hi
        hi *= 2
    while lo + 1 < hi:
        mid = (lo + hi) // 2
        if f(mid):
            lo = mid
        else:
            hi = mid
    return lo


def cli():
    """
    Provides optional arguments for user increased visibility. Note that using some of the arguments may slow down run time and program may take slightly longer to execute.
    """
    """
    first argument should be channel/user name
    -c --channel_type sets channel_type to 'channel'
    -o --overwrite overwrite file if a file of the same name already exists in the output directory
    --version shows version number and exits
    --csv writes to csv file
    --txt writes to txt file
    --docx writes to word dox (not yet available)
    --driver=Firefox sets selenium driver type to Firefox
    --driver=Opera sets selenium driver type to Opera
    --driver=Safari sets selenium driver type to Safari
    --driver=Chrome sets selenium driver type to Chrome
    -v --verbose print every 10 videos written to file
    -i --invisible opens a headless instance of the selenium driver to run the program in the background
    -q --quiet suppresses program updates, only prints to stdout when scrolling is complete files are opened and closed, and any errors that may occur
    -h --help display information on usage and functionality
    -p --pause change pause time between scrolls, set to 0.8s by default
    -r --reverse reverse the indexing so oldest video starts at 1 and most recent video has highest index
    """
    channel = 'schafer5'
    channel_type = 'user'
    file_name = None
    txt = True
    txt_write_format = 'x'
    csv = True
    csv_write_format = 'x'
    docx = False
    docx_write_format = 'x'
    chronological = False
    headless = False
    scroll_pause_time = 0.8
    driver = None
    return (channel, channel_type, file_name, txt, txt_write_format, csv,
        csv_write_format, docx, docx_write_format, chronological, headless,
        scroll_pause_time, driver)


def timid_relpath(arg):
    """convert an argument to a relative path, carefully"""
    from os.path import isabs, relpath, sep
    if isabs(arg):
        result = relpath(arg)
        if result.count(sep) + 1 < arg.count(sep):
            return result
    return arg


@classmethod
def has_archiving(cls):
    """Returns whether it supports archiving items on the fetch process.

        :returns: this backend supports items archive
        """
    return True


def fill_coords(img, fn, color):
    """
    Fill pixels of an image with coordinates matching a filter function
    """
    for y in range(img.shape[0]):
        for x in range(img.shape[1]):
            yf = (y + 0.5) / img.shape[0]
            xf = (x + 0.5) / img.shape[1]
            if fn(xf, yf):
                img[y, x] = color
    return img


def _get_umf_family(A):
    """Get umfpack family string given the sparse matrix dtype."""
    family = {'di': 'di', 'Di': 'zi', 'dl': 'dl', 'Dl': 'zl'}
    dt = A.dtype.char + A.indices.dtype.char
    return family[dt]


def calc_temp(Data_ref, Data):
    """
    Calculates the temperature of a data set relative to a reference.
    The reference is assumed to be at 300K.

    Parameters
    ----------
    Data_ref : DataObject
        Reference data set, assumed to be 300K
    Data : DataObject
        Data object to have the temperature calculated for

    Returns
    -------
    T : uncertainties.ufloat
        The temperature of the data set
    """
    T = 300 * (Data.A * Data_ref.Gamma / (Data_ref.A * Data.Gamma))
    Data.T = T
    return T


def mapped_attributes(cls):
    """ Return a list of the mapped attributes. """
    return cls._name_map.mapped()


@classmethod
def _emit_ok(cls):
    """Print OK for success."""
    cls._emit_message('OK\n')


@classmethod
def _match(cls, url, **kwargs):
    """Return True if this handler can handle the input URL"""
    return url.scheme.startswith('http')


def get_version(gdbdr):
    """Get Reactome version."""
    version = None
    query = 'MATCH (v:DBInfo) RETURN v'
    with gdbdr.session() as session:
        for rec in session.run(query).records():
            dbinfo = rec['v']
            assert dbinfo.get('name') == 'reactome'
            version = dbinfo.get('version')
    assert version is not None
    return version


def keplermag_to_sdssr(keplermag, kic_sdssg, kic_sdssr):
    """Converts magnitude measurements in Kepler band to SDSS r band.

    Parameters
    ----------

    keplermag : float or array-like
        The Kepler magnitude value(s) to convert to fluxes.

    kic_sdssg,kic_sdssr : float or array-like
        The SDSS g and r magnitudes of the object(s) from the Kepler Input
        Catalog. The .llc.fits MAST light curve file for a Kepler object
        contains these values in the FITS extension 0 header.

    Returns
    -------

    float or array-like
        SDSS r band magnitude(s) converted from the Kepler band magnitude.

    """
    kic_sdssgr = kic_sdssg - kic_sdssr
    if kic_sdssgr < 0.8:
        kepsdssr = (keplermag - 0.2 * kic_sdssg) / 0.8
    else:
        kepsdssr = (keplermag - 0.1 * kic_sdssg) / 0.9
    return kepsdssr


@classmethod
def from_id(cls, group_endpoint, cluster_id: int):
    """Instantiate from ZCL cluster by cluster id."""
    if cluster_id in cls._registry:
        return cls._registry[cluster_id](group_endpoint, is_server=True)
    group_endpoint.debug(
        '0x%04x cluster id is not supported for group requests', cluster_id)
    raise KeyError('Unsupported 0x{:04x} cluster id for groups'.format(
        cluster_id))


def get_column_ids(column_names, *names, **optional):
    """Find all names in column_names and return their indices."""
    result = []
    for name in names:
        try:
            result.append(column_names.index(name))
        except ValueError:
            if 'optional' in optional and optional['optional']:
                result.append(None)
            else:
                raise ValueError('Column not found in input file: %s' % name)
    if len(result) == 1:
        return result[0]
    return tuple(result)


@staticmethod
def get_compatable_connection_types():
    """
        This is needed so the build system knows which
        connection types this connection is compatable.
        return::['str'] A list of the compatable socket types.
        """
    return ['requester']


def filtered_words(words, mapping):
    """    Go through a sequence of words. Words occuring in mapping are replaced,
    others are passed on as-is.
    """
    for word in words:
        yield mapping.get(word, word)


@staticmethod
def __find_clause(query, clause):
    """
        checks if a sparql query already has some clause. Useful when trying to batch retrieve the results
        :param query: the sparql query string
        :return: -1 if the clause does not exist or the range of the number after the clause
        """
    clause = ' {} '.format(clause.strip().lower())
    query = query.lower().replace('\n', ' ')
    pos = query.find(clause)
    if pos == -1:
        return -1, -1
    else:
        i = pos + len(clause)
        while i < len(query) and query[i].isdigit():
            i += 1
        return pos + len(clause), i


def create_pytest_param_str_id(f):
    """
    Returns an id that can be used as a pytest id, from an object.

    :param f:
    :return:
    """
    if callable(f) and hasattr(f, '__name__'):
        return f.__name__
    else:
        return str(f)


def apply_K(df, k):
    """Apply the geometric factors to the dataset and compute (apparent)
    resistivities/conductivities
    """
    if 'k' not in df.columns:
        df['k'] = k
    if 'rho_a' not in df.columns:
        df['rho_a'] = df['r'] * df['k']
    if 'sigma_a' not in df.columns:
        df['sigma_a'] = 1.0 / df['rho_a']
    if 'Zt' in df.columns:
        df['rho_a_complex'] = df['Zt'] * df['k']
    return df


def exit_normal():
    """Returns loss coefficient for any exit to a pipe
    as shown in [1]_ and in other sources.

    .. math::
        K = 1

    .. figure:: fittings/flush_mounted_exit.png
       :scale: 28 %
       :alt: Exit from a flush mounted wall; after [1]_

    Returns
    -------
    K : float
        Loss coefficient [-]

    Notes
    -----
    It has been found on occasion that K = 2.0 for laminar flow, and ranges
    from about 1.04 to 1.10 for turbulent flow.

    Examples
    --------
    >>> exit_normal()
    1.0

    References
    ----------
    .. [1] Rennels, Donald C., and Hobart M. Hudson. Pipe Flow: A Practical
       and Comprehensive Guide. 1st edition. Hoboken, N.J: Wiley, 2012.
    """
    return 1.0