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


def unscale_action(action_space, scaled_action):
    """
    Rescale the action from [-1, 1] to [low, high]
    (no need for symmetric action space)

    :param action_space: (gym.spaces.box.Box)
    :param action: (np.ndarray)
    :return: (np.ndarray)
    """
    low, high = action_space.low, action_space.high
    return low + 0.5 * (scaled_action + 1.0) * (high - low)


def format(computer):
    """Method called at `slapos node format` phase.

    :param computer: slapos.format.Computer, currently formatted computer
    """


def get_data(var, calipso_scaling=False):
    """
    Reads raw data from a NetCDF.Variable instance.

    :param var: The specific Variable instance to read
    :return:  A numpy maskedarray. Missing values are False in the mask.
    """
    from jasmin_cis.utils import create_masked_array_for_missing_data
    data = var[:]
    return data


def dict_change(old, new):
    """Readable representation of dict change"""
    lines = []
    keys = set(new)
    keys.update(old)
    for key in sorted(keys):
        if key not in new:
            lines.append('%r: %r -> key removed' % (key, old[key]))
        elif key not in old:
            lines.append('%r: new key -> %r' % (key, new[key]))
        elif new[key] != old[key]:
            lines.append('%r: %r -> %r' % (key, old[key], new[key]))
    return lines


def validators_from_config(validators):
    """Consolidate (potentially hex-encoded) list of validators
    into list of binary address representations.
    """
    result = []
    for validator in validators:
        if len(validator) == 40:
            validator = validator.decode('hex')
        result.append(validator)
    return result


def duration_s(coordinate1, coordinate2):
    """
    Return the duration in seconds between two coordinate records.
    """
    return int((coordinate2.timestamp_UTC - coordinate1.timestamp_UTC).
        total_seconds())


def check_source_place_presence(net):
    """
    Check if there is a unique source place with empty connections

    Parameters
    -------------
    net
        Petri net

    Returns
    -------------
    place
        Unique source place (or None otherwise)
    """
    count_empty_input = 0
    unique_source = None
    for place in net.places:
        if len(place.in_arcs) == 0:
            count_empty_input = count_empty_input + 1
            unique_source = place
    if count_empty_input == 1:
        return unique_source
    return None


def chunkify(iterable, chunksize=10000):
    """Yield successive chunksized chunks from iterable.

    Args:
      iterable:
      chunksize:  (Default value = 10000)

    Returns:

    """
    i = 0
    chunk = []
    for item in iterable:
        chunk.append(item)
        i += 1
        if i == chunksize:
            yield chunk
            i = 0
            chunk = []
    if len(chunk) > 0:
        yield chunk


@classmethod
def new_comm_kwargs(cls, *args, **kwargs):
    """Get keyword arguments for new comm."""
    kwargs.setdefault('address', 'address')
    return args, kwargs


def psi_Ca_HSO4_OH_HMW84(T, P):
    """c-a-a': calcium bisulfate hydroxide [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def t_backtickedvar_ENCAPSED_AND_WHITESPACE(t):
    """( [^`\\\\${] | \\\\(.|\\n) | \\$(?![A-Za-z_{]) | \\{(?!\\$) )+"""
    t.lexer.lineno += t.value.count('\n')
    t.lexer.pop_state()
    return t


def add_append_list_filter(source, args, index):
    """Add the hxlappend filter to the end of the chain with an external list."""
    exclude_columns = args.get('append-list-exclude-columns%02d' % index, False
        )
    source_list_url = args.get('append-list-url%02d' % index, None)
    row_query = args.get('append-list-where%02d' % index, None)
    return source.append_external_list(source_list_url=source_list_url,
        add_columns=not exclude_columns, queries=row_query)


@staticmethod
def p_calibration_access(p):
    """calibration_access : CALIBRATION_ACCESS calibration_access_type"""
    p[0] = p[2]


def _check_tensor_is_scalar(var):
    """
    Checks if a tensor variable is scalar, raise ValueError otherwise
    """
    msg = '%(var)s is expected to be 0d tensor, got %(ndim)d'
    if var.ndim != 0:
        raise ValueError(msg % (var, var.ndim))


def disable_policy_type(RootId=None, PolicyType=None):
    """
    Disables an organizational control policy type in a root. A poicy of a certain type can be attached to entities in a root only if that type is enabled in the root. After you perform this operation, you no longer can attach policies of the specified type to that root or to any OU or account in that root. You can undo this by using the  EnablePolicyType operation.
    This operation can be called only from the organization's master account.
    See also: AWS API Documentation

    :example: response = client.disable_policy_type(
        RootId='string',
        PolicyType='SERVICE_CONTROL_POLICY'
    )

    :type RootId: string
    :param RootId: [REQUIRED]
            The unique identifier (ID) of the root in which you want to disable a policy type. You can get the ID from the ListPolicies operation.
            The regex pattern for a root ID string requires 'r-' followed by from 4 to 32 lower-case letters or digits.

    :type PolicyType: string
    :param PolicyType: [REQUIRED]
            The policy type that you want to disable in this root.

    :rtype: dict
    :return: {
        'Root': {
            'Id': 'string',
            'Arn': 'string',
            'Name': 'string',
            'PolicyTypes': [
                {
                    'Type': 'SERVICE_CONTROL_POLICY',
                    'Status': 'ENABLED'|'PENDING_ENABLE'|'PENDING_DISABLE'
                },
            ]
        }
    }

    """
    pass


@staticmethod
def construct_qos_policy_info(context, id, qos_policy, action):
    """
        #    {u'policy': {
        #               'shared': False,
        #               'tenant_id': u'c414cf57e9fc49efb8e3e0c8d4e41b33',
        #                u'name': u'qos-policy',
        #               'description': '',
        #               'rules':[],
        #               'id' :'5720800f-dece-4c9a-93d4-5dc3ef94ccb7'}}
        """
    if action == 'UPDATE':
        qos_policy = qos_policy['policy']
    qos_policy_info = {'input': {'id': id if id != 0 else qos_policy['id']}}
    input = qos_policy_info['input']
    if 'type' in qos_policy:
        input['type'] = qos_policy['type']
    if 'description' in qos_policy:
        input['description'] = qos_policy['description']
    if 'tenant_id' in qos_policy:
        input['tenant_id'] = qos_policy['tenant_id']
    if 'shared' in qos_policy:
        input['shared'] = qos_policy['shared']
    if 'name' in qos_policy:
        input['name'] = qos_policy['name']
    return qos_policy_info


def convert_cbaois_to_kpsois(cbaois):
    """Convert coordinate-based augmentables to KeypointsOnImage instances.

    Added in 0.4.0.

    Parameters
    ----------
    cbaois : list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.bbs.PolygonsOnImage or list of imgaug.augmentables.bbs.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.bbs.PolygonsOnImage or imgaug.augmentables.bbs.LineStringsOnImage
        Coordinate-based augmentables to convert, e.g. bounding boxes.

    Returns
    -------
    list of imgaug.augmentables.kps.KeypointsOnImage or imgaug.augmentables.kps.KeypointsOnImage
        ``KeypointsOnImage`` instances containing the coordinates of input
        `cbaois`.

    """
    if not isinstance(cbaois, list):
        return cbaois.to_keypoints_on_image()
    kpsois = []
    for cbaoi in cbaois:
        kpsois.append(cbaoi.to_keypoints_on_image())
    return kpsois


@classmethod
def _from_version_string(cls, s):
    """
        Parse *s* and return a _VersionInfo.
        """
    v = s.split('.')
    if len(v) == 3:
        v.append('final')
    return cls(year=int(v[0]), minor=int(v[1]), micro=int(v[2]),
        releaselevel=v[3])


@classmethod
def run_hooks(cls, hook_type, *args, **kwargs):
    """Run all hooks of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param args: args to be passed to every hook function
        :param kwargs: kwargs to be passed to every hook function
        """
    hook_funcs = cls._hooks_map.get(hook_type) or []
    for hook_func in hook_funcs:
        hook_func(*args, **kwargs)


def get_users(username):
    """Get user information from TimeSync"""
    if username:
        p_dict = [{'username': username, 'display_name': 'X. Ample User',
            'email': 'example@example.com', 'active': True, 'site_admin':
            True if username == 'admin' else False, 'site_spectator': True if
            username == 'spectator' else False, 'site_manager': True if
            username == 'manager' else False, 'created_at': '2015-02-29',
            'deleted_at': None}]
    else:
        p_dict = [{'username': 'userone', 'display_name':
            'One Is The Loneliest Number', 'email':
            'exampleone@example.com', 'active': True, 'site_admin': False,
            'site_manager': False, 'site_spectator': False, 'created_at':
            '2015-02-29', 'deleted_at': None}, {'username': 'usertwo',
            'display_name': 'Two Can Be As Bad As One', 'email':
            'exampletwo@example.com', 'active': True, 'site_admin': False,
            'site_manager': False, 'site_spectator': False, 'created_at':
            '2015-02-29', 'deleted_at': None}, {'username': 'userthree',
            'display_name': "Yes It's The Saddest Experience", 'email':
            'examplethree@example.com', 'active': True, 'site_admin': False,
            'site_manager': False, 'site_spectator': False, 'created_at':
            '2015-02-29', 'deleted_at': None}, {'username': 'userfour',
            'display_name': "You'll Ever Do", 'email':
            'examplefour@example.com', 'active': True, 'site_admin': False,
            'site_manager': False, 'site_spectator': False, 'created_at':
            '2015-02-29', 'deleted_at': None}]
    return p_dict


def keying_set_path_add():
    """Add empty path to active Keying Set

    """
    pass


def formula_2013_01_01(foyer_fiscal, period, parameters):
    """
        Taxation des revenus des valeurs et capitaux mobiliers
        """
    f2fa = foyer_fiscal('f2fa', period)
    P = parameters(period).impot_revenu.rvcm
    return f2fa * P.taux_forfaitaire


def __contains__(key):
    """Tell if a key exists in the mapping."""


def remove_elements(target, indices):
    """Remove multiple elements from a list and return result.
    This implementation is faster than the alternative below.
    Also note the creation of a new list to avoid altering the
    original. We don't have any current use for the original
    intact list, but may in the future..."""
    copied = list(target)
    for index in reversed(indices):
        del copied[index]
    return copied


def screen(image1, image2):
    """
    Superimposes two inverted images on top of each other.

    .. code-block:: python

        out = MAX - ((MAX - image1) * (MAX - image2) / MAX)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_screen(image2.im))


def currentwlock():
    """Return the wlock if it's held or None."""


def gps_delete_topic():
    """
    This deletes a Google Pub/Sub topic.

    TODO: finish this

    """


def v_lookup(version, d):
    """
    Find the value depending of current eplus version.

    Parameters
    ----------
    version: tuple of int
    d: dict
        {(0, 0): value, (x, x): value, ...}
        for version v, current value is the value of version lv such as lv <= v < lv+1
    """
    v = version[:2]
    for lv, value in sorted(d.items(), reverse=True):
        if v >= lv:
            return value


def fit(model, data_bunch, **kwargs):
    """
    Fits an H2O Model
    :param model: An H2O Model
    :param data_bunch: A DataBunch with "train" and "valid" datasets that consist of H2ODataWrapper or H2OSparklingDataWrapper
    :param kwargs: Keyword arguments to be passed to model.train
    :return: A (fitted) H2O Model
    """
    train_df = data_bunch.train.full_data.underlying
    valid_df = data_bunch.valid.full_data.underlying
    features_list = data_bunch.train.features.field_names
    targets_list = data_bunch.valid.targets.field_names[0]
    model.train(x=features_list, y=targets_list, training_frame=train_df,
        validation_frame=valid_df, **kwargs)
    return model


def rule_move_up():
    """Move boid rule up in the list

    """
    pass


def _set_string(src_dict, dst_proto, attr_name):
    """ Setter for a simple string """
    setattr(dst_proto, attr_name, str(src_dict[attr_name]))


@classmethod
def convertDistance(kls, painter, dist):
    """Convert a distance to plotter units.

        dist: eg 0.1 (fraction), 10% (percentage), 1/10 (fraction),
                 10pt, 1cm, 20mm, 1inch, 1in, 1" (size)
        painter: painter to get metrics to convert physical sizes
        """
    m = kls.distre.match(dist)
    if m is not None:
        func = kls.unit_func[m.group(2)]
        return func(m, painter)
    raise ValueError("Cannot convert distance in form '%s'" % dist)


def load_reportlab(finder, module):
    """the reportlab module loads a submodule rl_settings via exec so force
       its inclusion here"""
    finder.IncludeModule('reportlab.rl_settings')


def np2cp(u):
    """Identity function."""
    return u


def getFITSHduNames(fitsfile):
    """Return list of names to give HDUs given a FITS file."""
    nameset = set()
    names = []
    for i, hdu in enumerate(fitsfile):
        name = hdu.name
        if not name:
            name = 'hdu%i' % i
            while name in nameset:
                name += '~'
        else:
            name = name.lower()
            if 'EXTVER' in hdu.header:
                name = '%s%i' % (name, hdu.header['EXTVER'])
            if name in nameset:
                i = 2
                while name + str(i) in nameset:
                    i += 1
                name += str(i)
        nameset.add(name)
        names.append(name)
    return names


def config_dir(mkcustom=False):
    """Returns the configuration directory for custom package settings.
    """
    from acorn.utility import reporoot
    from acorn.base import testmode
    from os import path
    alternate = path.join(path.abspath(path.expanduser('~')), '.acorn')
    if testmode or not path.isdir(alternate) and not mkcustom:
        return path.join(reporoot, 'acorn', 'config')
    else:
        if mkcustom:
            from os import mkdir
            mkdir(alternate)
        return alternate


def verify_boolean(value):
    """Throws an exception if value is not a bool
    """
    if type(value) != bool:
        raise ValueError('expected boolean value.')
    return value


@staticmethod
def get_member_from_moudle(moudle, member_name):
    """
        从指定模块中获取成员对象（例如类）

        @param {Moudle} moudle - 要处理的模块对象
        @param {string} member_name - 成员对象名

        @return {object} - 返回成员对象
        """
    return getattr(moudle, member_name)


@staticmethod
def _run_cli_process(cmd, shell=True):
    """! Runs command as a process and return stdout, stderr and ret code
        @param cmd Command to execute
        @return Tuple of (stdout, stderr, returncode)
        """
    from subprocess import Popen, PIPE
    p = Popen(cmd, shell=shell, stdout=PIPE, stderr=PIPE)
    _stdout, _stderr = p.communicate()
    return _stdout, _stderr, p.returncode


def hours(daterange=None, human_resource=None, costunit=None, default=None):
    """ Returns the sum of the hours of the contained time entries, optionally only for a given human resource
            or cost unit
        """


def edited_clear():
    """Undo all edition performed on the particle system

    """
    pass


def flatten(x):
    """Flatten function
    Usage:
        out = flatten(x)
    """
    return x.contiguous().view(x.size(0), -1)


def _determine_fields_from_ions(ds, ion_list, fields, ftype, sampling_type):
    """
    Figure out what fields need to be added based on the ions present
    and the particle type

    For sph (determined by sampling_type):
    Identify if the number_density fields for the desired ions already
    exist on the dataset, and if so, just add them to the list
    of fields to be added to the ray.
    If not, add these ion fields to the dataset as particle fields,
    which prompts them being smoothed to the grid, and add the resulting
    smoothed fields (e.g. ("gas", "x_number_density")) to the list of fields
    to be added to the ray.  Include the 'temperature' field for
    calculating the width of voigt profiles in the absorption spectrum.

    For grid:
    Check if the number_density fields for these ions exist, and if so, add
    them to field list. If not, leave them off, as they'll be generated
    on the fly by SpectrumGenerator as long as we include the 'density',
    'temperature', and appropriate 'metallicity' fields.
    """
    fields_to_add_to_ds = []
    for ion in ion_list:
        atom = ion[0].capitalize()
        ion_state = ion[1]
        nuclei_field = '%s_nuclei_mass_density' % atom
        metallicity_field = '%s_metallicity' % atom
        field = '%s_p%d_number_density' % (atom, ion_state - 1)
        if ion_state == 1:
            alias_field = '%s_number_density' % atom
        else:
            alias_field = field
        if (ftype, field) not in ds.derived_field_list:
            if (ftype, alias_field) not in ds.derived_field_list:
                if sampling_type == 'particle':
                    fields_to_add_to_ds.append((atom, ion_state))
                    fields.append(('gas', field))
                else:
                    fields.append(('gas', 'density'))
                    if ('gas', metallicity_field) in ds.derived_field_list:
                        fields.append(('gas', metallicity_field))
                    elif ('gas', nuclei_field) in ds.derived_field_list:
                        fields.append(('gas', nuclei_field))
                    elif atom != 'H':
                        fields.append(('gas', 'metallicity'))
                    else:
                        pass
            else:
                fields.append(('gas', alias_field))
        else:
            fields.append(('gas', field))
    return fields, fields_to_add_to_ds


def eval_callbacks(callbacks, result):
    """Evaluate list of callbacks on result.

    The return values of the `callbacks` are ORed together to give the
    overall decision on whether or not the optimization procedure should
    continue.

    Parameters
    ----------
    * `callbacks` [list of callables]:
        Callbacks to evaluate.

    * `result` [`OptimizeResult`, scipy object]:
        Optimization result object to be stored.

    Returns
    -------
    * `decision` [bool]:
        Decision of the callbacks whether or not to keep optimizing
    """
    stop = False
    if callbacks:
        for c in callbacks:
            decision = c(result)
            if decision is not None:
                stop = stop or decision
    return stop


def month():
    """
    Return millis for a month
    :return: 30 * 24 * 60 * 60 * 1000
    """
    return 2592000000


def get_user_model():
    """
    Wrapper for get_user_model with compatibility for 1.5
    """
    try:
        from django.contrib.auth import get_user_model as _get_user_model
    except ImportError:
        from django.contrib.auth.models import User
    else:
        User = _get_user_model()
    return User


@staticmethod
def encode(error_code_protobuf_object, error_code_object: 'ErrorCode') ->None:
    """
        Encode an instance of this class into the protocol buffer object.

        The protocol buffer object in the error_code_protobuf_object argument is matched with the instance of this class in the 'error_code_object' argument.

        :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class.
        :param error_code_object: an instance of this class to be encoded in the protocol buffer object.
        :return: None
        """
    error_code_protobuf_object.error_code = error_code_object.value


def verify(xml, stream):
    """
    Verify the signaure of an XML document with the given certificate.
    Returns `True` if the document is signed with a valid signature.
    Returns `False` if the document is not signed or if the signature is
    invalid.

    :param lxml.etree._Element xml: The document to sign
    :param file stream: The private key to sign the document with

    :rtype: Boolean
    """
    import xmlsec
    signature_node = xmlsec.tree.find_node(xml, xmlsec.Node.SIGNATURE)
    if signature_node is None:
        return False
    ctx = xmlsec.SignatureContext()
    ctx.register_id(xml)
    for assertion in xml.xpath("//*[local-name()='Assertion']"):
        ctx.register_id(assertion)
    key = None
    for fmt in [xmlsec.KeyFormat.PEM, xmlsec.KeyFormat.CERT_PEM]:
        stream.seek(0)
        try:
            key = xmlsec.Key.from_memory(stream, fmt)
            break
        except ValueError:
            pass
    ctx.key = key
    try:
        ctx.verify(signature_node)
        return True
    except Exception:
        return False


def d_func(func):
    """ Mark a method as overridable from Enaml syntax.

    Parameters
    ----------
    func : FunctionType
        The function to tag as declarative.

    Returns
    -------
    result : func
        The original function tagged with the compiler metadata.

    """
    func._d_func = True
    return func


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 __zero_points__(calib):
    """
    Extracts the zero points from the HTML-code of a SVO filter web-page

    :param calib: The HTML-code of the zero-point part of a SVO filter web-page
    :type calib: str
    :return: The zero points in units of erg/cm2/s/A and in units of Jy
    :rtype: Union[float]
    """
    calib = calib.split('</table')[0]
    calib = calib.split('Zero Point')[-1]
    calib = calib.split('ZP Type')[0]
    calib = calib.split('<td nowrap>')[-8:-1]
    try:
        ergs = calib[1].split('</td')[0]
        ergs = float(ergs)
    except ValueError:
        ergs = calib[0].split('</td')[0]
        ergs = float(ergs)
    try:
        jy = calib[-2].split('</td')[0]
        jy = float(jy)
    except ValueError:
        jy = calib[-3].split('</td')[0]
        jy = float(jy)
    return ergs, jy


def nulltranslate(msgid, *args, **kwargs):
    """Workaround for non-registered translation domain to prevent breaking.
    """
    return msgid


def printContigSetup(FH, tabCount, inputBam, inputBamIndex, rmDup):
    """This needs to be able to handle GATK post-processing as well

    !!!!!!!!!!!!!!!!!!!!!!! NEEDS REFINEMENT !!!!!!!!!!!!!!!!!!!!!!!

    Does not look like that switch is properly implemented"""
    tabs = tabCount * '\t'
    alignment = True
    if alignment:
        contigBam = 'alnSampleContigBams[idx]'
    else:
        contigBam = 'contigBam'
    Str = (tabs + 'file[string] contigBams;\n' + tabs +
        """file[string] contigBamsIndex;

""" + tabs +
        '# Processed (genotyping ready) contig bams will be stored here\n' +
        tabs + """foreach contigName, idx in genomeContigs {
""" + tabs +
        '\t' + '# id for each contig\n' + tabs + '\t' +
        """# ".aln" has been removed to improve flexibility
""" + tabs +
        '\t' + 'string contigID = strcat(sample.ID,".",contigName);\n\n')
    """
    # Keep this around for if genotyping
    tabs + '	' + '# split into contig
' +
    tabs + '	' + '# Might be helpful to generate the index here
' +
    tabs + '	' + 'file contigBam <single_file_mapper; file=strcat(sample.dir,"/",contigID,".contig.bam")>;
' +
    tabs + '	' + 'file contigBamLog <single_file_mapper; file=strcat(sample.dir,"/",contigID,".contig.log")>;
' +
    tabs + '	' + '(contigBamLog,contigBam) = SamtoolsParseContig (' + inputBam + ',' + inputBamIndex + ',contigID,sample.dir,contigName);

')
    """
    rmDupStr = tabs + '\t' + '# rm dup\n' + tabs + '\t' + """file contigDupLog <single_file_mapper; file=strcat(sample.dir,"/",contigID,".contig.dup.log")>;
""" + tabs + '\t' + """file contigDupBam <single_file_mapper; file=strcat(sample.dir,"/",contigID,".contig.dup.bam")>;
""" + tabs + '\t' + """file contigDupMetrics <single_file_mapper; file=strcat(sample.dir,"/",contigID,".contig.dup.metrics")>;
""" + tabs + '\t' + '(contigDupLog,contigDupBam,contigDupMetrics) = PicardMarkDuplicates (' + contigBam + """,contigID,sample.dir);

"""
    if rmDup:
        outputBam = 'contigDupBam'
        FH.write(Str + rmDupStr)
    else:
        outputBam = contigBam
        FH.write(Str)
    return outputBam


def has_as_dict(obj):
    """Check if object has 'as_dict' method.
    """
    return hasattr(obj, 'as_dict') and callable(getattr(obj, 'as_dict', None))


def _next_rooted_tree(predecessor, p=None):
    """One iteration of the Beyer-Hedetniemi algorithm."""
    if p is None:
        p = len(predecessor) - 1
        while predecessor[p] == 1:
            p -= 1
    if p == 0:
        return None
    q = p - 1
    while predecessor[q] != predecessor[p] - 1:
        q -= 1
    result = list(predecessor)
    for i in range(p, len(result)):
        result[i] = result[i - p + q]
    return result


def limit(val, bottom=None, top=None):
    """
    Will return a copy of @val in such a way that:
    If @bottom is not None, the result will be no less than @bottom;
    If @top is not None, the result will be no more than @top.

    >>> limit(10)
    10
    >>> limit(10, 1)
    10
    >>> limit(10, 15)
    15
    >>> limit(10, 1, 8)
    8
    >>> # Can be used with anything that can be compared using max() and min()
    ... limit('6', top='3')
    '3'

    AUTHORS:
    v0.4.5+             --> pydsigner
    """
    uval = val
    if bottom is not None:
        uval = max(uval, bottom)
    if top is not None:
        uval = min(uval, top)
    return uval


def findObjectData(x):
    """For use in a lambda function to transform non-int converted data into something to plot.

    Uses so far:
        Turn Signal - 1556
        LKAS_HUD - 1042
        Gears - 956
    """
    if x == 'none' or x == 'standby' or x == 'P':
        return 0
    if x == 'left' or x == 'D':
        return 1
    else:
        return -1


@classmethod
def handle_fork(cls):
    """
        Called after a forking.  This should cleanup any remaining reactor state
        from the parent process.
        """
    pass


@classmethod
def get_active_settings(cls):
    """
        This method is used to easily retrieve the currently active settings object.
        This information is cached for a short amount of time (5 minutes) in order to
        speed up processing and reduce database load.
        Returns None, if no Setting object exists
        :return: Currently active settings object
        :rtype: Setting | None
        """
    try:
        return cls.objects.filter(active=True).first()
    except cls.DoesNotExist:
        return None


@classmethod
def from_attributes(cls, attributes, name, file_):
    """Construct from a dictionary, with some overloads available."""
    return cls.from_attributes_consume(attributes=dict(attributes), name=
        name, file_=file_)


def parents_of(item):
    """
    Returns list of parents (i.e. object.parent values) starting from the top one (Session)
    """
    parents = [item]
    current = item
    while current.parent is not None:
        parents.append(current.parent)
        current = current.parent
    return parents[::-1]


def mute(unselected: bool=False):
    """Mute (un)selected strips

    :param unselected: Unselected, Mute unselected rather than selected strips
    :type unselected: bool
    """
    pass


def chdir(dirname):
    """Changes the current working directory."""
    import os
    os.chdir(dirname)


def convert_dtypes(df, dtypes):
    """Convert the columns of a DataFrame to the types specified
    in the given dictionary, inplace.

    Args:
        df (DataFrame): The DataFrame to convert.
        dtypes (dict): Dictionary mapping columns to types.
    """
    for c in df.columns:
        try:
            df[c] = df[c].astype(dtypes[c])
        except KeyError:
            pass


def smtp_server():
    """ Return the configured SMTP server for the site.
        """


@classmethod
def is_user_authenticated(cls, user):
    """This method can be overwritten to implement custom user/session mechanizms
        currently it uses standard django.contrib.auth"""
    return user.is_authenticated() if user else False


def any(name, alternates):
    """Return a named group pattern matching list of alternates."""
    return '(?P<%s>' % name + '|'.join(alternates) + ')'


def _im_func(f):
    """Wrapper to get at the underlying function belonging to a method.

    Python 2 is slightly different because classes have "unbound methods"
    which wrap the underlying function, whereas on Python 3 they're just
    functions. (Methods work the same way on both versions.)
    """
    if hasattr(f, '__func__'):
        return f.__func__
    else:
        return f


@classmethod
def get_instance(cls, path):
    """Return Script instance associated with given path.

        Provide singletons for every script that is being updated.

        :param str path:
            path of script being updated

        :returns:
            singleton for given path
        :rtype: Script

        """
    try:
        instance = cls.instances[path]
    except KeyError:
        instance = cls(path)
        cls.instances[path] = instance
    return instance


def psi_Na_Cl_SO4_PK74(T, P):
    """c-a-a': sodium chloride sulfate [PK74]."""
    psi = 0.007
    valid = T == 298.15
    return psi, valid


def get_bug_id_from_url(url):
    """ Return the bug identifier for a given URL.

    :arg url: the url of the ticket

    """
    bugid = url.rsplit('/', 1)[-1]
    if 'id=' in url:
        bugid = url.split('id=', 1)[1]
    return bugid


def grayscale(decimal, darkest=0, lightest=255, reverse=False, lower=0, upper=1
    ):
    """
    Converts a decimal value to a hex RGB grayscale value
    between a max and min shade (default is 0-255).

    By default, lower values mean lighter shades of gray.
    The function will return a value based on the location of the input
    between the given lower and upper values for input
    (by default 0 and 1, respectively)
    """
    if decimal < lower or decimal > upper:
        return '#FFFFFF'
    scale = upper - lower
    percent = (decimal - lower) / scale
    if reverse == False:
        percent = 1 - percent
    shade_scale = lightest - darkest
    value = percent * shade_scale + darkest
    temp_string = hex(int(value))
    hex_scale = temp_string.split('x')[1]
    while len(hex_scale) < 2:
        hex_scale = '0' + hex_scale
    hex_string = '#' + hex_scale * 3
    return hex_string


def get_password(connection, digest):
    """Query the database for the digest and return the plaintext password.

  Parameters:
    - connection: The connection to the SQLite database.
    - digest: The digest of the plaintext word.

  Returns:
    - The plaintext password associated with the given digest.

  """
    cursor = connection.cursor()
    _t = digest,
    cursor.execute('SELECT word FROM rainbow WHERE digest=?', _t)
    return cursor.fetchone()


def batch(order_by=(), start=0, limit=20):
    """
        return a batch of contents with the given offset and size, and ordered
        by given listing of columns
        """


def sftp_upload(sftp, local_path, remote_path):
    """Upload binary file `reader` to `path` using `sftp` connection."""
    print('gj$ # sftp.put', local_path, remote_path)
    sftp.put(local_path, remote_path)


@classmethod
def get_context_id(cls):
    """Returns a unique, hashable identifier identifying the current call context."""
    return cls.get_context().id


def zipmap(keys, vals):
    """
    Return a ``dict`` with the keys mapped to the corresponding ``vals``.
    """
    return dict(zip(keys, vals))


def prepare_relational_field_to_karat(instance, field):
    """ get data of instance at the end of relational field
    """
    fields = field.split('__')
    field_data = instance
    for field in fields:
        if field == 'id':
            field_data = getattr(field_data, field, None)
            field_data = str(field_data).zfill(8)
        else:
            field_data = getattr(field_data, field, None)
    return field_data


def set_status(pipelineId=None, objectIds=None, status=None):
    """
    Requests that the status of the specified physical or logical pipeline objects be updated in the specified pipeline. This update might not occur immediately, but is eventually consistent. The status that can be set depends on the type of object (for example, DataNode or Activity). You cannot perform this operation on FINISHED pipelines and attempting to do so returns InvalidRequestException .
    See also: AWS API Documentation

    :example: response = client.set_status(
        pipelineId='string',
        objectIds=[
            'string',
        ],
        status='string'
    )

    :type pipelineId: string
    :param pipelineId: [REQUIRED]
            The ID of the pipeline that contains the objects.

    :type objectIds: list
    :param objectIds: [REQUIRED]
            The IDs of the objects. The corresponding objects can be either physical or components, but not a mix of both types.
            (string) --

    :type status: string
    :param status: [REQUIRED]
            The status to be set on all the objects specified in objectIds . For components, use PAUSE or RESUME . For instances, use TRY_CANCEL , RERUN , or MARK_FINISHED .

    """
    pass


@classmethod
def from_data(cls, data):
    """Construct a duration from its data representation.

        Parameters
        ----------
        data : :obj:`dict`
            The data dictionary.

        Returns
        -------
        :class:`Duration`
             An instance of :class:`Duration`.
        """
    duration = cls(0, 0)
    duration.data = data
    return duration


def get_model_view_matrix() ->'mathutils.Matrix':
    """Return a copy of the model-view matrix.

    :return:  A 4x4 view matrix.
    """
    pass


def assign_type(mol, force_recalc=False):
    """ PATTY [Bush et al. J. Inf. Comput. Sci 33 (1993) 756-762]
    TODO: not yet implemented

    1:cation 2:anion 3:donor 4:acceptor
    5:polar 6:hydrophobe 7:others
    """
    if 'PATTY' in mol.descriptors and not force_recalc:
        return
    mol.require('Phys_charge')
    for i, atom in mol.atoms_iter():
        nbrcnt = mol.neighbor_count(i)
        if (atom.charge > 0 or atom.charge_phys > 0 or atom.charge_conj > 0 and
            not atom.n_oxide):
            atom.type = 1
        elif atom.charge < 0 or atom.charge_phys < 0 or atom.charge_conj < 0 and not atom.n_oxide:
            atom.type = 2
        elif atom.symbol == 'N':
            if nbrcnt in (1, 2):
                if atom.pi == 2:
                    atom.type = 3
                elif atom.pi == 1:
                    atom.type = 4
        elif atom.symbol == 'O':
            if nbrcnt == 1 and not atom.pi:
                atom.type = 5
            else:
                atom.type = 4
        elif atom.symbol in ('C', 'Si', 'S', 'Se', 'P', 'As'):
            ewg = False
            for n, bond in mol.neighbors(i).items():
                natom = mol.atom(n)
                if natom.symbol in ('N', 'O', 'S') and atom.pi and not (
                    natom.pi == 2 and mol.neighbor_count(n) == 3):
                    ewg = True
                    break
            if not ewg:
                atom.type = 6
        elif atom.symbol in ('F', 'Cl', 'Br', 'I') and nbrcnt == 1:
            atom.type = 6
    mol.descriptors.add('PATTY')


@staticmethod
def iterate_beta(beta, acceptance_ratio):
    """
        Apply algorithm from Hukushima but reversed to maintain one replica at T=1.

        Parameters
        ----------
        beta : ndarray
            Inverse temperature.
        acceptance_ratio : ndarray
            Estimate of acceptance ratio.

        Returns
        -------
        ndarray
            New beta.
        """
    assert len(acceptance_ratio) + 1 == len(beta)
    assert (acceptance_ratio <= 1).all()
    newBeta = beta.copy()
    avg = acceptance_ratio.mean()
    for i in range(len(beta) - 1, 0, -1):
        newBeta[i - 1] = newBeta[i] - (beta[i] - beta[i - 1]
            ) * acceptance_ratio[i - 1] / avg
    return newBeta


def is_boolean(value):
    """Checks if `value` is a boolean value.

    Args:
        value (mixed): Value to check.

    Returns:
        bool: Whether `value` is a boolean.

    Example:

        >>> is_boolean(True)
        True
        >>> is_boolean(False)
        True
        >>> is_boolean(0)
        False

    .. versionadded:: 1.0.0

    .. versionchanged:: 3.0.0
        Added ``is_bool`` as alias.

    .. versionchanged:: 4.0.0
        Removed alias ``is_bool``.
    """
    return isinstance(value, bool)


def exempt_from_requirements(f):
    """
    Used to exempt a route handler from ambient requirement handling unless it
    is explicitly decorated with a requirement runner::

        @bp.route('/')
        @exempt_from_requirements
        def greeting_area():
            return "Hello!"

    To use with a class based view, apply it to the class level decorators
    attribute::

        class SomeCBV(View):
            decorators = [exempt_from_requirements]

            def get(self):
                return "Hello!"

    .. note::

        You cannot exempt individual methods of a class based view with this
        decorator, e.g. the follow will not work::

            class SomeCBV(MethodView):

                @exempt_from_requirements
                def get(self):
                    return "Hello!"

        Any permissioning applied at the blueprint level would still affect
        this route.

    :param f: The route handler to be decorated.

    .. versionadded:: 0.7.0
    """
    f.__allows_exempt__ = True
    return f


def retrieve_permission(pid: str, **filters):
    """

    DynamoDB Integration:
    ---

    if not all(required_fields):
        raise KeyError("NAMESPACE & ACTION fields are required")

    try:
        if pid == '__all__':

            return permission_table.query(
                    Key=Key('namespace').between('A', 'Z')
                    ProjectionExpression="namespace, action"
                )
            .

        return permission_table.get_item(Key={"pid": {"S": pid}})

    except Exception as e:
        print(e)

        return []
    """
    if pid == '__all__':
        pid = 'some-pid'
    return [{'pid': pid, 'namespace': 'test_namespace', 'action':
        'test_action', 'permission': 'test_namespace:test_action'}]


def _invert_signs(signs):
    """ Shall we invert signs?
    Invert if first (most probable) term is negative.
    """
    return signs[0] < 0


def create_preset(Name=None, Description=None, Container=None, Video=None,
    Audio=None, Thumbnails=None):
    """
    The CreatePreset operation creates a preset with settings that you specify.
    Elastic Transcoder uses the H.264 video-compression format. For more information, see the International Telecommunication Union publication Recommendation ITU-T H.264: Advanced video coding for generic audiovisual services .
    See also: AWS API Documentation

    :example: response = client.create_preset(
        Name='string',
        Description='string',
        Container='string',
        Video={
            'Codec': 'string',
            'CodecOptions': {
                'string': 'string'
            },
            'KeyframesMaxDist': 'string',
            'FixedGOP': 'string',
            'BitRate': 'string',
            'FrameRate': 'string',
            'MaxFrameRate': 'string',
            'Resolution': 'string',
            'AspectRatio': 'string',
            'MaxWidth': 'string',
            'MaxHeight': 'string',
            'DisplayAspectRatio': 'string',
            'SizingPolicy': 'string',
            'PaddingPolicy': 'string',
            'Watermarks': [
                {
                    'Id': 'string',
                    'MaxWidth': 'string',
                    'MaxHeight': 'string',
                    'SizingPolicy': 'string',
                    'HorizontalAlign': 'string',
                    'HorizontalOffset': 'string',
                    'VerticalAlign': 'string',
                    'VerticalOffset': 'string',
                    'Opacity': 'string',
                    'Target': 'string'
                },
            ]
        },
        Audio={
            'Codec': 'string',
            'SampleRate': 'string',
            'BitRate': 'string',
            'Channels': 'string',
            'AudioPackingMode': 'string',
            'CodecOptions': {
                'Profile': 'string',
                'BitDepth': 'string',
                'BitOrder': 'string',
                'Signed': 'string'
            }
        },
        Thumbnails={
            'Format': 'string',
            'Interval': 'string',
            'Resolution': 'string',
            'AspectRatio': 'string',
            'MaxWidth': 'string',
            'MaxHeight': 'string',
            'SizingPolicy': 'string',
            'PaddingPolicy': 'string'
        }
    )

    :type Name: string
    :param Name: [REQUIRED]
            The name of the preset. We recommend that the name be unique within the AWS account, but uniqueness is not enforced.

    :type Description: string
    :param Description: A description of the preset.

    :type Container: string
    :param Container: [REQUIRED]
            The container type for the output file. Valid values include flac , flv , fmp4 , gif , mp3 , mp4 , mpg , mxf , oga , ogg , ts , and webm .

    :type Video: dict
    :param Video: A section of the request body that specifies the video parameters.
            Codec (string) --The video codec for the output file. Valid values include gif , H.264 , mpeg2 , vp8 , and vp9 . You can only specify vp8 and vp9 when the container type is webm , gif when the container type is gif , and mpeg2 when the container type is mpg .
            CodecOptions (dict) --
            Profile (H.264/VP8/VP9 Only)
            The H.264 profile that you want to use for the output file. Elastic Transcoder supports the following profiles:
            baseline : The profile most commonly used for videoconferencing and for mobile applications.
            main : The profile used for standard-definition digital TV broadcasts.
            high : The profile used for high-definition digital TV broadcasts and for Blu-ray discs.
            Level (H.264 Only)
            The H.264 level that you want to use for the output file. Elastic Transcoder supports the following levels:
            1 , 1b , 1.1 , 1.2 , 1.3 , 2 , 2.1 , 2.2 , 3 , 3.1 , 3.2 , 4 , 4.1MaxReferenceFrames (H.264 Only)
            Applicable only when the value of Video:Codec is H.264. The maximum number of previously decoded frames to use as a reference for decoding future frames. Valid values are integers 0 through 16, but we recommend that you not use a value greater than the following:
            Min(Floor(Maximum decoded picture buffer in macroblocks * 256 / (Width in pixels * Height in pixels)), 16)
            where Width in pixels and Height in pixels represent either MaxWidth and MaxHeight, or Resolution. Maximum decoded picture buffer in macroblocks depends on the value of the Level object. See the list below. (A macroblock is a block of pixels measuring 16x16.)
            1 - 396
            1b - 396
            1.1 - 900
            1.2 - 2376
            1.3 - 2376
            2 - 2376
            2.1 - 4752
            2.2 - 8100
            3 - 8100
            3.1 - 18000
            3.2 - 20480
            4 - 32768
            4.1 - 32768
            MaxBitRate (Optional, H.264/MPEG2/VP8/VP9 only)
            The maximum number of bits per second in a video buffer; the size of the buffer is specified by BufferSize . Specify a value between 16 and 62,500. You can reduce the bandwidth required to stream a video by reducing the maximum bit rate, but this also reduces the quality of the video.
            BufferSize (Optional, H.264/MPEG2/VP8/VP9 only)
            The maximum number of bits in any x seconds of the output video. This window is commonly 10 seconds, the standard segment duration when you're using FMP4 or MPEG-TS for the container type of the output video. Specify an integer greater than 0. If you specify MaxBitRate and omit BufferSize , Elastic Transcoder sets BufferSize to 10 times the value of MaxBitRate .
            InterlacedMode (Optional, H.264/MPEG2 Only)
            The interlace mode for the output video.
            Interlaced video is used to double the perceived frame rate for a video by interlacing two fields (one field on every other line, the other field on the other lines) so that the human eye registers multiple pictures per frame. Interlacing reduces the bandwidth required for transmitting a video, but can result in blurred images and flickering.
            Valid values include Progressive (no interlacing, top to bottom), TopFirst (top field first), BottomFirst (bottom field first), and Auto .
            If InterlaceMode is not specified, Elastic Transcoder uses Progressive for the output. If Auto is specified, Elastic Transcoder interlaces the output.
            ColorSpaceConversionMode (Optional, H.264/MPEG2 Only)
            The color space conversion Elastic Transcoder applies to the output video. Color spaces are the algorithms used by the computer to store information about how to render color. Bt.601 is the standard for standard definition video, while Bt.709 is the standard for high definition video.
            Valid values include None , Bt709toBt601 , Bt601toBt709 , and Auto .
            If you chose Auto for ColorSpaceConversionMode and your output is interlaced, your frame rate is one of 23.97 , 24 , 25 , 29.97 , 50 , or 60 , your SegmentDuration is null, and you are using one of the resolution changes from the list below, Elastic Transcoder applies the following color space conversions:
            Standard to HD, 720x480 to 1920x1080 - Elastic Transcoder applies Bt601ToBt709
            Standard to HD, 720x576 to 1920x1080 - Elastic Transcoder applies Bt601ToBt709
            HD to Standard, 1920x1080 to 720x480 - Elastic Transcoder applies Bt709ToBt601
            HD to Standard, 1920x1080 to 720x576 - Elastic Transcoder applies Bt709ToBt601
            Note
            Elastic Transcoder may change the behavior of the ColorspaceConversionMode Auto mode in the future. All outputs in a playlist must use the same ColorSpaceConversionMode .
            If you do not specify a ColorSpaceConversionMode , Elastic Transcoder does not change the color space of a file. If you are unsure what ColorSpaceConversionMode was applied to your output file, you can check the AppliedColorSpaceConversion parameter included in your job response. If your job does not have an AppliedColorSpaceConversion in its response, no ColorSpaceConversionMode was applied.
            ChromaSubsampling
            The sampling pattern for the chroma (color) channels of the output video. Valid values include yuv420p and yuv422p .
            yuv420p samples the chroma information of every other horizontal and every other vertical line, yuv422p samples the color information of every horizontal line and every other vertical line.LoopCount (Gif Only)
            The number of times you want the output gif to loop. Valid values include Infinite and integers between 0 and 100 , inclusive.
            (string) --
            (string) --

            KeyframesMaxDist (string) --Applicable only when the value of Video:Codec is one of H.264 , MPEG2 , or VP8 .
            The maximum number of frames between key frames. Key frames are fully encoded frames; the frames between key frames are encoded based, in part, on the content of the key frames. The value is an integer formatted as a string; valid values are between 1 (every frame is a key frame) and 100000, inclusive. A higher value results in higher compression but may also discernibly decrease video quality.
            For Smooth outputs, the FrameRate must have a constant ratio to the KeyframesMaxDist . This allows Smooth playlists to switch between different quality levels while the file is being played.
            For example, an input file can have a FrameRate of 30 with a KeyframesMaxDist of 90. The output file then needs to have a ratio of 1:3. Valid outputs would have FrameRate of 30, 25, and 10, and KeyframesMaxDist of 90, 75, and 30, respectively.
            Alternately, this can be achieved by setting FrameRate to auto and having the same values for MaxFrameRate and KeyframesMaxDist .
            FixedGOP (string) --Applicable only when the value of Video:Codec is one of H.264 , MPEG2 , or VP8 .
            Whether to use a fixed value for FixedGOP . Valid values are true and false :
            true : Elastic Transcoder uses the value of KeyframesMaxDist for the distance between key frames (the number of frames in a group of pictures, or GOP).
            false : The distance between key frames can vary.
            Warning
            FixedGOP must be set to true for fmp4 containers.
            BitRate (string) --The bit rate of the video stream in the output file, in kilobits/second. Valid values depend on the values of Level and Profile . If you specify auto , Elastic Transcoder uses the detected bit rate of the input source. If you specify a value other than auto , we recommend that you specify a value less than or equal to the maximum H.264-compliant value listed for your level and profile:
            Level - Maximum video bit rate in kilobits/second (baseline and main Profile) : maximum video bit rate in kilobits/second (high Profile)
            1 - 64 : 80
            1b - 128 : 160
            1.1 - 192 : 240
            1.2 - 384 : 480
            1.3 - 768 : 960
            2 - 2000 : 2500
            3 - 10000 : 12500
            3.1 - 14000 : 17500
            3.2 - 20000 : 25000
            4 - 20000 : 25000
            4.1 - 50000 : 62500
            FrameRate (string) --The frames per second for the video stream in the output file. Valid values include:
            auto , 10 , 15 , 23.97 , 24 , 25 , 29.97 , 30 , 60
            If you specify auto , Elastic Transcoder uses the detected frame rate of the input source. If you specify a frame rate, we recommend that you perform the following calculation:
            Frame rate = maximum recommended decoding speed in luma samples/second / (width in pixels * height in pixels)
            where:
            width in pixels and height in pixels represent the Resolution of the output video.
            maximum recommended decoding speed in Luma samples/second is less than or equal to the maximum value listed in the following table, based on the value that you specified for Level.
            The maximum recommended decoding speed in Luma samples/second for each level is described in the following list (Level - Decoding speed ):
            1 - 380160
            1b - 380160
            1.1 - 76800
            1.2 - 1536000
            1.3 - 3041280
            2 - 3041280
            2.1 - 5068800
            2.2 - 5184000
            3 - 10368000
            3.1 - 27648000
            3.2 - 55296000
            4 - 62914560
            4.1 - 62914560
            MaxFrameRate (string) --If you specify auto for FrameRate , Elastic Transcoder uses the frame rate of the input video for the frame rate of the output video. Specify the maximum frame rate that you want Elastic Transcoder to use when the frame rate of the input video is greater than the desired maximum frame rate of the output video. Valid values include: 10 , 15 , 23.97 , 24 , 25 , 29.97 , 30 , 60 .
            Resolution (string) --
            Warning
            To better control resolution and aspect ratio of output videos, we recommend that you use the values MaxWidth , MaxHeight , SizingPolicy , PaddingPolicy , and DisplayAspectRatio instead of Resolution and AspectRatio . The two groups of settings are mutually exclusive. Do not use them together.
            The width and height of the video in the output file, in pixels. Valid values are auto and width x height :
            auto : Elastic Transcoder attempts to preserve the width and height of the input file, subject to the following rules.
            ``width x height `` : The width and height of the output video in pixels.
            Note the following about specifying the width and height:
            The width must be an even integer between 128 and 4096, inclusive.
            The height must be an even integer between 96 and 3072, inclusive.
            If you specify a resolution that is less than the resolution of the input file, Elastic Transcoder rescales the output file to the lower resolution.
            If you specify a resolution that is greater than the resolution of the input file, Elastic Transcoder rescales the output to the higher resolution.
            We recommend that you specify a resolution for which the product of width and height is less than or equal to the applicable value in the following list (List - Max width x height value ):
            1 - 25344
            1b - 25344
            1.1 - 101376
            1.2 - 101376
            1.3 - 101376
            2 - 101376
            2.1 - 202752
            2.2 - 404720
            3 - 404720
            3.1 - 921600
            3.2 - 1310720
            4 - 2097152
            4.1 - 2097152

            AspectRatio (string) --
            Warning
            To better control resolution and aspect ratio of output videos, we recommend that you use the values MaxWidth , MaxHeight , SizingPolicy , PaddingPolicy , and DisplayAspectRatio instead of Resolution and AspectRatio . The two groups of settings are mutually exclusive. Do not use them together.
            The display aspect ratio of the video in the output file. Valid values include:
            auto , 1:1 , 4:3 , 3:2 , 16:9
            If you specify auto , Elastic Transcoder tries to preserve the aspect ratio of the input file.
            If you specify an aspect ratio for the output file that differs from aspect ratio of the input file, Elastic Transcoder adds pillarboxing (black bars on the sides) or letterboxing (black bars on the top and bottom) to maintain the aspect ratio of the active region of the video.
            MaxWidth (string) --The maximum width of the output video in pixels. If you specify auto , Elastic Transcoder uses 1920 (Full HD) as the default value. If you specify a numeric value, enter an even integer between 128 and 4096.
            MaxHeight (string) --The maximum height of the output video in pixels. If you specify auto , Elastic Transcoder uses 1080 (Full HD) as the default value. If you specify a numeric value, enter an even integer between 96 and 3072.
            DisplayAspectRatio (string) --The value that Elastic Transcoder adds to the metadata in the output file.
            SizingPolicy (string) --Specify one of the following values to control scaling of the output video:
            Fit : Elastic Transcoder scales the output video so it matches the value that you specified in either MaxWidth or MaxHeight without exceeding the other value.
            Fill : Elastic Transcoder scales the output video so it matches the value that you specified in either MaxWidth or MaxHeight and matches or exceeds the other value. Elastic Transcoder centers the output video and then crops it in the dimension (if any) that exceeds the maximum value.
            Stretch : Elastic Transcoder stretches the output video to match the values that you specified for MaxWidth and MaxHeight . If the relative proportions of the input video and the output video are different, the output video will be distorted.
            Keep : Elastic Transcoder does not scale the output video. If either dimension of the input video exceeds the values that you specified for MaxWidth and MaxHeight , Elastic Transcoder crops the output video.
            ShrinkToFit : Elastic Transcoder scales the output video down so that its dimensions match the values that you specified for at least one of MaxWidth and MaxHeight without exceeding either value. If you specify this option, Elastic Transcoder does not scale the video up.
            ShrinkToFill : Elastic Transcoder scales the output video down so that its dimensions match the values that you specified for at least one of MaxWidth and MaxHeight without dropping below either value. If you specify this option, Elastic Transcoder does not scale the video up.
            PaddingPolicy (string) --When you set PaddingPolicy to Pad , Elastic Transcoder may add black bars to the top and bottom and/or left and right sides of the output video to make the total size of the output video match the values that you specified for MaxWidth and MaxHeight .
            Watermarks (list) --Settings for the size, location, and opacity of graphics that you want Elastic Transcoder to overlay over videos that are transcoded using this preset. You can specify settings for up to four watermarks. Watermarks appear in the specified size and location, and with the specified opacity for the duration of the transcoded video.
            Watermarks can be in .png or .jpg format. If you want to display a watermark that is not rectangular, use the .png format, which supports transparency.
            When you create a job that uses this preset, you specify the .png or .jpg graphics that you want Elastic Transcoder to include in the transcoded videos. You can specify fewer graphics in the job than you specify watermark settings in the preset, which allows you to use the same preset for up to four watermarks that have different dimensions.
            (dict) --Settings for the size, location, and opacity of graphics that you want Elastic Transcoder to overlay over videos that are transcoded using this preset. You can specify settings for up to four watermarks. Watermarks appear in the specified size and location, and with the specified opacity for the duration of the transcoded video.
            Watermarks can be in .png or .jpg format. If you want to display a watermark that is not rectangular, use the .png format, which supports transparency.
            When you create a job that uses this preset, you specify the .png or .jpg graphics that you want Elastic Transcoder to include in the transcoded videos. You can specify fewer graphics in the job than you specify watermark settings in the preset, which allows you to use the same preset for up to four watermarks that have different dimensions.
            Id (string) --A unique identifier for the settings for one watermark. The value of Id can be up to 40 characters long.
            MaxWidth (string) --The maximum width of the watermark in one of the following formats:
            number of pixels (px): The minimum value is 16 pixels, and the maximum value is the value of MaxWidth .
            integer percentage (%): The range of valid values is 0 to 100. Use the value of Target to specify whether you want Elastic Transcoder to include the black bars that are added by Elastic Transcoder, if any, in the calculation. If you specify the value in pixels, it must be less than or equal to the value of MaxWidth .
            MaxHeight (string) --The maximum height of the watermark in one of the following formats:
            number of pixels (px): The minimum value is 16 pixels, and the maximum value is the value of MaxHeight .
            integer percentage (%): The range of valid values is 0 to 100. Use the value of Target to specify whether you want Elastic Transcoder to include the black bars that are added by Elastic Transcoder, if any, in the calculation.
            If you specify the value in pixels, it must be less than or equal to the value of MaxHeight .
            SizingPolicy (string) --A value that controls scaling of the watermark:
            Fit : Elastic Transcoder scales the watermark so it matches the value that you specified in either MaxWidth or MaxHeight without exceeding the other value.
            Stretch : Elastic Transcoder stretches the watermark to match the values that you specified for MaxWidth and MaxHeight . If the relative proportions of the watermark and the values of MaxWidth and MaxHeight are different, the watermark will be distorted.
            ShrinkToFit : Elastic Transcoder scales the watermark down so that its dimensions match the values that you specified for at least one of MaxWidth and MaxHeight without exceeding either value. If you specify this option, Elastic Transcoder does not scale the watermark up.
            HorizontalAlign (string) --The horizontal position of the watermark unless you specify a non-zero value for HorizontalOffset :
            Left : The left edge of the watermark is aligned with the left border of the video.
            Right : The right edge of the watermark is aligned with the right border of the video.
            Center : The watermark is centered between the left and right borders.
            HorizontalOffset (string) --The amount by which you want the horizontal position of the watermark to be offset from the position specified by HorizontalAlign:
            number of pixels (px): The minimum value is 0 pixels, and the maximum value is the value of MaxWidth.
            integer percentage (%): The range of valid values is 0 to 100.
            For example, if you specify Left for HorizontalAlign and 5px for HorizontalOffset , the left side of the watermark appears 5 pixels from the left border of the output video.
            HorizontalOffset is only valid when the value of HorizontalAlign is Left or Right . If you specify an offset that causes the watermark to extend beyond the left or right border and Elastic Transcoder has not added black bars, the watermark is cropped. If Elastic Transcoder has added black bars, the watermark extends into the black bars. If the watermark extends beyond the black bars, it is cropped.
            Use the value of Target to specify whether you want to include the black bars that are added by Elastic Transcoder, if any, in the offset calculation.
            VerticalAlign (string) --The vertical position of the watermark unless you specify a non-zero value for VerticalOffset :
            Top : The top edge of the watermark is aligned with the top border of the video.
            Bottom : The bottom edge of the watermark is aligned with the bottom border of the video.
            Center : The watermark is centered between the top and bottom borders.
            VerticalOffset (string) --
            VerticalOffset
            The amount by which you want the vertical position of the watermark to be offset from the position specified by VerticalAlign:
            number of pixels (px): The minimum value is 0 pixels, and the maximum value is the value of MaxHeight .
            integer percentage (%): The range of valid values is 0 to 100.
            For example, if you specify Top for VerticalAlign and 5px for VerticalOffset , the top of the watermark appears 5 pixels from the top border of the output video.
            VerticalOffset is only valid when the value of VerticalAlign is Top or Bottom.
            If you specify an offset that causes the watermark to extend beyond the top or bottom border and Elastic Transcoder has not added black bars, the watermark is cropped. If Elastic Transcoder has added black bars, the watermark extends into the black bars. If the watermark extends beyond the black bars, it is cropped.
            Use the value of Target to specify whether you want Elastic Transcoder to include the black bars that are added by Elastic Transcoder, if any, in the offset calculation.
            Opacity (string) --A percentage that indicates how much you want a watermark to obscure the video in the location where it appears. Valid values are 0 (the watermark is invisible) to 100 (the watermark completely obscures the video in the specified location). The datatype of Opacity is float.
            Elastic Transcoder supports transparent .png graphics. If you use a transparent .png, the transparent portion of the video appears as if you had specified a value of 0 for Opacity . The .jpg file format doesn't support transparency.
            Target (string) --A value that determines how Elastic Transcoder interprets values that you specified for HorizontalOffset , VerticalOffset , MaxWidth , and MaxHeight :
            Content : HorizontalOffset and VerticalOffset values are calculated based on the borders of the video excluding black bars added by Elastic Transcoder, if any. In addition, MaxWidth and MaxHeight , if specified as a percentage, are calculated based on the borders of the video excluding black bars added by Elastic Transcoder, if any.
            Frame : HorizontalOffset and VerticalOffset values are calculated based on the borders of the video including black bars added by Elastic Transcoder, if any. In addition, MaxWidth and MaxHeight , if specified as a percentage, are calculated based on the borders of the video including black bars added by Elastic Transcoder, if any.

    :type Audio: dict
    :param Audio: A section of the request body that specifies the audio parameters.
            Codec (string) --The audio codec for the output file. Valid values include aac , flac , mp2 , mp3 , pcm , and vorbis .
            SampleRate (string) --The sample rate of the audio stream in the output file, in Hertz. Valid values include:
            auto , 22050 , 32000 , 44100 , 48000 , 96000
            If you specify auto , Elastic Transcoder automatically detects the sample rate.
            BitRate (string) --The bit rate of the audio stream in the output file, in kilobits/second. Enter an integer between 64 and 320, inclusive.
            Channels (string) --The number of audio channels in the output file. The following values are valid:
            auto , 0 , 1 , 2
            One channel carries the information played by a single speaker. For example, a stereo track with two channels sends one channel to the left speaker, and the other channel to the right speaker. The output channels are organized into tracks. If you want Elastic Transcoder to automatically detect the number of audio channels in the input file and use that value for the output file, select auto .
            The output of a specific channel value and inputs are as follows:
            auto channel specified, with any input: Pass through up to eight input channels.
            0 channels specified, with any input: Audio omitted from the output.
            1 channel specified, with at least one input channel: Mono sound.
            2 channels specified, with any input: Two identical mono channels or stereo. For more information about tracks, see Audio:AudioPackingMode.
            For more information about how Elastic Transcoder organizes channels and tracks, see Audio:AudioPackingMode .
            AudioPackingMode (string) --The method of organizing audio channels and tracks. Use Audio:Channels to specify the number of channels in your output, and Audio:AudioPackingMode to specify the number of tracks and their relation to the channels. If you do not specify an Audio:AudioPackingMode , Elastic Transcoder uses SingleTrack .
            The following values are valid:
            SingleTrack , OneChannelPerTrack , and OneChannelPerTrackWithMosTo8Tracks
            When you specify SingleTrack , Elastic Transcoder creates a single track for your output. The track can have up to eight channels. Use SingleTrack for all non-mxf containers.
            The outputs of SingleTrack for a specific channel value and inputs are as follows:
            0 channels with any input: Audio omitted from the output
            1, 2, or auto channels with no audio input: Audio omitted from the output
            1 channel with any input with audio: One track with one channel, downmixed if necessary
            2 channels with one track with one channel: One track with two identical channels
            2 or auto channels with two tracks with one channel each: One track with two channels
            2 or auto channels with one track with two channels: One track with two channels
            2 channels with one track with multiple channels: One track with two channels
            auto channels with one track with one channel: One track with one channel
            auto channels with one track with multiple channels: One track with multiple channels
            When you specify OneChannelPerTrack , Elastic Transcoder creates a new track for every channel in your output. Your output can have up to eight single-channel tracks.
            The outputs of OneChannelPerTrack for a specific channel value and inputs are as follows:
            0 channels with any input: Audio omitted from the output
            1, 2, or auto channels with no audio input: Audio omitted from the output
            1 channel with any input with audio: One track with one channel, downmixed if necessary
            2 channels with one track with one channel: Two tracks with one identical channel each
            2 or auto channels with two tracks with one channel each: Two tracks with one channel each
            2 or auto channels with one track with two channels: Two tracks with one channel each
            2 channels with one track with multiple channels: Two tracks with one channel each
            auto channels with one track with one channel: One track with one channel
            auto channels with one track with multiple channels: Up to eight tracks with one channel each
            When you specify OneChannelPerTrackWithMosTo8Tracks , Elastic Transcoder creates eight single-channel tracks for your output. All tracks that do not contain audio data from an input channel are MOS, or Mit Out Sound, tracks.
            The outputs of OneChannelPerTrackWithMosTo8Tracks for a specific channel value and inputs are as follows:
            0 channels with any input: Audio omitted from the output
            1, 2, or auto channels with no audio input: Audio omitted from the output
            1 channel with any input with audio: One track with one channel, downmixed if necessary, plus six MOS tracks
            2 channels with one track with one channel: Two tracks with one identical channel each, plus six MOS tracks
            2 or auto channels with two tracks with one channel each: Two tracks with one channel each, plus six MOS tracks
            2 or auto channels with one track with two channels: Two tracks with one channel each, plus six MOS tracks
            2 channels with one track with multiple channels: Two tracks with one channel each, plus six MOS tracks
            auto channels with one track with one channel: One track with one channel, plus seven MOS tracks
            auto channels with one track with multiple channels: Up to eight tracks with one channel each, plus MOS tracks until there are eight tracks in all
            CodecOptions (dict) --If you specified AAC for Audio:Codec , this is the AAC compression profile to use. Valid values include:
            auto , AAC-LC , HE-AAC , HE-AACv2
            If you specify auto , Elastic Transcoder chooses a profile based on the bit rate of the output file.
            Profile (string) --You can only choose an audio profile when you specify AAC for the value of Audio:Codec.
            Specify the AAC profile for the output file. Elastic Transcoder supports the following profiles:
            auto : If you specify auto , Elastic Transcoder selects the profile based on the bit rate selected for the output file.
            AAC-LC : The most common AAC profile. Use for bit rates larger than 64 kbps.
            HE-AAC : Not supported on some older players and devices. Use for bit rates between 40 and 80 kbps.
            HE-AACv2 : Not supported on some players and devices. Use for bit rates less than 48 kbps.
            All outputs in a Smooth playlist must have the same value for Profile .
            Note
            If you created any presets before AAC profiles were added, Elastic Transcoder automatically updated your presets to use AAC-LC. You can change the value as required.
            BitDepth (string) --You can only choose an audio bit depth when you specify flac or pcm for the value of Audio:Codec.
            The bit depth of a sample is how many bits of information are included in the audio samples. The higher the bit depth, the better the audio, but the larger the file.
            Valid values are 16 and 24 .
            The most common bit depth is 24 .
            BitOrder (string) --You can only choose an audio bit order when you specify pcm for the value of Audio:Codec.
            The order the bits of a PCM sample are stored in.
            The supported value is LittleEndian .
            Signed (string) --You can only choose whether an audio sample is signed when you specify pcm for the value of Audio:Codec.
            Whether audio samples are represented with negative and positive numbers (signed) or only positive numbers (unsigned).
            The supported value is Signed .

    :type Thumbnails: dict
    :param Thumbnails: A section of the request body that specifies the thumbnail parameters, if any.
            Format (string) --The format of thumbnails, if any. Valid values are jpg and png .
            You specify whether you want Elastic Transcoder to create thumbnails when you create a job.
            Interval (string) --The approximate number of seconds between thumbnails. Specify an integer value.
            Resolution (string) --
            Warning
            To better control resolution and aspect ratio of thumbnails, we recommend that you use the values MaxWidth , MaxHeight , SizingPolicy , and PaddingPolicy instead of Resolution and AspectRatio . The two groups of settings are mutually exclusive. Do not use them together.
            The width and height of thumbnail files in pixels. Specify a value in the format `` width `` x `` height `` where both values are even integers. The values cannot exceed the width and height that you specified in the Video:Resolution object.
            AspectRatio (string) --
            Warning
            To better control resolution and aspect ratio of thumbnails, we recommend that you use the values MaxWidth , MaxHeight , SizingPolicy , and PaddingPolicy instead of Resolution and AspectRatio . The two groups of settings are mutually exclusive. Do not use them together.
            The aspect ratio of thumbnails. Valid values include:
            auto , 1:1 , 4:3 , 3:2 , 16:9
            If you specify auto , Elastic Transcoder tries to preserve the aspect ratio of the video in the output file.
            MaxWidth (string) --The maximum width of thumbnails in pixels. If you specify auto, Elastic Transcoder uses 1920 (Full HD) as the default value. If you specify a numeric value, enter an even integer between 32 and 4096.
            MaxHeight (string) --The maximum height of thumbnails in pixels. If you specify auto, Elastic Transcoder uses 1080 (Full HD) as the default value. If you specify a numeric value, enter an even integer between 32 and 3072.
            SizingPolicy (string) --Specify one of the following values to control scaling of thumbnails:
            Fit : Elastic Transcoder scales thumbnails so they match the value that you specified in thumbnail MaxWidth or MaxHeight settings without exceeding the other value.
            Fill : Elastic Transcoder scales thumbnails so they match the value that you specified in thumbnail MaxWidth or MaxHeight settings and matches or exceeds the other value. Elastic Transcoder centers the image in thumbnails and then crops in the dimension (if any) that exceeds the maximum value.
            Stretch : Elastic Transcoder stretches thumbnails to match the values that you specified for thumbnail MaxWidth and MaxHeight settings. If the relative proportions of the input video and thumbnails are different, the thumbnails will be distorted.
            Keep : Elastic Transcoder does not scale thumbnails. If either dimension of the input video exceeds the values that you specified for thumbnail MaxWidth and MaxHeight settings, Elastic Transcoder crops the thumbnails.
            ShrinkToFit : Elastic Transcoder scales thumbnails down so that their dimensions match the values that you specified for at least one of thumbnail MaxWidth and MaxHeight without exceeding either value. If you specify this option, Elastic Transcoder does not scale thumbnails up.
            ShrinkToFill : Elastic Transcoder scales thumbnails down so that their dimensions match the values that you specified for at least one of MaxWidth and MaxHeight without dropping below either value. If you specify this option, Elastic Transcoder does not scale thumbnails up.
            PaddingPolicy (string) --When you set PaddingPolicy to Pad , Elastic Transcoder may add black bars to the top and bottom and/or left and right sides of thumbnails to make the total size of the thumbnails match the values that you specified for thumbnail MaxWidth and MaxHeight settings.

    :rtype: dict
    :return: {
        'Preset': {
            'Id': 'string',
            'Arn': 'string',
            'Name': 'string',
            'Description': 'string',
            'Container': 'string',
            'Audio': {
                'Codec': 'string',
                'SampleRate': 'string',
                'BitRate': 'string',
                'Channels': 'string',
                'AudioPackingMode': 'string',
                'CodecOptions': {
                    'Profile': 'string',
                    'BitDepth': 'string',
                    'BitOrder': 'string',
                    'Signed': 'string'
                }
            },
            'Video': {
                'Codec': 'string',
                'CodecOptions': {
                    'string': 'string'
                },
                'KeyframesMaxDist': 'string',
                'FixedGOP': 'string',
                'BitRate': 'string',
                'FrameRate': 'string',
                'MaxFrameRate': 'string',
                'Resolution': 'string',
                'AspectRatio': 'string',
                'MaxWidth': 'string',
                'MaxHeight': 'string',
                'DisplayAspectRatio': 'string',
                'SizingPolicy': 'string',
                'PaddingPolicy': 'string',
                'Watermarks': [
                    {
                        'Id': 'string',
                        'MaxWidth': 'string',
                        'MaxHeight': 'string',
                        'SizingPolicy': 'string',
                        'HorizontalAlign': 'string',
                        'HorizontalOffset': 'string',
                        'VerticalAlign': 'string',
                        'VerticalOffset': 'string',
                        'Opacity': 'string',
                        'Target': 'string'
                    },
                ]
            },
            'Thumbnails': {
                'Format': 'string',
                'Interval': 'string',
                'Resolution': 'string',
                'AspectRatio': 'string',
                'MaxWidth': 'string',
                'MaxHeight': 'string',
                'SizingPolicy': 'string',
                'PaddingPolicy': 'string'
            },
            'Type': 'string'
        },
        'Warning': 'string'
    }

    :returns:
    auto channel specified, with any input: Pass through up to eight input channels.
    0 channels specified, with any input: Audio omitted from the output.
    1 channel specified, with at least one input channel: Mono sound.
    2 channels specified, with any input: Two identical mono channels or stereo. For more information about tracks, see Audio:AudioPackingMode.

    """
    pass


@staticmethod
def make_spectra_table(nebins, spec_dict):
    """Construct the spectral values table

        Returns
        -------

        table : `astropy.table.Table`
            The table has these columns

        ref_mass : float
            The DM mass for this row in the table

        ref_chan : int
            The index of the DM interaction channel for this row

        ref_dnde : array
            The reference differential photon flux fpr each energy [ph / (MeV cm2 s)]

        ref_flux : array
            The reference integral photon flux for each energy [ph / (cm2 s)]

        ref_eflux : array
            The reference integral energy flux for each energy [MeV / (cm2 s)]

        """
    from astropy import table
    col_masses = table.Column(name='ref_mass', dtype=float, unit='GeV',
        data=spec_dict['mass'])
    col_chans = table.Column(name='ref_chan', dtype=int, data=spec_dict['chan']
        )
    col_dnde = table.Column(name='ref_dnde', dtype=float, shape=nebins,
        unit='ph / (MeV cm2 s)', data=spec_dict['dnde'])
    col_flux = table.Column(name='ref_flux', dtype=float, shape=nebins,
        unit='ph / (cm2 s)', data=spec_dict['flux'])
    col_eflux = table.Column(name='ref_eflux', dtype=float, shape=nebins,
        unit='MeV / (cm2 s)', data=spec_dict['eflux'])
    table = table.Table(data=[col_masses, col_chans, col_dnde, col_flux,
        col_eflux])
    return table


@classmethod
def get(cls, backend_id, *args, **kwargs):
    """
        Return an instance of backend type
        """
    backend_class = cls.get_class(backend_id)
    return backend_class.create(*args, **kwargs)


@staticmethod
def copy_with_comments(source_dict, source_key, dest_dict, dest_key,
    delete_source=False, logger=None):
    """Copy dict with comments in config."""
    dest_dict[dest_key] = source_dict[source_key]
    try:
        dest_dict.ca.items[dest_key] = source_dict.ca.items[source_key]
        if logger and not delete_source:
            logger.debug('Copying key: %s -> %s', source_key, dest_key)
    except (KeyError, AttributeError):
        pass
    if delete_source:
        if logger:
            logger.debug('Moving key: %s -> %s', source_key, dest_key)
        del source_dict[source_key]
        source_dict.ca.items.pop(source_key, None)


def first(func, items):
    """Return the first item in the list for what func returns True"""
    for item in items:
        if func(item):
            return item


def from_gm_timestamp(timestamp):
    """Convert timestamp in microseconds to timestamp in seconds."""
    return int(timestamp / 1000000)


def mun2i_NH3_NH3_Cl_CB89(T, P):
    """n-n-a: ammonia ammonia chloride [CB89]."""
    mun2i = 0
    valid = T == 298.15
    return mun2i, valid


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 compare_s1_points_to_s2_block(s1, s2):
    """
    Returns a list of points where schedule 1 disagress with schedule 2
    """
    from datetime import datetime, timedelta
    a_monday = datetime.strptime('2014-03-03 00:00:00', '%Y-%m-%d %H:%M:%S')
    mismatches = []
    for k, v in s1.day_schedules.iteritems():
        for i in range(len(v)):
            t = v[0][i]
            value = v[1][i]
            correct_day = a_monday + timedelta(days=k)
            correct_day_and_time = correct_day + timedelta(hours=t.hour,
                minutes=t.minute, seconds=t.second, microseconds=t.microsecond)
            other_block = s2.schedule_block(correct_day_and_time)
            if other_block.value != value:
                mismatches.append((k, t))
    return mismatches


def is_kernelspec_model(spec_dict):
    """Returns True if spec_dict is already in proper form.  This will occur when using a gateway."""
    return (isinstance(spec_dict, dict) and 'name' in spec_dict and 'spec' in
        spec_dict and 'resources' in spec_dict)


def binom(n, k):
    """
    Returns binomial coefficient (n choose k).
    """
    if k > n:
        return 0
    if k == 0:
        return 1
    result = 1
    for denom in range(1, k + 1):
        result *= n
        result /= denom
        n -= 1
    return result


def extrude_repeat(offset: float=2.0, steps: int=10):
    """Extrude selected vertices, edges or faces repeatedly

    :param offset: Offset
    :type offset: float
    :param steps: Steps
    :type steps: int
    """
    pass


def lookup(*args, **kwargs):
    """
        Get the function that will be called with a given set of arguments, or
        raises DispatchError. Can be called with
        """
    return args[0].lookup_explicit(args[1:], kwargs)


def router_from_id(routerid):
    """
        Note that this method MUST always return a Router instance --
        if you ask for a router ID that didn't yet exist, it is
        created (although without IP addresses and such because it
        wasn't in the consensus). You may find out if a Router came
        from the 'GETINFO ns/all' list by checking the from_consensus
        attribute. This is to simplify code like in Circuit.update()
        that needs to handle the case where an EXTENDED circuit event
        is the only time we've seen a Router -- it's possible for Tor
        to do things with routers not in the consensus (like extend
        circuits to them).

        :return: a router by its ID.
        """


def is_abstract_model(model):
    """
    Given a model class, returns a boolean True if it is abstract and False if it is not.
    """
    return hasattr(model, '_meta') and hasattr(model._meta, 'abstract'
        ) and model._meta.abstract


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 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 bC_MgOH_HSO4_HMW84(T, P):
    """c-a: magnesium-hydroxide bisulfate [HMW84]."""
    b0 = 0.0
    b1 = 0.0
    b2 = 0.0
    C0 = 0
    C1 = 0
    alph1 = 2
    alph2 = -9
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


@classmethod
def fetch(cls, client, name):
    """
        Easy, user-facing way to retrieve a record from the REST API
        """
    out = cls(client, name)
    out.refresh()
    return out


def bech32_polymod(values):
    """Internal function that computes the Bech32 checksum."""
    generator = [996825010, 642813549, 513874426, 1027748829, 705979059]
    chk = 1
    for value in values:
        top = chk >> 25
        chk = (chk & 33554431) << 5 ^ value
        for i in range(5):
            chk ^= generator[i] if top >> i & 1 else 0
    return chk


def nan_dropper(data, treshold=0.9):
    """
    Drops nans in a specific column or a range of
    columns, using np.isnull() through pandas.

    The treshold sets the % at which the whole column
    is droped (nan % of all values in the column).

    """
    import wrangle as wr
    temp = wr.df_find_nan(data)
    temp = temp.transpose()
    for col in temp:
        if temp[col][1] < treshold:
            data = data.drop(col, axis=1)
            nan_rate = (1 - temp[col][1]) * 100
            print('DROPPED (%.2f%% nans): %s' % (nan_rate, col))
    data.dropna(inplace=True)
    return data


def __len__():
    """
        Count how many entries are in the cache.
        """


def google_fixed_width_font(style):
    """check if the css of the current element defines a fixed width font"""
    font_family = ''
    if 'font-family' in style:
        font_family = style['font-family']
    if 'Courier New' == font_family or 'Consolas' == font_family:
        return True
    return False


def epilog():
    """
    Returns epilog text for CLI help

    :return: string
    """
    epilog_text = """
    Time format options:
    yyyy (2016),
    yyyy-mm (2016-01),
    yyyy-mm-dd (2016-01-01),
    yyyymmdd (20160101),
    yyyymmddThh (20160101T12),
    yyyy-mm-ddThh:mm:ss-hh:mm (2016-01-01T00:00:00-00:00)
    """
    return epilog_text


@classmethod
def send_exit_with_code(cls, sock, code):
    """Send an Exit chunk over the specified socket, containing the specified return code."""
    encoded_exit_status = cls.encode_int(code)
    cls.send_exit(sock, payload=encoded_exit_status)


def _convert_resize(builder, node, graph, err):
    """
    convert to CoreML Upsample or Resize Bilinear Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L2139
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L2178
    """
    mode = node.attrs.get('mode', 'nearest')
    if node.inputs[1] not in node.input_tensors:
        return err.unsupported_op_configuration(builder, node, graph,
            'Scaling factor unknown!! CoreML does not support dynamic scaling for Resize'
            )
    mode = 'NN' if mode == 'nearest' else 'BILINEAR'
    scale = node.input_tensors[node.inputs[1]]
    builder.add_upsample(name=node.name, scaling_factor_h=scale[-2],
        scaling_factor_w=scale[-1], input_name=node.inputs[0], output_name=
        node.outputs[0], mode=mode)


@staticmethod
def get_name(commit):
    """Extract the name from the author or committer.

        Arguments:
          commit (:py:class:`dict`): The JSON data from the response.

        Returns:
          :py:class:`str`: The author (or committer) name.

        """
    author = commit.get('author', {})
    if 'name' in author:
        return author['name']
    return commit.get('committer', {}).get('name')


@classmethod
def factory_default(cls):
    """
        Returns a factory default version of this settings object.
        """
    return cls({})


def copybuffer():
    """Selected objects are saved in a temp file

    """
    pass


def describe_parameters(Filters=None, MaxResults=None, NextToken=None):
    """
    Get information about a parameter.
    See also: AWS API Documentation

    :example: response = client.describe_parameters(
        Filters=[
            {
                'Key': 'Name'|'Type'|'KeyId',
                'Values': [
                    'string',
                ]
            },
        ],
        MaxResults=123,
        NextToken='string'
    )

    :type Filters: list
    :param Filters: One or more filters. Use a filter to return a more specific list of results.
            (dict) --One or more filters. Use a filter to return a more specific list of results.
            Key (string) --The name of the filter.
            Values (list) -- [REQUIRED]The filter values.
            (string) --

    :type MaxResults: integer
    :param MaxResults: The maximum number of items to return for this call. The call also returns a token that you can specify in a subsequent call to get the next set of results.

    :type NextToken: string
    :param NextToken: The token for the next set of items to return. (You received this token from a previous call.)

    :rtype: dict
    :return: {
        'Parameters': [
            {
                'Name': 'string',
                'Type': 'String'|'StringList'|'SecureString',
                'KeyId': 'string',
                'LastModifiedDate': datetime(2015, 1, 1),
                'LastModifiedUser': 'string',
                'Description': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


@classmethod
def get_schema(cls):
    """Creates a table schema for incoming data from PlexxiCore.

        Returns a dictionary map of tablenames corresponding to column names
        for that table. Both tableNames and columnnames are strings.
        """
    d = {}
    d[cls.HOSTS] = 'uuid', 'name', 'mac_count', 'vmcount'
    d[cls.HOST_MACS] = 'Host_uuid', 'Mac_Address'
    d[cls.HOST_GUESTS] = 'Host_uuid', 'VM_uuid'
    d[cls.VMS] = 'uuid', 'name', 'host_uuid', 'ip', 'mac_count'
    d[cls.VM_MACS] = 'vmID', 'Mac_Address'
    d[cls.AFFINITIES] = 'uuid', 'name'
    d[cls.VSWITCHES] = 'uuid', 'host_count', 'vnic_count'
    d[cls.VSWITCHES_MACS] = 'vswitch_uuid', 'Mac_Address'
    d[cls.VSWITCHES_HOSTS] = 'vswitch_uuid', 'hostuuid'
    d[cls.PLEXXISWITCHES] = 'uuid', 'ip', 'status'
    d[cls.PLEXXISWITCHES_MACS] = 'Switch_uuid', 'Mac_Address'
    d[cls.PORTS] = 'uuid', 'name'
    d[cls.NETWORKLINKS] = ('uuid', 'name', 'port_uuid', 'start_uuid',
        'start_name', 'stop_uuid', 'stop_name')
    return d


def get(isamAppliance, name, check_mode=False, force=False):
    """
    Get management authorization role
    """
    return isamAppliance.invoke_get('Get management authorization role',
        '/authorization/roles/{0}/v1'.format(name))


def delivery_report(err, msg):
    """
    This is a utility method passed to the Kafka Producer to handle the delivery
    of messages sent using `send(topic, message)`.
    """
    if err is not None:
        print('message delivery failed: {}'.format(msg))
        print('failed message: {}'.format(err))


def get_query_count() ->int:
    """
        Get number of queries tranaction ran
        """


def parent_in_tree(parent_label, tree_hash):
    """ Return True if the parent of node_label is in the tree """
    return parent_label in tree_hash


def do_OP_WITHIN(vm):
    """
    >>> s = [b'b', b'a', b'c']
    >>> do_OP_WITHIN(s, False)
    >>> print(s == [b''])
    True
    >>> s = [b'd', b'a', b'c']
    >>> do_OP_WITHIN(s, False)
    >>> print(s == [b''])
    True
    """
    v3, v2, v1 = [vm.pop_int() for i in range(3)]
    ok = v2 <= v1 < v3
    vm.append(vm.bool_to_script_bytes(ok))


def uniq_stable(elems):
    """uniq_stable(elems) -> list

    Return from an iterable, a list of all the unique elements in the input,
    but maintaining the order in which they first appear.

    A naive solution to this problem which just makes a dictionary with the
    elements as keys fails to respect the stability condition, since
    dictionaries are unsorted by nature.

    Note: All elements in the input must be hashable.
    """
    unique = []
    unique_set = set()
    for nn in elems:
        if nn not in unique_set:
            unique.append(nn)
            unique_set.add(nn)
    return unique


def sqrt(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise square-root value of the input.

    .. math::
       \\textrm{sqrt}(x) = \\sqrt{x}

    Example::

       sqrt([4, 9, 16]) = [2, 3, 4]

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

       - sqrt(default) = default
       - sqrt(row_sparse) = row_sparse
       - sqrt(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_pow.cc:L142

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

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

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


def sfloat(S):
    """convert a string to a float, treating an all-blank string as zero"""
    if S.strip():
        return float(S)
    else:
        return 0.0


def colour_stream(colour=True):
    """ Let stream logger use coloured output

	Parameters
	----------
	colour: boolean (default=True)
		Boolean indicating if stream logging should be coloured. """
    global __colouredstream__
    __colouredstream__ = bool(colour)


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 '+'