@staticmethod
def _get_default_uri():
    """Return the url to download indices"""
    return [
        'http://services.swpc.noaa.gov/text/predicted-sunspot-radio-flux.txt']


def _trapz_2pt_error2(dy1, dy2, dx):
    """Squared error on the trapezoidal rule for two points.

    For errors dy1 and dy2 and spacing dx."""
    return (0.5 * dx) ** 2 * (dy1 ** 2 + dy2 ** 2)


def initialize_stats_dict(individual):
    """
    Initializes the stats dict for individual
    The statistics initialized are:
        'generation': generation in which the individual was evaluated. Initialized as: 0
        'mutation_count': number of mutation operations applied to the individual and its predecessor cumulatively. Initialized as: 0
        'crossover_count': number of crossover operations applied to the individual and its predecessor cumulatively. Initialized as: 0
        'predecessor': string representation of the individual. Initialized as: ('ROOT',)

    Parameters
    ----------
    individual: deap individual

    Returns
    -------
    object
    """
    individual.statistics['generation'] = 0
    individual.statistics['mutation_count'] = 0
    individual.statistics['crossover_count'] = 0
    individual.statistics['predecessor'] = 'ROOT',


def is_text(data):
    """
    Checks if the data given is a suitable for holding text

    That is, if it can hold text that requires more than one byte for
    each character.
    """
    return isinstance(data, str)


def methods_of(obj):
    """Return non-private methods from an object.

    Get all callable methods of an object that don't start with underscore
    :return: a list of tuples of the form (method_name, method)
    """
    result = []
    for i in dir(obj):
        if callable(getattr(obj, i)) and not i.startswith('_'):
            result.append((i, getattr(obj, i)))
    return result


@staticmethod
def get_date(instance):
    """
        Guess date for instance based on the OS disk
        """
    for disk in instance['instance_view']['disks']:
        if disk['name'] == instance['storage_profile']['os_disk']['name']:
            try:
                return disk['statuses'][0]['time']
            except KeyError:
                break
    return instance['instance_view']['statuses'][0].get('time')


@classmethod
def style(cls, option, text):
    """Applies styling option to given text"""
    return '{start}{text}{reset}'.format(start=getattr(cls, option), text=
        text, reset=cls.RESET)


def ShowControls(Controls, pFile=None, SeqRef=False):
    """Print controls information"""
    pFile.write(' Least squares controls:\n')
    pFile.write(' Refinement type: %s\n' % Controls['deriv type'])
    if 'Hessian' in Controls['deriv type']:
        pFile.write(' Maximum number of cycles: %d\n' % Controls['max cyc'])
    else:
        pFile.write(' Minimum delta-M/M for convergence: %.2g\n' % Controls
            ['min dM/M'])
    pFile.write(' Regularize hydrogens (if any): %s\n' % Controls.get(
        'HatomFix', False))
    pFile.write(' Initial shift factor: %.3f\n' % Controls['shift factor'])
    if SeqRef:
        pFile.write(' Sequential refinement controls:\n')
        pFile.write(' Copy of histogram results to next: %s\n' % Controls[
            'Copy2Next'])
        pFile.write(' Process histograms in reverse order: %s\n' % Controls
            ['Reverse Seq'])


def write_predictions(identifier2prediction, filepath):
    """
    Create a predictions file.

    Parameters
    ----------
    identifier2prediction : Dict[str, str]
        Map an identifier (as used in write_gt) to a prediction.
        The prediction is a single class, not a distribution.
    filepath : str
        Write to this CSV file.
    """
    with open(filepath, 'w') as f:
        for identifier, prediction in identifier2prediction.items():
            f.write('{};{}\n'.format(identifier, prediction))


@classmethod
def store_obj(cls, intf, obj):
    """Stores the topo object. """
    cls.topo_intf_obj_dict[intf] = obj


def get_column_code_by_index(index):
    """
    根据索引编号，获取excel列编号
    :param index: 索引编号，从1开始
    :return:
    """
    if index > 16384 or index < 1:
        return ''
    charSize = 26
    indexName = ''
    for i in range(0, 5):
        tmp = index % charSize
        index = int((index - 1) / charSize)
        if tmp == 0:
            tmp = charSize
        indexName = chr(64 + tmp) + indexName
        if index <= 0:
            break
    return indexName


def _gulp_parse_energy(lines):
    """Parse energy out of a GULP output split in lines"""
    for l in lines[::-1]:
        if 'Total lattice energy       =' in l and 'eV' in l:
            return float(l.split()[4])
    return None


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

        :param int val:
        :rtype: UploadApiRateLimitValue
        """
    return cls('limit', val)


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

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

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


def centroid_points_xy(points):
    """Compute the centroid of a set of points lying in the XY-plane.

    Warning
    -------
    Duplicate points are **NOT** removed. If there are duplicates in the
    sequence, they should be there intentionally.

    Parameters
    ----------
    points : list of list
        A sequence of points represented by their XY(Z) coordinates.

    Returns
    -------
    list
        XYZ coordinates of the centroid (Z = 0.0).

    Examples
    --------
    >>>
    """
    p = len(points)
    x, y = list(zip(*points))[:2]
    return [sum(x) / p, sum(y) / p, 0.0]


def __api_reverse_suffix(path):
    """Return the normalized suffix of a url without any api information so that the correct version can be added."""
    if path.startswith('/api/'):
        components = path.split('/', 3)
        if len(components) >= 4 and components[2].isdigit():
            return '/' + components[3]
        else:
            return path[4:]
    else:
        return path


def pushOutput(data, out):
    """Push block of outputted data into processor.

        Processor writes data to pass along on output stream to
        out, using .write().
        """


def reverse_remove_duplicate_renditions(*args, **kwargs):
    """This is a no-op. The migration removes duplicates, we cannot recreate those duplicates."""
    pass


def reverseDict(d):
    """
    Helper for generating fullToTag
    Makes dict of value to key
    """
    retD = {}
    for k in d:
        retD[d[k]] = k
    return retD


def burrows_wheeler(text):
    """Calculates the burrows wheeler transform of <text>.

    returns the burrows wheeler string and the suffix array indices
    The text is assumed to not contain the character $"""
    text += '$'
    all_permutations = []
    for i in range(len(text)):
        all_permutations.append((text[i:] + text[:i], i))
    all_permutations.sort()
    bw_l = []
    sa_i = []
    for w, j in all_permutations:
        bw_l.append(w[-1])
        sa_i.append(j)
    return ''.join(bw_l), sa_i


def _ifq(cond, ifT, ifF):
    """ Fortran-style ternary if """
    return ifT if cond else ifF


@classmethod
def from_skycoords(cls, skycoords, max_norder):
    """
        Creates a MOC from an `astropy.coordinates.SkyCoord`.

        Parameters
        ----------
        skycoords : `astropy.coordinates.SkyCoord`
            The sky coordinates that will belong to the MOC.
        max_norder : int
            The depth of the smallest HEALPix cells contained in the MOC.

        Returns
        -------
        result : `~mocpy.moc.MOC`
            The resulting MOC
        """
    return cls.from_lonlat(lon=skycoords.icrs.ra, lat=skycoords.icrs.dec,
        max_norder=max_norder)


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


@staticmethod
def load_tag_map(path):
    """
        Load Stanford Universal Tags map file

        :param path: the map file path
        :return: map of dependency labels to parts-of-speech.
        """
    map_dict = {}
    open_file = open(path, encoding='utf8').readlines()
    for line in open_file:
        line = line.strip().split('\t')
        if line[1].strip() == 'ADP':
            map_dict[line[0]] = 'PREP'
        elif line[1].strip() == 'PROPN':
            map_dict[line[0]] = 'NOUN'
        else:
            map_dict[line[0]] = line[1].strip()
    map_dict['""'] = 'PUNCT'
    map_dict['SP'] = 'SPACE'
    map_dict['_SP'] = 'SPACE'
    map_dict['ADD'] = 'X'
    map_dict['GW'] = 'X'
    map_dict['NFP'] = 'X'
    map_dict['XX'] = 'X'
    return map_dict


@classmethod
def where_unique(cls, ip, object_id, location):
    """ Get db model by username """
    return cls.query.filter_by(ip=ip, object_id=object_id, location=location
        ).first()


def event_receiver(event_type, details):
    """This is the callback that (in this example) doesn't do much..."""
    print("Recieved event '%s'" % event_type)
    print('Details = %s' % details)


@staticmethod
def candidate_urls(bzr_branch):
    """Iterate through related URLs that might be Launchpad URLs.

        :param bzr_branch: A Bazaar branch to find URLs from.
        :return: a generator of URL strings.
        """
    url = bzr_branch.get_public_branch()
    if url is not None:
        yield url
    url = bzr_branch.get_push_location()
    if url is not None:
        yield url
    url = bzr_branch.get_parent()
    if url is not None:
        yield url
    yield bzr_branch.base


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

        :param CreateFolderDetails val:
        :rtype: EventDetails
        """
    return cls('create_folder_details', val)


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['operation']
    if type == 'IMPORT_TF_STATE':
        return 'ImportTfStateJobOperationDetailsSummary'
    if type == 'PLAN':
        return 'PlanJobOperationDetailsSummary'
    if type == 'DESTROY':
        return 'DestroyJobOperationDetailsSummary'
    if type == 'APPLY':
        return 'ApplyJobOperationDetailsSummary'
    else:
        return 'JobOperationDetailsSummary'


@staticmethod
def shorten_string(string, max_length=30):
    """Truncate and add '...' if the string is too long"""
    suffix = '' if len(string) < max_length else '...'
    return string[:max_length] + suffix


def detection_time_to_impact(detection_time, impact_data):
    """
    Coverts detection time to an impact/damage metric.

    The impact DataFrame returned from this function can be used as input to
    :py:class:`ImpactFormulation<chama.optimization.ImpactFormulation>`.

    Parameters
    ----------
    detection_time : pandas DataFrame
        Detection time for each scenario-sensor pair. The DataFrame has
        columns 'Scenario', 'Sensor', and 'T'. Note the 'T' column here is a
        single time and not a list of detection times.
    impact_data : pandas DataFrame
        Impact data for each scenario and time. The DataFrame has
        columns 'T' and one column for each scenario (user defined names)
        containing the impact/damage if each scenario was first detected at
        the times in 'T'.

    Returns
    ----------
    det_damage : pandas DataFrame
        DataFrame with columns 'Scenario', 'Sensor', and 'Impact'.
    """
    impact_data = impact_data.set_index('T')
    allT = list(set(detection_time['T']) | set(impact_data.index))
    impact_data = impact_data.reindex(allT)
    impact_data.sort_index(inplace=True)
    impact_data.interpolate(inplace=True)
    det_damage = detection_time.copy()
    det_damage['T'] = impact_data.lookup(detection_time['T'],
        detection_time['Scenario'])
    det_damage.rename(columns={'T': 'Impact'}, inplace=True)
    return det_damage


@classmethod
def numeric_hash_to_location(cls, numeric_hash, precision=None):
    """
        Given a numeric hash return a location

        Precision needs to be given to account for leading zeroes.

        Parameters
        ----------
        numeric_hash : int
        precision : int

        Returns
        -------
        Location
        """
    if precision is None:
        precision = 25
    octant = numeric_hash % 8
    numeric_hash = numeric_hash // 8
    i = 3
    levels = []
    while i < precision:
        levels.append(numeric_hash % 4)
        numeric_hash = numeric_hash // 4
        i += 2
    return cls.levels_to_location(octant, levels)


def matchingQuoteWord(w, quotationList):
    """
        Return the quotation set in which belong the word (None otherwise).
        w must be of the form (word,index)
    """
    for quote in quotationList:
        if w.index in quote[2]:
            return quote
    return None


def asDict():
    """
        Returns the SQLObject instance as a dictionary (column names
        as keys, column values as values).

        Use like::

            ASQLObjectClass(a=1, b=2).asDict()

        Which should return ``{'a': 1, 'b': 2}``.

        Note: this is a *copy* of the object's columns; changing the
        dictionary will not effect the object it was created from.
        """


def fetch_file(url, file_name, resume=True, timeout=10.0):
    """Load requested file, downloading it if needed or requested.

    Parameters
    ----------
    url: string
        The url of file to be downloaded.
    file_name: string
        Name, along with the path, of where downloaded file will be saved.
    resume: bool, optional
        If true, try to resume partially downloaded files.
    timeout : float
        The URL open timeout.
    """
    from mne.utils import _fetch_file
    _fetch_file(url=url, file_name=file_name, print_destination=True,
        resume=resume, hash_=None, timeout=timeout)


@staticmethod
def swagger(result_schema):
    """
        given the schema of the inner
        result object, return back the
        swagger schema representation.
        """
    raise NotImplementedError()


def set_login_state(logged_in):
    """Sets the login state"""
    global LOGGED_IN
    LOGGED_IN = logged_in


def p_flags(t):
    """flags : FLAGS flaglist"""
    t[0] = 'flags', t[2]


@classmethod
def _PosConcatTransitionSet(cls, pos, transition_set):
    """Implement definition 11.3 in B{HOV09}"""
    ts = []
    for q, psi in transition_set:
        ts.append((pos + q, cls._PosConcatUpdateInstruction(pos, psi)))
    return ts


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

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

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


def hide(unselected: bool=False):
    """Tag selected bones to not be visible in Pose Mode

    :param unselected: Unselected
    :type unselected: bool
    """
    pass


def leaderboard(benchmark, results=None, output_dir=None, leaderboard_dir=
    None, **ax_set_kwargs):
    """Generates a leaderboard for all metrics in `benchmark`,
  by appending the (optional) `results`.

  Args:
    benchmark: `str`, the registerd name of `bdlb.Benchmark`.
    results: (optional) `dict`, dictionary of `pandas.DataFrames`
      with the results from a new method to be plotted against
      the leaderboard.
    leaderboard_dir: (optional) `str`, the path to the parent
      directory with all the leaderboard results.
    output_dir: (optional) `str`, the directory name to
      store the figures.
  """
    import os
    import pandas as pd
    import matplotlib.pyplot as plt
    from .constants import BDLB_ROOT_DIR
    COLORS = plt.rcParams['axes.prop_cycle'].by_key()['color']
    MARKERS = ['o', 'D', 's', '8', '^', '*']
    leaderboard_dir = leaderboard_dir or os.path.join(BDLB_ROOT_DIR,
        'leaderboard')
    benchmark_dir = os.path.join(leaderboard_dir, benchmark)
    if not os.path.exists(benchmark_dir):
        ValueError('No leaderboard data found at {}'.format(benchmark_dir))
    metrics = os.listdir(benchmark_dir)
    for metric in metrics:
        fig, ax = plt.subplots()
        baselines = os.listdir(os.path.join(benchmark_dir, metric))
        for b, baseline in enumerate(baselines):
            baseline = baseline.replace('.csv', '')
            df = pd.read_csv(os.path.join(benchmark_dir, metric, '{}.csv'.
                format(baseline)))
            retained_data = df['retained_data']
            mean = df['mean']
            std = df['std']
            ax.plot(retained_data, mean, label=baseline, color=COLORS[b %
                len(COLORS)], marker=MARKERS[b % len(MARKERS)])
            ax.fill_between(retained_data, mean - std, mean + std, color=
                COLORS[b % len(COLORS)], alpha=0.25)
        if results is not None:
            if metric in results:
                df = results[metric]
                baseline = df.name if hasattr(df, 'name') else 'new_method'
                retained_data = df['retained_data']
                mean = df['mean']
                std = df['std']
                ax.plot(retained_data, mean, label=baseline, color=COLORS[(
                    b + 1) % len(COLORS)], marker=MARKERS[(b + 1) % len(
                    MARKERS)])
                ax.fill_between(retained_data, mean - std, mean + std,
                    color=COLORS[(b + 1) % len(COLORS)], alpha=0.25)
        ax.set(xlabel='retained data', ylabel=metric)
        ax.legend()
        fig.tight_layout()
        if isinstance(output_dir, str):
            os.makedirs(output_dir, exist_ok=True)
            fig.savefig(os.path.join(output_dir, '{}.pdf'.format(metric)),
                trasparent=True, dpi=300, format='pdf')
        fig.show()


def local_conv2d(inputs, kernel, kernel_size, strides, output_shape,
    data_format=None):
    """Apply 2D conv with un-shared weights.

    # Arguments
        inputs: 4D tensor with shape:
                (batch_size, filters, new_rows, new_cols)
                if data_format='channels_first'
                or 4D tensor with shape:
                (batch_size, new_rows, new_cols, filters)
                if data_format='channels_last'.
        kernel: the unshared weight for convolution,
                with shape (output_items, feature_dim, filters)
        kernel_size: a tuple of 2 integers, specifying the
                     width and height of the 2D convolution window.
        strides: a tuple of 2 integers, specifying the strides
                 of the convolution along the width and height.
        output_shape: a tuple with (output_row, output_col)
        data_format: the data format, channels_first or channels_last

    # Returns
        A 4d tensor with shape:
        (batch_size, filters, new_rows, new_cols)
        if data_format='channels_first'
        or 4D tensor with shape:
        (batch_size, new_rows, new_cols, filters)
        if data_format='channels_last'.

    # Raises
        ValueError: if `data_format` is neither
                    `channels_last` or `channels_first`.
    """
    raise NotImplementedError(
        'MXNet Backend: local_conv2d operator is not supported yet.')


def apStar_url(telescope, location_id, field, file_, url_header=None):
    """ apStar url generator
    which in principle is able to generate file path

    Parameters
    ----------
    telescope: string
        TELESCOPE, {"apo1m', 'apo25m'}
    location_id: int
        for 'apo1m', it's 1
        for 'apo25m', it's like PLATE
    field: string
        for 'apo1m', it's 'hip'|'calibration'|...
        for 'apo25m', it's non-sense
    file_: string
        FILE
    url_header: string
        if None|'sas', it's set to be
        "https://data.sdss.org/sas/dr13/apogee/spectro/redux/%s/stars"%version

    Returns
    -------
    url: string
        the url of apStar file

    Note
    ----
    version: string
        currently it's 'r6' @20161031
    """
    if url_header is None or url_header is 'sas':
        url_header = (
            'https://data.sdss.org/sas/dr13/apogee/spectro/redux/r6/stars')
    url_header = url_header.strip()
    telescope = telescope.strip()
    field = field.strip()
    file_ = file_.strip()
    if telescope == 'apo1m':
        url = '%s/%s/%s/%s' % (url_header, telescope, field, file_)
    elif telescope == 'apo25m':
        url = '%s/%s/%s/%s' % (url_header, telescope, location_id, file_)
    else:
        raise ValueError('@Cham: This is not an option!')
    return url


def iterkeys():
    """iterate over keys; equivalent to __iter__"""


def _filter_scaling(reduction_indices, start_cell_num):
    """Compute the expected filter scaling at given PNASNet cell start_cell_num.

  In the pnasnet.py code, filter_scaling starts at 1.0. We instead
  adapt filter scaling to depend on the starting cell.
  At first cells, before any reduction, filter_scalling is 1.0. With passing
  any reduction cell, the filter_scaling is multiplied by 2.

  Args:
    reduction_indices: list of int indices.
    start_cell_num: int.
  Returns:
    filter_scaling: float.
  """
    filter_scaling = 1.0
    for ind in reduction_indices:
        if ind < start_cell_num:
            filter_scaling *= 2.0
    return filter_scaling


def overlap(cls, tspan):
    """ If supplied timespan overlaps this timespan, returns True. """
    if cls.start_dt <= tspan.end_dt and cls.end_dt >= tspan.start_dt:
        return True
    else:
        return False


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

        :param LookupError val:
        :rtype: SyncSettingsError
        """
    return cls('path', val)


def extract_basic_stat_info(stats):
    """ Returns size, modification, creation time and access mode. """
    return stats.st_size, stats.st_mtime, stats.st_ctime, stats.st_mode


def print_url(title, url):
    """Pretty-print a URL on the terminal."""
    import click
    click.secho('  %s: ' % title, nl=False, fg='blue')
    click.secho(url, bold=True)


def writeNestedListToSettings(settings, key, values, props, transforms=None):
    """
    Writes a nested list to settings

    :param settings QSettings: Settings object to write from
    :param key str: The section the array will reside in
    :param values QStandardItemModel: The array to write
    :param props dict: A dict containing mappings from Qt Item roles
        to array property names.
    :param transforms dict: A dict containing mappings from Qt Item roles
        to callables that transform it into the right type.

    .. tip::
        Example props parameter.

        .. code-block:: python

            {
                Qt.DisplayRole:'testProp',
                Qt.UserRole   :'testProp2',
                Qt.UserRole+1 :'testProp3',
            }
    """
    if transforms is None:
        transforms = {}
    settings.beginWriteArray(key)
    size = values.rowCount()
    for i in range(size):
        settings.setArrayIndex(i)
        val = values.item(i)
        for prop in props:
            value = val.data(prop)
            if prop in transforms:
                value = transforms[prop](value)
            settings.setValue(props[prop], value)
    settings.endArray()


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


def to_language(locale):
    """Turns a locale name (en_US) into a language name (en-us)."""
    p = locale.find('_')
    if p >= 0:
        return locale[:p].lower() + '-' + locale[p + 1:].lower()


def _run_algorithm_from_json(params, output_file):
    """Runs the Aqua Chemistry experiment from Qiskit Aqua json dictionary

    Args:
        params (dictionary): Qiskit Aqua json dictionary
        output_file (filename): Output file name to save results
    """
    from qiskit.aqua import run_algorithm
    from qiskit.aqua.utils import convert_json_to_dict
    ret = run_algorithm(params, None, True)
    if output_file is not None:
        with open(output_file, 'w') as run_output:
            print('{}'.format(ret), file=run_output)
    else:
        convert_json_to_dict(ret)
        print(
            """

--------------------------------- R E S U L T ------------------------------------
"""
            )
        if isinstance(ret, dict):
            for k, v in ret.items():
                print("'{}': {}".format(k, v))
        else:
            print(ret)


def readthrough_in_bedpe(record, annotation, rt_threshold):
    """
    Determine if the two genes in the record are within `rt_threshold` bp of each other on the same
    chromosome.

    :param BEDPE record: A BEDPE line from the input file
    :param dict(str, GTFRecord) annotation: see `read_fusions:gene_annotations`
    :param rt_threshold: The genomic distance on the same chromosome below which we will call a
           candidate fusion a readthrough.
    :returns: True if the pair is considered a readthrough and False if not
    :rtype: bool
    """
    return record.chrom1 == record.chrom2 and (annotation[record.hugo1].
        start <= annotation[record.hugo2].start <= annotation[record.hugo1]
        .end + rt_threshold or annotation[record.hugo2].start <= annotation
        [record.hugo1].start <= annotation[record.hugo2].end + rt_threshold)


def parse_bdist_wininst(name):
    """Return (base,pyversion) or (None,None) for possible .exe name"""
    lower = name.lower()
    base, py_ver, plat = None, None, None
    if lower.endswith('.exe'):
        if lower.endswith('.win32.exe'):
            base = name[:-10]
            plat = 'win32'
        elif lower.startswith('.win32-py', -16):
            py_ver = name[-7:-4]
            base = name[:-16]
            plat = 'win32'
        elif lower.endswith('.win-amd64.exe'):
            base = name[:-14]
            plat = 'win-amd64'
        elif lower.startswith('.win-amd64-py', -20):
            py_ver = name[-7:-4]
            base = name[:-20]
            plat = 'win-amd64'
    return base, py_ver, plat


def calculate_width_and_height(url_parts, options):
    """Appends width and height information to url"""
    width = options.get('width', 0)
    has_width = width
    height = options.get('height', 0)
    has_height = height
    flip = options.get('flip', False)
    flop = options.get('flop', False)
    if flip:
        width = width * -1
    if flop:
        height = height * -1
    if not has_width and not has_height:
        if flip:
            width = '-0'
        if flop:
            height = '-0'
    if width or height:
        url_parts.append('%sx%s' % (width, height))


def daily2monthly(df_in, averaging=True, volumetric=False,
    volumetric_factor=86400, plot=False):
    """Aggregates daily values to monthly values. Note that the unit is not changed (m3/s) unless volumetric is True.

    Arguments:
        df_in (dataframe): dataframe containing daily values

    Keyword Arguments:
        averaging (bool) : whether or not to compute monthly average or not; if False, the monthly aggregate is computed (default: True)
        volumetric (bool): whether flux is converted to volume (e.g. m3/s to m3) (default: False)
        volumetric_factor (int): factor to convert flux to volume if specified (default: 86400)
        plot (bool): whether or not to plot the monthly timeseries (default: False)

    Returns:
        dataframe: dataframe containing monthly values
    """
    if averaging:
        df_out = df_in.resample('M').mean()
    else:
        df_out = df_in.resample('M').sum()
    if volumetric:
        df_out = df_out * volumetric_factor
    if plot:
        df_out.plot()
    return df_out


def bool_value(value):
    """
    Converts the given object to a bool if it is possible.

    Parameters
    ----------
    value : object
        Object to be converted to bool.

    Returns
    -------
    value : bool
        Bool value.

    Raises
    ------
    ValueError
        If the object cannot be converted to bool.
    """
    if isinstance(value, bool):
        return value
    if hasattr(value, 'render'):
        value = value.render()
    if value in ['true', '1']:
        return True
    elif value in ['false', '0']:
        return False
    raise ValueError('Invalid bool value: {!r}'.format(value))


def doStart():
    """
        Called every time this is connected to a Port or Connector.
        """


def cast_int_float_string(value):
    """ Cast given string value, if possible, to an int, float or returns unchanged.

    Parameters
    ----------
    value : str or unicode
        Value to try casting to an int and float.

    Returns
    -------
    int, float, str or unicode
        Cast *value*.
    """
    try:
        return int(value)
    except ValueError:
        try:
            return float(value)
        except ValueError:
            return value


def get_sens_at_time(filename, varname, timename, attime, vals, maxn):
    """
    Get results from a sensitivity run at a specific type and across
    sensitivity runs.

    currently not implemented
    """
    raise NotImplementedError


@classmethod
def get_readable_properties(cls):
    """
        Get all the readable properties for this class
        """
    return list(filter(lambda x: x.is_readable(), cls.get_properties()))


@classmethod
def concatenate_data(cls, data_list, axis):
    """Concatenates a list of Data objects into a single Data object along
    the specified access (see cf.Data.concatenate for details). In the
    case that the list contains only one element, that element is
    simply returned.

    :Parameters:

        data_list: `list`
            The list of data objects to concatenate.

        axis: `int`
            The axis along which to perform the concatenation.

    :Returns:

        `Data`
            The resulting single `Data` object.

        """
    if len(data_list) > 1:
        data = cls.concatenate(data_list, axis=axis)
        if data.fits_in_one_chunk_in_memory(data.dtype.itemsize):
            data.varray
        return data
    else:
        assert len(data_list) == 1
        return data_list[0]


def create_prediction_data(discri_dict, **kwargs):
    """
		specific to each rule, stores the main information to predict a sequence
		"""
    pass


def grouper_list(l, n):
    """Evenly divide list into fixed-length piece, no filled value if chunk
    size smaller than fixed-length.

    Example::

        >>> list(grouper(range(10), n=3)
        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

    **中文文档**

    将一个列表按照尺寸n, 依次打包输出, 有多少输出多少, 并不强制填充包的大小到n。

    下列实现是按照性能从高到低进行排列的:

    - 方法1: 建立一个counter, 在向chunk中添加元素时, 同时将counter与n比较, 如果一致
      则yield。然后在最后将剩余的item视情况yield。
    - 方法2: 建立一个list, 每次添加一个元素, 并检查size。
    - 方法3: 调用grouper()函数, 然后对里面的None元素进行清理。
    """
    chunk = list()
    counter = 0
    for item in l:
        counter += 1
        chunk.append(item)
        if counter == n:
            yield chunk
            chunk = list()
            counter = 0
    if len(chunk) > 0:
        yield chunk


def bC_Mg_SO3_RZM91(T, P):
    """c-a: magnesium sulfite [RZM91]."""
    b0 = -2.8
    b1 = 12.9
    b2 = -201
    C0 = 0
    C1 = 0
    alph1 = 1.4
    alph2 = 12
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


def flip(array, axis=1):
    """Defines the missing numpy.flip function."""
    indexer = [slice(None)] * array.ndim
    indexer[axis] = slice(None, None, -1)
    return array[tuple(indexer)]


def selected_toggle():
    """Toggle the Outliner selection of items

    """
    pass


@classmethod
def from_stream(cls, stream, marker_code, offset):
    """
        Return an |_App0Marker| instance for the APP0 marker at *offset* in
        *stream*.
        """
    segment_length = stream.read_short(offset)
    density_units = stream.read_byte(offset, 9)
    x_density = stream.read_short(offset, 10)
    y_density = stream.read_short(offset, 12)
    return cls(marker_code, offset, segment_length, density_units,
        x_density, y_density)


def default_configuration():
    """Default standardization configuration."""
    return dict(pc=(0.0, 99.8), landmarks=tuple(range(10, 100, 10)), scale=
        (1, 4095))


def to_human(seconds):
    """Converts seconds to human readable (weeks, days, hours) form.

    :param int seconds: number of seconds.

    :return: (weeks, days, hours) equivalent to the seconds.

    :rtype: str
    """
    weeks = seconds / (7 * 24 * 60 * 60)
    days = seconds / (24 * 60 * 60) - 7 * weeks
    hours = seconds / (60 * 60) - 7 * 24 * weeks - 24 * days
    return '%sw, %sd, %sh' % (weeks, days, hours)


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

        :param list of [str] val:
        :rtype: GroupMembersRemoveError
        """
    return cls('members_not_in_team', val)


def _image_create_from_config(client, config, wait=False):
    """ Create an image from the given configuration.

    See: https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-6
    """
    response = client.api.images.post(json=config)
    if wait:
        return client.operations.wait_for_operation(response.json()[
            'operation'])
    return response.json()['operation']


def stop_assessment_run(assessmentRunArn=None):
    """
    Stops the assessment run that is specified by the ARN of the assessment run.
    See also: AWS API Documentation

    Examples
    Stops the assessment run that is specified by the ARN of the assessment run.
    Expected Output:

    :example: response = client.stop_assessment_run(
        assessmentRunArn='string'
    )

    :type assessmentRunArn: string
    :param assessmentRunArn: [REQUIRED]
            The ARN of the assessment run that you want to stop.

    :return: response = client.stop_assessment_run(
        assessmentRunArn='arn:aws:inspector:us-west-2:123456789012:target/0-nvgVhaxX/template/0-it5r2S4T/run/0-11LMTAVe',
    )

    print(response)

    """
    pass


@staticmethod
def set_geo_point_field():
    """
        sets geo_point data type
        :return dictionary:
        """
    return {'type': 'geo_point'}


def t_CPP_COMMENT1(t):
    """(/\\*(.|\\n)*?\\*/)"""
    ncr = t.value.count('\n')
    t.lexer.lineno += ncr
    t.type = 'CPP_WS'
    t.value = '\n' * ncr if ncr else ' '
    return t


def make_post(api, top_artists, args):
    """Post weekly or yearly top 3 artists to Twitter.

    :param api: The twitter API setup in the setup_twitter function.
    :type api: cls twitter..api.Api

    :param top_artists: contains the top artists retrieved from last.fm API.
    :type top_artists: list

    :param args: The args from the commandline, here used to determine yr|wk
    :type args: cls argparse.Namespace
    """
    if args.yearly:
        post = (
            f'My top 3 #lastfm artists for the past 12 months: {top_artists[0].item}({str(top_artists[0].weight)}),{top_artists[1].item}({str(top_artists[1].weight)}),{top_artists[2].item}({str(top_artists[2].weight)})'
            )
    else:
        post = (
            f'My top 3 #lastfm artists for the past 7 days: {top_artists[0].item}({str(top_artists[0].weight)}),{top_artists[1].item}({str(top_artists[1].weight)}),{top_artists[2].item}({str(top_artists[2].weight)})'
            )
    status = api.PostUpdates(post)
    print(status)


def _is_iterable(obj):
    """A Python 2 and 3 compatible util to check whether `obj` is iterable."""
    try:
        iter(obj)
        return True
    except TypeError:
        return False


def get(isdsAppliance, check_mode=False, force=False):
    """
    Retrieving the administrator settings
    """
    return isdsAppliance.invoke_get('Retrieving the administrator settings',
        '/admin_cfg')


def p_DictionaryMembers_empty(p):
    """DictionaryMembers : """
    p[0] = []


def __new__(cls, name, description=None):
    """Keep a dict of PermissionSetting instances, indexed by
        name. If the name already exists in the dict, return that
        instance rather than creating a new one.
        """
    instances = cls.__dict__.get('_z_instances')
    if instances is None:
        cls._z_instances = instances = {}
    it = instances.get(name)
    if it is None:
        instances[name] = it = object.__new__(cls)
        it._init(name, description)
    return it


def setResult(result):
    """Sets response result value based on input.

        Input is usually a unicode string, a string, None, or an object
        that can be adapted to IResult with the request.  The end result
        is an iterable such as WSGI prefers, determined by following the
        process described below.

        Try to adapt the given input, with the request, to IResult
        (found above in this file).  If this fails, and the original
        value was a string, use the string as the result; or if was
        None, use an empty string as the result; and if it was anything
        else, raise a TypeError.

        If the result of the above (the adaptation or the default
        handling of string and None) is unicode, encode it (to the
        preferred encoding found by adapting the request to
        zope.i18n.interfaces.IUserPreferredCharsets, usually implemented
        by looking at the HTTP Accept-Charset header in the request, and
        defaulting to utf-8) and set the proper encoding information on
        the Content-Type header, if present.  Otherwise (the end result
        was not unicode) application is responsible for setting
        Content-Type header encoding value as necessary.

        If the result of the above is a string, set the Content-Length
        header, and make the string be the single member of an iterable
        such as a tuple (to send large chunks over the wire; see
        discussion in the IResult interface).  Otherwise (the end result
        was not a string) application is responsible for setting
        Content-Length header as necessary.

        Set the result of all of the above as the response's result. If
        the status has not been set, set it to 200 (OK). """


def neg_real(data):
    """
    Negate real data
    """
    data.real = -data.real
    return data


def weight_sample():
    """Use the mouse to sample a weight in the 3D view

    """
    pass


def set_mode(how):
    """ Sets the behavior of the API

    :param how: if 'remote' all the execution is performed on the remote server; if 'local' all
           it is executed locally. Default = 'local'
    :return: None
    """
    global __mode
    if how == 'local':
        __mode = how
    elif how == 'remote':
        __mode = how
    else:
        raise ValueError("how must be 'local' or 'remote'")


def __long__():
    """Convert to a long-int number of seconds since the epoch (gmt)"""


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def is_last_attempt(request):
    """
    Return `True` if the request is on its last attempt, meaning that
    the `TransactionTween` will not invoke the handler again, regardless
    of what happens during this attempt.
    """
    environ = request.environ
    attempt = environ.get('retry.attempt')
    attempts = environ.get('retry.attempts')
    return (True if attempt is None or attempts is None else attempt + 1 ==
        attempts)


def check_domain_running(conn, guestname, logger):
    """ check if the domain exists, may or may not be active """
    guest_names = []
    ids = conn.listDomainsID()
    for id in ids:
        obj = conn.lookupByID(id)
        guest_names.append(obj.name())
    if guestname not in guest_names:
        logger.error("%s doesn't exist or not running" % guestname)
        return 1
    else:
        return 0


def _build_parameters(host, tile_dir, tiles_port, ui_port):
    """Helper to build the parameters needed for starting tilestream.

    :param tile_dir: Optional directory on the remote host that holds one or
        more mbtiles files to be published. If ommitted the default of
        `~/Documents/MapBox/tiles` will be used by tilestream.
    :type tile_dir: str

    :param ui_port: Port on which the tilestream ui should be available.
    :type ui_port: int

    :param tiles_port: Port on which tilestream tile service should be
        available. You may want to use a different port here and then run a
        CDN such as cloudflare in front of the tile service.
    :type tiles_port: int

    :param host: Host name under which the service will run. Must match the
        hostname to which requests are made (even if you run it behind mod
        proxy).
    :type host: str

    :returns: A string containing parameters for starting tilestream.
    :rtype: str
    """
    params = ''
    if tile_dir is not None:
        params += ' --tiles=%s' % tile_dir
    params += ' --uiPort=%i' % ui_port
    params += ' --tilePort=%i' % tiles_port
    if host is not None:
        params += ' --host=%s' % host
    return params


def check_global_permission(user, permission, obj):
    """Generic permission check for base classes."""
    if user.is_superuser:
        return True
    return user.groups.filter(roles__permissions__codename=permission).exists()


def close_circuit(circuit):
    """
        Asks Tor to close the circuit. Note that the Circuit instance
        is only removed as a result of the next CIRC CLOSED event. The
        Deferred returned from this method callbacks when the
        CLOSECIRCUIT command has successfully executed, not when the
        circuit is actually gone.

        If you wish to know when this circuit is actually gone, add an
        ICircuitListener and wait for circuit_closed()
        """


@classmethod
def _ber_enc_content_indefinite(cls, content):
    """Returns :term:`BER` content encoding for indefinite length.

        :param content: content to encode
        :type  content: bytes
        :returns:       encoded content
        :rtype:         bytes

        """
    return content + b'\x00\x00'


@staticmethod
def _to_evalset(data, target, train_idx, *valid_idx):
    """
        Creating an eval_set dictionary, where key is the name
        of the sample, value is a tuple with the input samples
        and the target values.
        """
    eval_set = {'train': (data.loc[train_idx], target.loc[train_idx]),
        'valid': (data.loc[valid_idx[0]], target.loc[valid_idx[0]])}
    if len(valid_idx) == 2:
        eval_set['test'] = data.loc[valid_idx[1]], target.loc[valid_idx[1]]
    return eval_set


@classmethod
def run_disable_maintenance_mode(cls, options=None):
    """Build foreman-maintain advanced procedure run
         maintenance-mode-disable"""
    cls.command_sub = 'maintenance-mode-disable'
    if options is None:
        options = {}
    result = cls._construct_command(options)
    return result


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 convert1Dindices_fromcroppedarray(data_array_shape,
    indices1D_croppedarray, removedges=0):
    """
    convert 1D indices from raveled array
    coming from an array ((data_array_shape) ) which edges have been removed

    in corresponding indices of 1d array
    TODO: give example
    """
    nbrow, nbcol = data_array_shape
    offset = removedges * (nbcol + 1)
    original_index = offset + indices1D_croppedarray / (nbcol - 2 * removedges
        ) + indices1D_croppedarray % (nbcol - 2 * removedges)
    return original_index


def subset_check(subset=None, set_=None):
    """Return True/False depending on if set is subset of larger set.

    If subset - set_ != 0, then subset contains keys that are not in
    set_.

    set_ is our 'allowed keys' in this use case.

    Another use case is testing if a required subset exists in set_.
    For example, looking for keys that are REQUIRED to be in the config.

    :param subset: The set we are checking to see if it is a subset of
        set_.
    :param set_: The set_ being tested against.

    :return: True if subset, False if it isn't.
    """
    if subset - set_:
        return False
    return True


def set_color(message, message_color, foreground_color):
    """Set color characters around a message
    :param message: Message string
    :param message_color: Message color
    :param foreground_color: Color that the output will be reset to
    :return: Message wrapped in color characters
    """
    return '{message_color}{message}{foreground_color}'.format(message_color
        =message_color, message=message, foreground_color=foreground_color)


@classmethod
def gettype(cls, rng):
    """Get the class for the input file type.

        Now ReacNetGen support the following files:
        LAMMPS bond files: http://lammps.sandia.gov/doc/fix_reax_bonds.html
        LAMMPS dump files: https://lammps.sandia.gov/doc/dump.html
        """
    if rng.inputfiletype not in cls.subclasses:
        raise ValueError(f'Unsupported input file type {rng.inputfiletype}')
    return cls.subclasses[rng.inputfiletype](rng)


def get_patch_baseline_for_patch_group(PatchGroup=None):
    """
    Retrieves the patch baseline that should be used for the specified patch group.
    See also: AWS API Documentation

    :example: response = client.get_patch_baseline_for_patch_group(
        PatchGroup='string'
    )

    :type PatchGroup: string
    :param PatchGroup: [REQUIRED]
            The name of the patch group whose patch baseline should be retrieved.

    :rtype: dict
    :return: {
        'BaselineId': 'string',
        'PatchGroup': 'string'
    }

    """
    pass


@staticmethod
def verify_signatures_available():
    """
        check if this strategy can verify signatures

        :return: boolean if this strategy can verify signatures
        """
    try:
        import gpg
        return True
    except ImportError:
        return False


def ka_C_Binary_ratio(y, positive=1):
    """Find the positive ration of dependent variable

        Parameters
        ----------
        y: pandas series
           binary dependent variable
        positive: 1 or 0
                  identify which value is positive

        Return
        ------
        float value display positive rate
    """
    return y.value_counts()[positive] / y.value_counts().sum()


def from_NAF(naf: list) ->int:
    """
    Converts a NAF sequence into an integer.

    Parameters:
        naf (list): NAF sequence.

    Returns:
        int: Integer representation.
    """
    total = 0
    reversed_naf = naf[::-1]
    for i in range(len(naf)):
        total += 2 ** i * reversed_naf[i]
    return total


def degrees(data=None, name=None, attr=None, out=None, **kwargs):
    """Converts each element of the input array from radians to degrees.

    .. math::
       degrees([0, \\pi/2, \\pi, 3\\pi/2, 2\\pi]) = [0, 90, 180, 270, 360]

    The storage type of ``degrees`` output depends upon the input storage type:

       - degrees(default) = default
       - degrees(row_sparse) = row_sparse
       - degrees(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_trig.cc:L274

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

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

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


def convert_to_fortran_string(string):
    """
    converts some parameter strings to the format for the inpgen
    :param string: some string
    :returns: string in right format (extra "")
    """
    new_string = '"' + string + '"'
    return new_string


def combine(default, override):
    """
    Returns a combined dictionary of the 2 dictionaries given (with the 2nd
    overriding the 1st).
    Examples:
    >>> combine({'a': 1, 'b': 2}, {'b': 3, 'c': 4}) == {'a': 1, 'b': 3, 'c': 4}
    True
    """
    combined = default.copy()
    combined.update(override)
    return combined


def discretiseRegularXi(GF, D):
    """
    regular discretisation in Xi space
    """
    pass


@staticmethod
def combine_schema_and_table_name(schema, table):
    """
        Creates a full table name by combining a schema and table.

        `Args:`
            schema: str
                The schema name
            table: str
                The table name
        `Returns:`
            str
                The combined full table name
        """
    return f'{schema}.{table}'


@staticmethod
def _symbol_to_tuple(re_sym):
    """
        Returns a tuple of properties of the given PyELF symbol.
        This is unique enough as a key for both symbol lookup and retrieval.
        """
    entry = re_sym.entry
    return (entry.st_name, entry.st_value, entry.st_size, entry.st_info.
        bind, entry.st_info.type, entry.st_shndx)


def HTML_Desc(Title, Description, file):
    """
    Write model description in html file.

    :param Title: simulation title (analysis model)
    :type Title : str
    :param Description: model description
    :type Description : str
    :param file: html file object
    :type file : file object
    :return: None
    """
    file.write('
What is ' + Title + ' ?
\n')
    file.write('
' +
        Description + '
\n')


@classmethod
def unpack_scalar(cls, dataset, data):
    """
        Given a dataset object and data in the appropriate format for
        the interface, return a simple scalar.
        """
    if len(data.data_vars) == 1 and len(data[dataset.vdims[0].name].shape
        ) == 0:
        return data[dataset.vdims[0].name].item()
    return data


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 runtest_makereport(item, call, rep):
    """Store item in the report object."""
    try:
        scenario_report = item.__scenario_report__
    except AttributeError:
        pass
    else:
        rep.scenario = scenario_report.serialize()
        rep.item = {'name': item.name}


def format_list(data):
    """Return a formatted strings

    :param data: a list of strings
    :rtype: a string formatted to a,b,c
    """
    return ', '.join(data)


def strip_jump(next: bool=True, center: bool=True):
    """Move frame to previous edit point

    :param next: Next Strip
    :type next: bool
    :param center: Use strip center
    :type center: bool
    """
    pass


def determine_if_sne_are_discovered(log, limitingMags, ripeDayList,
    cadenceDictionary, observedFrameLightCurveInfo, extraSurveyConstraints,
    plot=True):
    """
    *Generate a list of dictionaries which describe if and when a SN is discovered in each and any filter.*

    **Key Arguments:**
        - ``log`` -- logger
        - ``limitingMags`` -- the limiting magnitudes of the survey
        - ``ripeDayList`` -- a list of dictionaries describing the time relative to peak that the SN reaches the limiting mag of the survey
        - ``cadenceDictionary``  -- a dictionary of { band : observedDayList }
        - ``observedFrameLightCurveInfo`` -- the observed franme lightcurve info (dictionary)
        - ``extraConstraints`` -- some extra constraints
        - ``plot`` -- generate plots?

    **Return:**
        - ``discoveredList`` -- a list of dictionaries which describe if and when a SN is discovered in each and any filter.
    """
    import numpy as np
    filters = ['g', 'r', 'i', 'z']
    models = ['he80', 'he100', 'he130']
    lunarMonth = 29.3
    surveyYear = 12.0 * lunarMonth
    surveyDiscoveryDayList = []
    lightCurveDiscoveryDayList = []
    snCampaignLengthList = []
    log.info('ripeDayList %s' % (len(ripeDayList),))
    for item in range(len(ripeDayList)):
        lightCurveEndDay = observedFrameLightCurveInfo[item][
            'endOfLightcurveDay']
        visibleDay = np.random.rand() * surveyYear
        surveyDiscoveryDayDict = {}
        lightCurveDiscoverDayDict = {}
        snCampaignLengthDict = {}
        if not ripeDayList[item]['any']:
            surveyDiscoveryDayDict['any'] = False
            lightCurveDiscoverDayDict['any'] = False
            snCampaignLengthDict['any'] = False
            for ffilter in filters:
                lightCurveDiscoverDayDict[ffilter] = False
                surveyDiscoveryDayDict[ffilter] = False
                snCampaignLengthDict[ffilter] = False
            lightCurveDiscoveryDayList.append(lightCurveDiscoverDayDict)
            surveyDiscoveryDayList.append(surveyDiscoveryDayDict)
            snCampaignLengthList.append(snCampaignLengthDict)
        else:
            for ffilter in filters:
                if not ripeDayList[item][ffilter]:
                    surveyDiscoveryDayDict[ffilter] = False
                    lightCurveDiscoverDayDict[ffilter] = False
                    snCampaignLengthDict[ffilter] = False
                else:
                    if visibleDay > max(cadenceDictionary[ffilter]):
                        waitingTime = surveyYear + min(cadenceDictionary[
                            ffilter]) - visibleDay
                        surveyDiscoveryDayDict[ffilter] = min(cadenceDictionary
                            [ffilter])
                        cdIndex = 0
                    else:
                        cdIndex = -1
                        for day in cadenceDictionary[ffilter]:
                            cdIndex += 1
                            if day > visibleDay:
                                waitingTime = day - visibleDay
                                surveyDiscoveryDayDict[ffilter] = day
                                break
                    lightCurveDiscoverDayDict[ffilter] = ripeDayList[item][
                        ffilter] + waitingTime
                    if observedFrameLightCurveInfo[item]['lightCurves'][ffilter
                        ](lightCurveDiscoverDayDict[ffilter]) > limitingMags[
                        ffilter]:
                        lightCurveDiscoverDayDict[ffilter] = False
                        surveyDiscoveryDayDict[ffilter] = False
                        snCampaignLengthDict[ffilter] = False
                    else:
                        snCampaignLengthDict[ffilter] = 0
                        lcDay = lightCurveDiscoverDayDict[ffilter]
                        cdIndex += 1
                        while 1 > 0:
                            if cdIndex >= len(cadenceDictionary[ffilter]):
                                log.info(
                                    'item: %s. NEXT YEAR: cdIndex %s, len(cadenceDictionary[ffilter]) %s'
                                     % (item, cdIndex, len(
                                    cadenceDictionary[ffilter])))
                                nextLcDay = lcDay + surveyYear + min(
                                    cadenceDictionary[ffilter]) - max(
                                    cadenceDictionary[ffilter])
                                cdIndex = 1
                            else:
                                log.info(
                                    'item: %s. SAME YEAR: cdIndex %s, len(cadenceDictionary[ffilter]) %s'
                                     % (item, cdIndex, len(
                                    cadenceDictionary[ffilter])))
                                nextLcDay = lcDay + cadenceDictionary[ffilter][
                                    cdIndex] - cadenceDictionary[ffilter][
                                    cdIndex - 1]
                                cdIndex += 1
                            if observedFrameLightCurveInfo[item]['lightCurves'
                                ][ffilter](nextLcDay) < limitingMags[ffilter
                                ] and lightCurveEndDay > nextLcDay:
                                snCampaignLengthDict[ffilter
                                    ] += nextLcDay - lcDay
                                log.info('campaign length %s, filter %s' %
                                    (snCampaignLengthDict[ffilter], ffilter))
                                lcDay = nextLcDay
                            else:
                                break
            surveyDiscoveryDayDict['any'] = False
            lightCurveDiscoverDayDict['any'] = False
            snCampaignLengthDict['max'] = 0
            for ffilter in filters:
                if surveyDiscoveryDayDict[ffilter]:
                    surveyDiscoveryDayDict['any'] = True
                    lightCurveDiscoverDayDict['any'] = True
                if snCampaignLengthDict[ffilter] > snCampaignLengthDict['max']:
                    snCampaignLengthDict['max'] = snCampaignLengthDict[ffilter]
            lightCurveDiscoveryDayList.append(lightCurveDiscoverDayDict)
            surveyDiscoveryDayList.append(surveyDiscoveryDayDict)
            snCampaignLengthList.append(snCampaignLengthDict)
    return (lightCurveDiscoveryDayList, surveyDiscoveryDayList,
        snCampaignLengthList)


def _np_prod(a, axis=None, dtype=None, out=None, keepdims=False):
    """
    Return the product of array elements over a given axis.

    Parameters
    ----------
    a : ndarray
        Input data.
    axis : None or int or tuple of ints, optional
        Axis or axes along which a product is performed.
        The default (`axis` = `None`) is perform a product over all
        the dimensions of the input array. `axis` may be negative, in
        which case it counts from the last to the first axis.
        If this is a tuple of ints, a product is performed on multiple
        axes, instead of a single axis or all the axes as before.
    dtype : data-type, optional
        The data-type of the returned array, as well as of the accumulator
        in which the elements are multiplied.  By default, if `a` is of
        integer type, `dtype` is the default platform integer. (Note: if
        the type of `a` is unsigned, then so is `dtype`.)  Otherwise,
        the dtype is the same as that of `a`.
    out : ndarray, optional
        Alternative output array in which to place the result. It must have
        the same shape as the expected output, but the type of the
        output values will be cast if necessary.
    keepdims : bool, optional
        If this is set to True, the axes which are reduced are left
        in the result as dimensions with size one. With this option,
        the result will broadcast correctly against the original `arr`.

    Returns
    -------
    product_along_axis : ndarray, see `dtype` parameter above.
        An array shaped as `a` but with the specified axis removed.
        Returns a reference to `out` if specified.

    See Also
    --------
    ndarray.prod : equivalent method

    Notes
    -----
    Arithmetic is modular when using integer types, and no error is
    raised on overflow.  That means that, on a 32-bit platform:

    >>> x = np.array([536870910, 536870910, 536870910, 536870910])
    >>> np.prod(x) #random
    array(8.307675e+34)

    Examples
    --------
    By default, calculate the product of all elements:

    >>> np.prod(np.array([1.,2.]))
    array(2.)

    Even when the input array is two-dimensional:

    >>> np.prod(np.array([1.,2.,3.,4.]).reshape((2,2)))
    array(24.)

    But we can also specify the axis over which to multiply:

    >>> np.prod(np.array([1.,2.,3.,4.]).reshape((2,2)), axis=1)
    array([  2.,  12.])

    If the type of `x` is unsigned, then the output type is
    the unsigned platform integer:

    >>> x = np.array([1, 2, 3], dtype=np.uint8)
    >>> np.prod(x).dtype == np.uint8
    True

    If `x` is of a signed integer type, then the output type
    is the default platform integer:

    >>> x = np.array([1, 2, 3], dtype=np.int8)
    >>> np.prod(x).dtype == np.int8
    True
    """
    pass


def save_blob(session, localfile=None, resource=None):
    """
        put a local image on the server and return the URL
        to the METADATA XML record

        @param session: the local session
        @param image: an BQImage object
        @param localfile:  a file-like object or name of a localfile
        @return XML content  when upload ok

        @exceptions comm.BQCommError - if blob is failed to be posted
    """
    content = session.postblob(localfile, xml=resource)
    content = session.factory.string2etree(content)
    if len(content) < 1:
        return None
    return content[0]


def interleaved2complex(data):
    """
    Make a complex array from interleaved data

    """
    return data[(...), ::2] + 1.0j * data[(...), 1::2]


def create_hkl_group(py_obj, h_group, call_id=0):
    """ Create a new group within the hickle file

    Args:
        h_group (h5.File.group): group to dump data into.
        call_id (int): index to identify object's relative location in the iterable.

    """
    h_subgroup = h_group.create_group('data_%i' % call_id)
    h_subgroup.attrs['type'] = [str(type(py_obj))]
    return h_subgroup


def generate_action_buttons_html(object_id, name, description, modal_id,
    delete_function_name):
    """Generates HTML for action buttons.

    Action button - 'Edit' and 'Delete' used in
    pictures' management tab and albums' management tab
    in administrator's panel.
    """
    edit_button = '<button {}>Edit</button>'.format('type="button" ' +
        'class="btn-xs btn-default" ' + 'data-toggle="modal" ' +
        'data-target="#' + modal_id + '" ' + 'data-id="' + str(object_id) +
        '" ' + 'data-name="' + str(name) + '" ' + 'data-description="' +
        str(description) + '" ')
    delete_button = '<button {}>Delete</button>'.format(
        'class="btn-xs btn-danger" ' + 'onclick="' + delete_function_name +
        '(' + str(object_id) + ')"')
    return ('
' +
        '
' +
        '
' + edit_button + '
' +
        '
' + delete_button + '
' +
        '
' + '
')


def _display_summary(message, status, fun, iteration):
    """
    Print the termination summary of the linear program

    Parameters
    ----------
    message : str
            A string descriptor of the exit status of the optimization.
    status : int
        An integer representing the exit status of the optimization::

                0 : Optimization terminated successfully
                1 : Iteration limit reached
                2 : Problem appears to be infeasible
                3 : Problem appears to be unbounded
                4 : Serious numerical difficulties encountered

    fun : float
        Value of the objective function.
    iteration : iteration
        The number of iterations performed.
    """
    print(message)
    if status in (0, 1):
        print('         Current function value: {0: <12.6f}'.format(fun))
    print('         Iterations: {0:d}'.format(iteration))


def _alphabetize_actions(arg_parser):
    """Alphabetize arg parser actions for the sake of nicer help printouts."""
    for g in arg_parser._action_groups:
        g._group_actions.sort(key=lambda opt: opt.dest)


@classmethod
def title(cls, key):
    """Return title for key."""
    key = str(key)
    if cls.TITLES is not None and key in cls.TITLES:
        return cls.TITLES[key]
    return key.capitalize()


def init_legendre_rational(basetensor, ind, x):
    """Initialize the initial values before starting the recursion.

    Parameters
    ----------
    basetensor: numpy.ndarray
        The ``num_dims+1``- dimensional array considered, with samples
        along the first dimension. For each sample we have ``num_dims``
        -dimensional subarrays with non-zero values on the edges.
    ind: numpy.ndarray
        Instance of the class ``NDArrayManager`` created in the
        ``RecursiveExpansion.execute`` method and passed when
        calling this function.
    x: numpy.ndarray
        A two-dimensional numpy array passed to
        ``RecursiveExpansion.execute``. The recursion will be evaluated
        on the data contained. Observations of
        variables are stored in the rows of the array, individual variables
        are stored in the columns. This means that one row contains one
        particular observation/measurement of all variables, and one
        column contains all observations/measurements of one particular
        variable.
    """
    ind.zeroAllBut(0, 0)
    basetensor[ind.all + ind.getCurrent()] = 1.0
    for i in range(x.shape[1]):
        ind.zeroAllBut(i, 1)
        basetensor[ind.all + ind.getCurrent()] = (x[:, (i)] - 1.0) / (x[:,
            (i)] + 1.0)


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

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

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


def represent_as_memory_index(argument):
    """
    Format the argument so it appears as a memory index.

    See :func:`~.is_memory_index` for details on what a memory index is.

    Args:
        argument (str): The argument to represent as a memory index.
    Returns:
        str: The formatted argument.
    """
    return '[{argument}]'.format(argument=argument)


@classmethod
def keys(cls, section=None):
    """Get a list with all config keys"""
    section = section or cls._default_sect
    if section not in cls._conf:
        cls._load(section=section)
    return cls._conf[section].keys()


@classmethod
def from_string(cls, string):
    """Generate a Parameter from a query string snippet.

        Args:
            string (str): The snippet of a URL which contains a query
                parameter. Ex: id=1,2,3,$NONE

        Raises:
            ValueError: If the string is not a query string.

        Returns:
            AnyParameter: If the $ANY special token is anywhere in the value.
            SingleParameter: If there is only one value.
            MultiParameter: If there are multiple values.
        """
    if string.count('=') > 1:
        raise ValueError('Invalid query parameter string')
    if string.startswith('?'):
        string = string[1:]
    field, value = string.split('=')
    return cls(field, value)


def view_layer_add():
    """Add a view layer

    """
    pass


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
         {
            "dynamic":true,
            "properties": {
                "data": {
                    "properties": {
                        "user": {
                            "properties": {
                                "entities": {
                                    "dynamic":false,
                                    "properties": {}
                                }
                            }
                        },
                        "hashtags": {
                            "properties": {
                                "indices": {
                                    "dynamic":false,
                                    "properties": {}
                                }
                            }
                        },
                        "metadata": {
                            "dynamic":false,
                            "properties": {}
                        },
                        "entities": {
                            "properties": {
                                "media": {
                                    "dynamic":false,
                                    "properties": {}
                                },
                                "symbols": {
                                    "dynamic":false,
                                    "properties": {}
                                },
                                "urls": {
                                    "dynamic":false,
                                    "properties": {}
                                },
                                "user_mentions": {
                                    "dynamic":false,
                                    "properties": {}
                                }
                            }
                        },
                        "extended_entities": {
                            "dynamic":false,
                            "properties": {}
                        },
                        "extended_tweet": {
                            "dynamic":false,
                            "properties": {}
                        },
                        "quoted_status": {
                            "dynamic":false,
                            "properties": {}
                        },
                        "retweeted_status": {
                            "dynamic":false,
                            "properties": {}
                        }
                    }
                }
            }
        }
        """
    return {'items': mapping}


def calculate_change(old_val, new_val):
    """
    Return a float representing the decimal change between old_val and new_val.
    """
    if old_val == 0 and new_val == 0:
        return 0.0
    if old_val == 0:
        return float(new_val - old_val) / (float(old_val + new_val) / 2)
    return float(new_val - old_val) / abs(old_val)


def get_attribute_at(config, target_path, key, default_value=None):
    """
    Return attribute value at a given path

    :param config:
    :param target_path:
    :param key:
    :param default_value:
    :return:
    """
    for target in target_path:
        config = config[target]
    return config[key] if key in config else default_value


@classmethod
def is_ssid_valid(cls, ssid):
    """
        Check if the specified ssid is valid

        :param cls: A HostapdConfig class
        :param ssid: The service set identifier
        :type cls: HostapdConfig class
        :type ssid: str
        :return: True if the ssid is valid
        :rtype: bool
        """
    return bool(len(ssid) < 33)


def mimetype_to_icon(mtype):
    """Converts a file mime type into an icon
	to be displayed next to the file name.
	"""
    ficon = 'fa fa-fw fa-file-o'
    if mtype.startswith('image'):
        ficon = 'fa fa-fw fa-file-image-o'
    elif mtype.startswith('audio'):
        ficon = 'fa fa-fw fa-file-audio-o'
    elif mtype.startswith('video'):
        ficon = 'fa fa-fw fa-file-video-o'
    elif mtype.startswith('message'):
        ficon = 'fa fa-fw fa-envelope'
    elif mtype.startswith('application/vnd.visio'):
        ficon = 'fa fa-fw fa-sitemap'
    elif mtype.startswith('application/octet-stream'):
        ficon = 'fa fa-fw fa-cogs'
    elif mtype.startswith('application/x-gzip'):
        ficon = 'fa fa-fw fa-file-archive-o'
    elif mtype.startswith('application/x-gtar'):
        ficon = 'fa fa-fw fa-file-archive-o'
    elif mtype.startswith('application/x-tar'):
        ficon = 'fa fa-fw fa-file-archive-o'
    elif mtype.startswith('application/zip'):
        ficon = 'fa fa-fw fa-file-archive-o'
    elif mtype.startswith('application/vnd.ms-cab-compressed'):
        ficon = 'fa fa-fw fa-file-archive-o'
    elif mtype.startswith('application/x-rpm'):
        ficon = 'fa fa-fw fa-file-archive-o'
    elif mtype.startswith(
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'):
        ficon = 'fa fa-fw fa-file-excel-o'
    elif mtype.startswith('application/vnd.ms-excel'):
        ficon = 'fa fa-fw fa-file-excel-o'
    elif mtype.startswith('application/vnd.oasis.opendocument.spreadsheet'):
        ficon = 'fa fa-fw fa-table'
    elif mtype.startswith('application/msword'):
        ficon = 'fa fa-fw fa-file-word-o'
    elif mtype.startswith(
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
        ):
        ficon = 'fa fa-fw fa-file-word-o'
    elif mtype.startswith('application/vnd.oasis.opendocument.text'):
        ficon = 'fa fa-fw fa-file-text-o'
    elif mtype.startswith('application/vnd.ms-powerpoint'):
        ficon = 'fa fa-fw fa-file-powerpoint-o'
    elif mtype.startswith(
        'application/vnd.openxmlformats-officedocument.presentationml.presentation'
        ):
        ficon = 'fa fa-fw fa-file-powerpoint-o'
    elif mtype.startswith('application/vnd.oasis.opendocument.presentation'):
        ficon = 'fa fa-fw fa-slideshare'
    elif mtype.startswith('application/pdf'):
        ficon = 'fa fa-fw fa-file-pdf-o'
    elif mtype.startswith('text/html'):
        ficon = 'fa fa-fw fa-file-code-o'
    elif mtype.startswith('application/xhtml+xml'):
        ficon = 'fa fa-fw fa-file-code-o'
    elif mtype.startswith('text/css'):
        ficon = 'fa fa-fw fa-file-code-o'
    elif mtype.startswith('text/xml') or mtype.startswith('application/xml'):
        ficon = 'fa fa-fw fa-code-o'
    elif mtype.startswith('application/x-perl'):
        ficon = 'fa fa-fw fa-file-code-o'
    elif mtype.startswith('application/x-python'):
        ficon = 'fa fa-fw fa-file-code-o'
    elif mtype.startswith('text/x-python'):
        ficon = 'fa fa-fw fa-file-code-o'
    elif mtype.startswith('application/x-perl'):
        ficon = 'fa fa-fw fa-file-code-o'
    elif mtype.startswith('application/x-sh'):
        ficon = 'fa fa-fw fa-terminal'
    elif mtype.startswith('text/plain'):
        ficon = 'fa fa-fw fa-file-text-o'
    elif mtype.startswith('application'):
        ficon = 'fa fa-fw fa-cog'
    return ficon


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

        :param SharedContentRelinquishMembershipDetails val:
        :rtype: EventDetails
        """
    return cls('shared_content_relinquish_membership_details', val)


def keep_in_bound(pos, grid):
    """
    Function for truncating and bounding the random walk to within the defined grid

    @param pos: tuple of the point to be checked
    @param grid: the bounds for limiting the walk

    @return position tuple after bounding the point
    """
    pos[0] = max(pos[0], grid[0] - grid[2] / 2)
    pos[0] = min(pos[0], grid[0] + grid[2] / 2)
    pos[1] = max(pos[1], grid[1] - grid[3] / 2)
    pos[1] = min(pos[1], grid[1] + grid[3] / 2)
    return pos


def record_sink(sink_path):
    """Record an audio file using pysoundcard."""
    from aubio import sink
    from pysoundcard import Stream
    hop_size = 256
    duration = 5
    s = Stream(blocksize=hop_size, channels=1)
    g = sink(sink_path, samplerate=int(s.samplerate))
    s.start()
    total_frames = 0
    try:
        while total_frames < duration * s.samplerate:
            vec = s.read(hop_size)
            mono_vec = vec.sum(-1) / float(s.channels[0])
            g(mono_vec, hop_size)
            total_frames += hop_size
    except KeyboardInterrupt:
        duration = total_frames / float(s.samplerate)
        print('stopped after %.2f seconds' % duration)
    s.stop()


def get_frac_dels(var):
    """
    Returns the fraction of reads containing spanning deletions,
    or None if it isn't present in the VCF.
    """
    return var.INFO.get('Dels')


def extract_nothing(fileobj, keywords, comment_tags, options):
    """Pseudo extractor that does not actually extract anything, but simply
    returns an empty list.
    """
    return []


def get(old_path, default=None):
    """Get the new path to the object that used to be at old_path.

        Will return the default value (None, unless set otherwise) if old_path
        is not found.
        """


def __hash__():
    """
        This object hashes like its value.
        """


@classmethod
def _from_et(cls, root, parent):
    """
        Create a :class:`Pad` from a :code:`pad` element.

        :param root: The element tree tree to parse.
        :param parent: :class:`EagleFilePart` that should hold the resulting :class:`EagleFilePart`
        :rtype: :class:`Pad`
        """
    n = cls()
    n._init_from_et(root, parent)
    return n


def linalg_inverse(A=None, out=None, name=None, **kwargs):
    """Compute the inverse of a matrix.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, *A* is a square matrix. We compute:

      *out* = *A*\\ :sup:`-1`

    If *n>2*, *inverse* is performed separately on the trailing two dimensions
    for all inputs (batch mode).

    .. note:: The operator supports float32 and float64 data types only.

    Examples::

       Single matrix inverse
       A = [[1., 4.], [2., 3.]]
       inverse(A) = [[-0.6, 0.8], [0.4, -0.2]]

       Batch matrix inverse
       A = [[[1., 4.], [2., 3.]],
            [[1., 3.], [2., 4.]]]
       inverse(A) = [[[-0.6, 0.8], [0.4, -0.2]],
                     [[-2., 1.5], [1., -0.5]]]

    Defined in src/operator/tensor/la_op.cc:L919

    Parameters
    ----------
    A : NDArray
        Tensor of square matrix

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

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


def gross_lev(positions):
    """
    Calculates the gross leverage of a strategy.

    Parameters
    ----------
    positions : pd.DataFrame
        Daily net position values.
         - See full explanation in tears.create_full_tear_sheet.

    Returns
    -------
    pd.Series
        Gross leverage.
    """
    exposure = positions.drop('cash', axis=1).abs().sum(axis=1)
    return exposure / positions.sum(axis=1)


@classmethod
def get_asset_sensors(cls, session, asset_key):
    """Get sensors that belong to a particular asset

        Args:
            session: database session
            asset_key: key of the asset sensors belong to
        Returns:
            list: of sensor dictionaries
        """
    results = session.run(
        """
            MATCH (a:Asset { key: $key })-[:HAS_SENSOR]->(sensor:Sensor)
            OPTIONAL MATCH (sensor)-[:HAS_ADDRESS_SPACE]->(addr)
            RETURN sensor, addr
            """
        , key=int(asset_key))
    sensors = []
    for record in results:
        sensor = dict(record['sensor'])
        sensors.append({'specs': sensor, 'address_space': dict(record[
            'addr']) if 'index' in sensor else None})
    return sensors


def changeVolume(raw, scale):
    """
    Change the volume

    Parameters
    ----------
    raw: np.array
        The raw sound data
    scale: num
        The change scale

    Returns
    -------
    value: np.array
        The changed sound data
    """
    return raw * scale


def var(array, *args, **kwargs):
    """
    Computes the variance.

    See Also
    --------
    Array.var
    """
    return array.var(*args, **kwargs)


def getPost(postid, username, password):
    """Return a post as struct.
        """


def cTensorMultiply():
    """
    Return the kernel source for cTensorMultiply
    """
    code_text = """
        KERNEL void cTensorMultiply(
            const unsigned int batch, // batch
            const unsigned int dim, // dimensions
            GLOBAL_MEM const  unsigned int *Nd, // In batch mode, Nd*batch but is calculated outside the kernel
            GLOBAL_MEM const  unsigned int *Nd_elements, // Number of elements to move along the dimension = strides / itemsize
            GLOBAL_MEM const  float *invNd_elements,   //  float: inverse of the Nd_elements, which aims for fast division // batch mode: Nd_elements / batch
            GLOBAL_MEM const float *vec, // Real, vector, length sum Nd[dimid]
            GLOBAL_MEM       float2 *outdata,
            const unsigned int div)
        {
        const unsigned int gid=get_global_id(0);
        const unsigned int pid = (float)gid / (float)batch;
        // const unsigned int bat = gid - pid * batch;

        unsigned int group;
        unsigned int Nd_indx_shift = 0;
        float mul = 1.0;
        unsigned int res = pid;

        for (unsigned int dimid = 0; dimid < dim; dimid ++){
            group = (float)res * invNd_elements[dimid]; // The index along the axis
            res = res - group * Nd_elements[dimid];

            const unsigned int N = Nd[dimid];

            mul = mul * vec[group + Nd_indx_shift];

            Nd_indx_shift = Nd_indx_shift + N;
        }

        if (div == 1){
            // for (unsigned int bat = 0; bat < batch; bat ++ )
            // {
            float2 tmp = outdata[gid];
            tmp.x = tmp.x /  mul;
            tmp.y = tmp.y / mul;
            outdata[gid] = tmp;
            // };
            };
        if (div == 0){
           // for (unsigned int bat = 0; bat < batch; bat ++ )
            // {
            float2 tmp = outdata[gid];
            tmp.x = tmp.x *  mul;
            tmp.y = tmp.y * mul;
            outdata[gid] = tmp;
            // };
            };

        };
        """
    return code_text


def match(needle, haystack):
    """
    Command-T-style string matching.
    """
    score = 1
    j = 0
    last_match = 0
    needle = needle.lower()
    haystack = haystack.lower()
    for c in needle:
        while j < len(haystack) and haystack[j] != c:
            j += 1
        if j >= len(haystack):
            return 0
        score += 1 / (last_match + 1.0)
        last_match = j
        j += 1
    return score


@classmethod
def get_files(cls, request, ppm_id):
    """
        Queries P2MD for all uploaded files related to this participant.
        """
    return cls.get(request, f'/sources/api/file/{ppm_id}')


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

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


def inline_hook(tokens):
    """Removes `_inline`, `__inline`, and `__forceinline`"""
    for token in tokens:
        if token not in ('_inline', '__inline', '__forceinline'):
            yield token


def _transform_spherical_gpforce(inode_xyz, unused_inode_gp, data,
    cid_transform, coord, unused_xyz_cid0, unused_log):
    """helper method for transform_gpforce_to_globali"""
    for itime in range(data.shape[0]):
        translation = data[(itime), (inode_xyz), :3]
        rotation = data[(itime), (inode_xyz), 3:]
        translation = coord.coord_to_xyz_array(data[(itime), (inode_xyz), :3])
        rotation = coord.coord_to_xyz_array(data[(itime), (inode_xyz), 3:])
        data[(itime), (inode_xyz), :3] = translation.dot(cid_transform)
        data[(itime), (inode_xyz), 3:] = rotation.dot(cid_transform)


def escape_opaque_token(xml):
    """
    Escape raw token xml to put it in form field.

    The RealMe Java backend use this function to escape:

        org.apache.commons.lang.StringEscapeUtils.escapeHtml

    which will escape quote, while most Python libraries don't do this by default.
    So the `quote=True` arg is important.
    """
    from html import escape
    return escape(xml, quote=True)


def _parse_alpha(args):
    """
    If args is a list of a single INTEGER or NUMBER token,
    retur its value clipped to the 0..1 range
    Otherwise, return None.
    """
    if len(args) == 1 and args[0].type == 'number':
        return min(1, max(0, args[0].value))


def print_inline(data):
    """ Print a given text in a unique line. """


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

        :param files.SyncSettingsError val:
        :rtype: TeamFolderUpdateSyncSettingsError
        """
    return cls('sync_settings_error', val)


def fnv1_hash(somestr):
    """
    Translated to python from src/util/Hash.h -- note that this
    hash function is broken so we cannot use the fnvHash python library,
    since persistent data used this hash function.
    """
    fnvprime = 16777619
    fnvsize = 2 ** 32
    hval = 0
    for byte in somestr:
        hval = fnvprime * hval % fnvsize
        hval ^= byte & 255
    return hval


@staticmethod
def _foldclassname(classname, width):
    """Split `classname` in newlines if the width is wider than `width`.

        >>> fold = FoldedInheritanceGraph._foldclassname
        >>> fold('aaa.bbb.ccc', 7)
        'aaa.bbb\\n.ccc'
        >>> fold('aaa.bbb.ccc', 3)
        'aaa\\n.bbb\\n.ccc'
        >>> identity = lambda x, y: ''.join(fold(x, y).split('\\n'))
        >>> identity('aaa.bbb.ccc', 7)
        'aaa.bbb.ccc'
        >>> identity('aaa.bbb.ccc', 3)
        'aaa.bbb.ccc'
        """
    parts = classname.split('.')
    lines = []
    chunk = [parts.pop(0)]
    for part in parts:
        if len('.'.join(chunk + [part])) > width:
            lines.append('.'.join(chunk))
            chunk = [part]
        else:
            chunk.append(part)
    lines.append('.'.join(chunk))
    return '\\n.'.join(lines)


def fix_whitespace(line, offset, replacement):
    """Replace whitespace at offset and return fixed line."""
    left = line[:offset].rstrip('\n\r \t\\')
    right = line[offset:].lstrip('\n\r \t\\')
    if right.startswith('#'):
        return line
    return left + replacement + right


def process_type_args(type_args, project):
    """
    Process the HTML form arguments from the custom type object

    The processing is strictly dependant on the class of the particular parameter. For instance,
    if the argument is a str the processed one will be the value of the Project's attribute named this way.

    :param attmap.AttMap type_args: the HTML form arguments from the type object
    :param peppy.Project project: the Project in the context of which the data should be processed
    :return dict: the dict with processed values
    """
    for k, v in type_args.iteritems():
        if isinstance(v, str):
            type_args[k] = getattr(project, v)
    return type_args


@staticmethod
def dir():
    """Return the list of patched function names. Used for patching
        functions imported from the module.
        """
    return 'disk_usage',


def add_n(attrs, inputs, cls):
    """Elementwise sum of arrays"""
    return 'add_n', attrs, inputs


def log_sum_exp(x):
    """calculate log(sum(exp(x))) = max(x) + log(sum(exp(x - max(x))))
    """
    max_score = x.max(-1)[0]
    return max_score + (x - max_score.unsqueeze(-1)).exp().sum(-1).log()


def get_default_comm():
    """Define the default communicator.
    """
    from mpi4py import MPI
    return MPI.COMM_SELF


def convertStorageUnitToString(num, srcUnit):
    """Convert unit to string
    - num: value
    - srcUnit: gb/mb/kb/byte
    """
    try:
        units = ['gb', 'mb', 'kb', 'byte']
        if srcUnit not in units:
            return '0 KB'
        num = float(num)
        srcIndex = units.index(srcUnit)
        if srcIndex == 0:
            return str(round(num, 2)) + ' ' + units[0].upper()
        tmp = num
        while srcIndex != 0:
            num = num / 1024
            if num < 1:
                return str(round(tmp, 2)) + ' ' + units[srcIndex].upper()
            tmp = num
            srcIndex = srcIndex - 1
        return str(round(tmp, 2)) + ' ' + units[srcIndex].upper()
    except:
        return '0 KB'


def _sabr_implied_vol_hagan_A11(underlying, strike, maturity, alpha, beta,
    rho, nu):
    """_sabr_implied_vol_hagan_A11
    One of factor in hagan formua.
    See :py:func:`sabr_implied_vol_hagan`.

    .. math::
        A_{11} := (SK)^{(1-\\beta)/2}

    :param float underlying:
    :param float strike:
    :param float maturity:
    :param float alpha: must be within :math:`[0, 1]`.
    :param float beta: must be greater than 0.
    :param float rho: must be within :math:`[-1, 1]`.
    :param float nu: volatility of volatility. This must be positive.

    :return: value of factor.
    :rtype: float.
    """
    return (underlying * strike) ** ((1.0 - beta) / 2.0)


def _prepare_fixed_ips(client_manager, parsed_args):
    """Fix and properly format fixed_ip option.

    Appropriately convert any subnet names to their respective ids.
    Convert fixed_ips in parsed args to be in valid dictionary format:
    {'subnet': 'foo'}.
    """
    client = client_manager.network
    ips = []
    if parsed_args.fixed_ip:
        for ip_spec in parsed_args.fixed_ip:
            if 'subnet' in ip_spec:
                subnet_name_id = ip_spec['subnet']
                if subnet_name_id:
                    _subnet = client.find_subnet(subnet_name_id,
                        ignore_missing=False)
                    ip_spec['subnet_id'] = _subnet.id
                    del ip_spec['subnet']
            if 'ip-address' in ip_spec:
                ip_spec['ip_address'] = ip_spec['ip-address']
                del ip_spec['ip-address']
            ips.append(ip_spec)
    if ips:
        parsed_args.fixed_ip = ips


def remove(obj, value):
    """Remove the specified value associated with the object.

        Comparisons are made with the IKeyReference hashes.

        If `value` is not set for `obj`, raises KeyError.
        """


def execute(cur, *args):
    """Utility function to print sqlite queries before executing.

    Use instead of cur.execute().  First argument is cursor.

    cur.execute(stmt)
    becomes
    util.execute(cur, stmt)
    """
    stmt = args[0]
    if len(args) > 1:
        stmt = stmt.replace('%', '%%').replace('?', '%r')
        print(stmt % args[1])
    return cur.execute(*args)


@staticmethod
def get_name(obj):
    """Shorthand for ``obj.__class__.__name__``."""
    return obj.__class__.__name__


def read_bundled_file(name):
    """Read a file that is packaged together with this application."""
    try:
        return __loader__.get_data(name).decode('UTF-8')
    except NameError:
        with open(name, mode='r') as f:
            return f.read()


@staticmethod
def score(uri: str) ->int:
    """
        Returns a score value for the give uri. E.g. 0 for unlikely/unknown, 20 for yes, probalby thats the file format the reader can read.

        :param uri: str
        :return: int
        """
    return 0


@staticmethod
def actions():
    """Dictionary of actions that can be performed on object

        Returns:
            Dict[str, str]: Dictionary of actions that can be performed on object
        """
    return {'show': 'resource_show', 'update': 'resource_update', 'create':
        'resource_create', 'delete': 'resource_delete', 'search':
        'resource_search', 'patch': 'resource_patch', 'datastore_delete':
        'datastore_delete', 'datastore_create': 'datastore_create',
        'datastore_insert': 'datastore_insert', 'datastore_upsert':
        'datastore_upsert', 'datastore_search': 'datastore_search'}


def findtext(node):
    """Return the text() node for the input `node` or None if no text() is
    found.

    Args:
        node: An lxml etree Element node.
    """
    return next(iter(node.xpath('text()')), None)


def dec_identity(ob):
    """
    Identity decorator. If Numba is not available, this decorator is used. The
    decorator does nothing.
    """
    return ob


@classmethod
def table_name(cls):
    """
        gets the table name that this entity represents in database.

        :rtype: str
        """
    return cls.__tablename__


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

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

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


@classmethod
def list(cls, global_):
    """ Return configuration file content. """
    scope = 'global' if global_ else 'local'
    return cls._conffiles.get(scope, {})


def make_file(path):
    """Create an empty file in a given directory"""
    open(path, 'a').close()


def tick(price, tick_size=0.05):
    """
    Rounds a given price to the requested tick
    """
    return round(price / tick_size) * tick_size


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 readFile(in_path):
    """Return content of file at given path"""
    with open(in_path, 'r') as in_file:
        contents = in_file.read()
    return contents


def unsetDomainOnDeactivation(domain, event):
    """Unset the permission id up registration deactivation.

    Let's see how this notifier can be used. First we need to create an event
    using the permission instance and a registration stub:

    >>> class Registration:
    ...     def __init__(self, obj, name):
    ...         self.component = obj
    ...         self.name = name

    >>> domain1 = TranslationDomain()
    >>> domain1.domain = 'domain1'

    >>> import zope.interface.interfaces
    >>> event = zope.interface.interfaces.Unregistered(
    ...     Registration(domain1, 'domain1'))

    Now we pass the event into this function, and the id of the role should be
    set to '<domain not activated>'.

    >>> unsetDomainOnDeactivation(domain1, event)
    >>> domain1.domain
    '<domain not activated>'
    """
    domain.domain = '<domain not activated>'


def _gcd(a, b):
    """Euclidean algorithm for calculating the GCD of two numbers a, b.
    This algoritm also works for real numbers:
    Find the greatest number h such that a and b are integer multiples of h.
    """
    while a > 1e-05:
        a, b = b % a, a
    return b


def _entity_with_credentials(credentials, cli_entity_cls):
    """Create entity class using credentials. If credentials is None will
    return cli_entity_cls itself

    :param credentials: tuple (login, password)
    :param cli_entity_cls: Cli Entity Class
    :return: Cli Entity Class
    """
    if credentials is not None:
        cli_entity_cls = cli_entity_cls.with_user(*credentials)
    return cli_entity_cls


def collection(name, *varlist, **kwargs):
    """
    Defines a set of variables that are treated as a single effect with multiple DOF

    Parameters
    ----------
    name : string
        Specifies the name of the effect
    *varlist : one or more strings
        Defines a set of variables that are treated as a single effect
        with multiple degrees of freedom. The columns in the design
        matrix that are contributed by a collection effect are the design
        columns of its constituent variables in the order in which they
        appear in the definition of the collection effect.
        Default: []
    details : boolean, optional
        requests a table that shows additional details related to this
        effect.
        Default: False

    Returns
    -------
    dict

    """
    return dict(name=name, varlist=list(varlist), **kwargs)


def makeGroupBy(columns):
    """ Make a GROUP BY clause appropriate for list of columns"""
    clause = 'GROUP BY '
    for val in range(1, len(columns) + 1):
        clause += str(f'{val}, ')
    ret = clause[0:-2] + ' '
    return ret


def real_space_pixel_scales_tag_from_real_space_pixel_scales(
    real_space_pixel_scales):
    """Generate a sub-grid tag, to customize phase names based on the sub-grid size used.

    This changes the phase name 'phase_name' as follows:

    real_space_pixel_scales = None -> phase_name
    real_space_pixel_scales = 1 -> phase_name_real_space_pixel_scales_2
    real_space_pixel_scales = 4 -> phase_name_real_space_pixel_scales_4
    """
    if real_space_pixel_scales is None:
        return ''
    y = '{0:.2f}'.format(real_space_pixel_scales[0])
    x = '{0:.2f}'.format(real_space_pixel_scales[1])
    return '__rs_pix_' + y + 'x' + x


def train(init_args, train_args):
    """Train a language model."""
    from langdist.langmodel import CharLSTM
    char_lstm = CharLSTM(**init_args)
    char_lstm.train(**train_args)


@staticmethod
def isComposedResultAnError(composed_result):
    """
            Determine if the specified result is an error.
        """
    return composed_result < 0


def connected_children_names(obj, bone_name):
    """ Returns a list of bone names (in order) of the bones that form a single
        connected chain starting with the given bone as a parent.
        If there is a connected branch, the list stops there.
    """
    bone = obj.data.bones[bone_name]
    names = []
    while True:
        connects = 0
        con_name = ''
        for child in bone.children:
            if child.use_connect:
                connects += 1
                con_name = child.name
        if connects == 1:
            names += [con_name]
            bone = obj.data.bones[con_name]
        else:
            break
    return names