def Func(arg_0, arg_1):
        """
        Get the t-SNE projection, including responses and tags.

        :param data_view_id: The ID of the data view to retrieve TSNE from
        :type data_view_id: int
        :return: The TSNE analysis
        :rtype: :class:`Tsne`
        """
        arg_2 = arg_0._data_analysis(arg_1)
        arg_3 = arg_2['projections']
        Func = Tsne()
        for arg_5, arg_6 in arg_3.items():
            arg_7 = Projection(
                xs=arg_6['x'],
                ys=arg_6['y'],
                responses=arg_6['label'],
                tags=arg_6['inputs'],
                uids=arg_6['uid']
            )
            Func.add_projection(arg_5, arg_7)

        return Func


def Func(arg_0, arg_1, arg_2, arg_3='scalar', arg_4=True):
        """
        Submits an async prediction request.

        :param data_view_id: The id returned from create
        :param candidates: Array of candidates
        :param prediction_source: 'scalar' or 'scalar_from_distribution'
        :param use_prior: True to use prior prediction, otherwise False
        :return: Predict request Id (used to check status)
        """

        arg_5 = {
            "prediction_source":
                arg_3,
            "use_prior":
                arg_4,
            "candidates":
                arg_2
        }

        arg_6 = "Configuration creation failed"
        arg_7 = 'v1/data_views/' + str(arg_1) + '/predict/submit'
        return arg_0._get_success_json(
            arg_0._post_json(arg_7, arg_5, arg_6=arg_6)
        )['data']['uid']


def Func(arg_0, arg_1, arg_2):
        """
        Returns a string indicating the status of the prediction job

        :param view_id: The data view id returned from data view create
        :param predict_request_id: The id returned from predict
        :return: Status data, also includes results if state is finished
        """

        arg_3 = "Get status on predict failed"

        arg_4 = arg_0._get_success_json(arg_0._get(
            'v1/data_views/' + str(arg_1) + '/predict/' + str(arg_2) + '/status',
            None, arg_3=arg_3))

        arg_5 = arg_4["data"]
        # result.update({"message": bare_response["message"]})

        return arg_5


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None, arg_5=[], arg_6="Default"):
        """
        Submits a new experimental design run.

        :param data_view_id: The ID number of the data view to which the
            run belongs, as a string
        :type data_view_id: str
        :param num_candidates: The number of candidates to return
        :type num_candidates: int
        :param target: An :class:``Target`` instance representing
            the design run optimization target
        :type target: :class:``Target``
        :param constraints: An array of design constraints (instances of
            objects which extend :class:``BaseConstraint``)
        :type constraints: list of :class:``BaseConstraint``
        :param sampler: The name of the sampler to use during the design run:
            either "Default" or "This view"
        :type sampler: str
        :return: A :class:`DesignRun` instance containing the UID of the
            new run
        """
        if arg_3 > 30:
            raise CitrinationClientError("Parameter effort must be less than 30 to trigger a design run")

        if arg_4 is not None:
            arg_4 = arg_4.to_dict()

        arg_7 = [c.to_dict() for c in arg_5]

        arg_8 = {
            "num_candidates": arg_2,
            "target": arg_4,
            "effort": arg_3,
            "constraints": arg_7,
            "sampler": arg_6
        }

        arg_9 = routes.submit_data_view_design(arg_1)

        arg_10 = arg_0._post_json(arg_9, arg_8).json()

        return DesignRun(arg_10["data"]["design_run"]["uid"])


def Func(arg_0, arg_1):
        """
        Retrieves a summary of information for a given data view
            - view id
            - name
            - description
            - columns

        :param data_view_id: The ID number of the data view to which the
            run belongs, as a string
        :type data_view_id: str
        """

        arg_2 = routes.Func(arg_1)

        arg_3 = arg_0._get(arg_2).json()

        arg_4 = arg_3["data"]["data_view"]

        arg_5 = []
        for arg_6 in arg_4["datasets"]:
            arg_5.append(Dataset(
                name=arg_6["name"],
                id=arg_6["id"],
                description=arg_6["description"]
            ))

        arg_7 = []
        for arg_8 in arg_4["columns"]:
            arg_7.append(ColumnFactory.from_dict(arg_8))

        return DataView(
            view_id=arg_1,
            name=arg_4["name"],
            description=arg_4["description"],
            datasets=arg_5,
            columns=arg_7,
        )


def Func(arg_0):
    """
    Given a filepath, loads the file as a dictionary from YAML

    :param path: The path to a YAML file
    """
    with open(arg_0, "r") as f:
      arg_1 = f.read()
      arg_2 = yaml.load(arg_1)
    return arg_2


def Func(arg_0):
    """
    Extracts credentials from the yaml formatted credential filepath
    passed in. Uses the default profile if the CITRINATION_PROFILE env var
    is not set, otherwise looks for a profile with that name in the credentials file.

    :param filepath: The path of the credentials file
    """
    try:
        arg_1 = load_file_as_yaml(arg_0)
    except Exception:
        arg_1 = {}

    arg_2 = os.environ.get(citr_env_vars.CITRINATION_PROFILE)
    if arg_2 is None or len(arg_2) == 0:
        arg_2 = DEFAULT_CITRINATION_PROFILE
    arg_3 = None
    arg_4 = None
    try:
        arg_5 = arg_1[arg_2]
        arg_3 = arg_5[CREDENTIALS_API_KEY_KEY]
        arg_4 = arg_5[CREDENTIALS_SITE_KEY]
    except KeyError:
        pass

    return (arg_3, arg_4)


def Func(arg_0, arg_1, arg_2=arg_3):
    """
    Given an API key, a site url and a credentials file path, runs through a prioritized list of credential sources to find credentials.

    Specifically, this method ranks credential priority as follows:
        1. Those passed in as the first two parameters to this method
        2. Those found in the environment as variables
        3. Those found in the credentials file at the profile specified
           by the profile environment variable
        4. Those found in the default stanza in the credentials file

    :param api_key: A Citrination API Key or None
    :param site: A Citrination site URL or None
    :param cred_file: The path to a credentials file
    """
    arg_4, arg_5 = get_credentials_from_file(arg_2)
    if arg_0 is None:
        arg_0 =  os.environ.get(citr_env_vars.CITRINATION_API_KEY)
    if arg_0 is None or len(arg_0) == 0:
        arg_0 = arg_4

    if arg_1 is None:
        arg_1 = os.environ.get(citr_env_vars.CITRINATION_SITE)
    if arg_1 is None or len(arg_1) == 0:
        arg_1 = arg_5
    if arg_1 is None:
        arg_1 = "https://citrination.com"

    return arg_0, arg_1


def Func(arg_0, arg_1, arg_2=".", arg_3=False):
        """
        Returns the number of files matching a pattern in a dataset.

        :param dataset_id: The ID of the dataset to search for files.
        :type dataset_id: int
        :param glob: A pattern which will be matched against files in the dataset.
        :type glob: str
        :param is_dir: A boolean indicating whether or not the pattern should match against the beginning of paths in the dataset.
        :type is_dir: bool
        :return: The number of matching files
        :rtype: int
        """
        arg_4 = arg_0.list_files(arg_1, arg_2, arg_3)
        return len(arg_4)


def Func(arg_0, arg_1, arg_2, arg_3 = None):
        """
        Retrieves a PIF from a given dataset.

        :param dataset_id: The id of the dataset to retrieve PIF from
        :type dataset_id: int
        :param uid: The uid of the PIF to retrieve
        :type uid: str
        :param dataset_version: The dataset version to look for the PIF in. If nothing is supplied, the latest dataset version will be searched
        :type dataset_version: int
        :return: A :class:`Pif` object
        :rtype: :class:`Pif`
        """
        arg_4 = "An error occurred retrieving PIF {}".format(arg_2)
        if arg_3 == None:
            arg_5 = arg_0._get(routes.pif_dataset_uid(arg_1, arg_2), arg_4=arg_4)
        else:
            arg_5 = arg_0._get(routes.pif_dataset_version_uid(arg_1, arg_2, arg_3), arg_4=arg_4)

        return pif.loads(arg_5.content.decode("utf-8"))


def Func(arg_0, arg_1):
        """
        Retrieves the set of columns from the combination of dataset ids given

        :param dataset_ids: The id of the dataset to retrieve columns from
        :type dataset_ids: list of int
        :return: A list of column names from the dataset ids given.
        :rtype: list of str
        """
        if not isinstance(arg_1, list):
            arg_1 = [arg_1]

        arg_2 = {
            "dataset_ids":
                arg_1
        }

        arg_3 = "Failed to get available columns in dataset(s) {}".format(arg_1)

        return arg_0._get_success_json(arg_0._post_json(
            'v1/datasets/get-available-columns', arg_2, arg_3=arg_3))['data']


def Func(arg_0, arg_1):
        """
        Generates a default search templates from the available columns in the dataset ids given.

        :param dataset_ids: The id of the dataset to retrieve files from
        :type dataset_ids: list of int
        :return: A search template based on the columns in the datasets given
        """

        arg_2 = {
            "dataset_ids":
                arg_1
        }

        arg_3 = "Failed to generate a search template from columns in dataset(s) {}".format(arg_1)

        return arg_0._get_success_json(arg_0._post_json(
            'v1/search_templates/builders/from-dataset-ids', arg_2, arg_3=arg_3))['data']


def Func(arg_0, arg_1, arg_2):
        """
        Returns a new search template, but the new template has only the extract_as_keys given.

        :param extract_as_keys: List of extract as keys to keep
        :param search_template: The search template to prune
        :return: New search template with pruned columns
        """

        arg_3 = {
            "extract_as_keys":
                arg_1,
            "search_template":
                arg_2
        }

        arg_4 = "Failed to prune a search template"

        return arg_0._get_success_json(arg_0._post_json(
            'v1/search_templates/prune-to-extract-as', arg_3, arg_4=arg_4))['data']


def Func(arg_0, arg_1):
        """
        Make a copy of a dictionary with all keys converted to camel case. This is just calls to_camel_case on each of the keys in the dictionary and returns a new dictionary.

        :param obj: Dictionary to convert keys to camel case.
        :return: Dictionary with the input values and all keys in camel case
        """
        return dict((to_camel_case(arg_2), arg_3) for (arg_2, arg_3) in arg_1.items())


def Func(arg_0, arg_1):
        """
        Runs the template against the validation endpoint, returns a message indicating status of the templte

        :param ml_template: Template to Func
        :return: OK or error message if validation failed
        """

        arg_2 = {
            "ml_template":
                arg_1
        }

        arg_3 = "ML template validation invoke failed"

        arg_4 = arg_0._get_success_json(arg_0._post_json(
            'ml_templates/Func', arg_2, arg_3=arg_3))['data']
        if arg_4['valid']:
            return 'OK'
        return arg_4['reason']


def Func(arg_0, arg_1):
    """Compute the hamming distance between two hashes"""
    if len(arg_0) != len(arg_1):
        raise ValueError('Hamming distance requires two strings of equal length')

    return sum(map(lambda x: 0 if x[0] == x[1] else 1, zip(arg_0, arg_1)))


def Func(arg_0, arg_1=8):
    """ Compute the average hash of the given image. """
    with open(arg_0, 'rb') as f:
        # Open the image, resize it and convert it to black & white.
        arg_2 = Image.open(f).resize((arg_1, arg_1), Image.ANTIALIAS).convert('L')
        arg_3 = list(arg_2.getdata())

    arg_4 = sum(arg_3) / len(arg_3)

    # Compute the hash based on each pixels value compared to the average.
    arg_5 = "".join(map(lambda pixel: '1' if pixel > arg_4 else '0', arg_3))
    arg_6 = "0{hashlength}x".format(hashlength=arg_1 ** 2 // 4)
    return int(arg_5, 2).__format__(arg_6)


def Func(arg_0, arg_1, arg_2, arg_3=None):
    """Set up the Vizio media player platform."""
    arg_4 = arg_1.get(CONF_HOST)
    arg_5 = arg_1.get(CONF_ACCESS_TOKEN)
    arg_6 = arg_1.get(CONF_NAME)
    arg_7 = arg_1.get(CONF_VOLUME_STEP)
    arg_8 = arg_1.get(CONF_DEVICE_CLASS)
    arg_9 = VizioDevice(arg_4, arg_5, arg_6, arg_7, arg_8)
    if arg_9.validate_setup() is False:
        _LOGGER.error("Failed to set up Vizio platform, "
                      "please check if host and API key are correct")
        return
    elif (arg_5 is None or arg_5 == "") and arg_8 == "tv":
        _LOGGER.error("Failed to set up Vizio platform, "
                      "if device_class is 'tv' then an auth_token needs "
                      "to be provided, otherwise if device_class is "
                      "'soundbar' then add the right device_class to config")
        return

    if arg_1.get(CONF_SUPPRESS_WARNING):
        from requests.packages import urllib3
        _LOGGER.warning("InsecureRequestWarning is disabled "
                        "because of Vizio platform configuration")
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    arg_2([arg_9], True)


def Func(arg_0):
        """Retrieve latest state of the device."""
        arg_1 = arg_0._device.get_power_state()

        if arg_1:
            arg_0._state = STATE_ON

            arg_3 = arg_0._device.get_current_volume()
            if arg_3 is not None:
                arg_0._volume_level = float(arg_3) / arg_0._max_volume

            arg_5 = arg_0._device.get_current_input()
            if arg_5 is not None:
                arg_0._current_input = arg_5.meta_name

            arg_7 = arg_0._device.get_inputs()
            if arg_7 is not None:
                arg_0._available_inputs = [arg_5.name for arg_5 in arg_7]

        else:
            if arg_1 is None:
                arg_0._state = None
            else:
                arg_0._state = STATE_OFF

            arg_0._volume_level = None
            arg_0._current_input = None
            arg_0._available_inputs = None


def Func(arg_0, arg_1):
        """Mute the volume."""
        if arg_1:
            arg_0._device.mute_on()
        else:
            arg_0._device.mute_off()


def Func(arg_0):
        """Increasing volume of the device."""
        arg_0._volume_level += arg_0._volume_step / arg_0._max_volume
        arg_0._device.vol_up(num=arg_0._volume_step)


def Func(arg_0):
        """Decreasing volume of the device."""
        arg_0._volume_level -= arg_0._volume_step / arg_0._max_volume
        arg_0._device.vol_down(num=arg_0._volume_step)


def Func(arg_0):
        '''Restores the starting position.'''
        arg_0.piece_bb = [
                BB_VOID,                       # NONE
                BB_RANK_C | BB_RANK_G,         # PAWN
                BB_A1 | BB_I1 | BB_A9 | BB_I9, # LANCE
                BB_A2 | BB_A8 | BB_I2 | BB_I8, # KNIGHT
                BB_A3 | BB_A7 | BB_I3 | BB_I7, # SILVER
                BB_A4 | BB_A6 | BB_I4 | BB_I6, # GOLD
                BB_B2 | BB_H8,                 # BISHOP
                BB_B8 | BB_H2,                 # ROOK
                BB_A5 | BB_I5,                 # KING
                BB_VOID,                       # PROM_PAWN
                BB_VOID,                       # PROM_LANCE
                BB_VOID,                       # PROM_KNIGHT
                BB_VOID,                       # PROM_SILVER
                BB_VOID,                       # PROM_BISHOP
                BB_VOID,                       # PROM_ROOK
        ]

        arg_0.pieces_in_hand = [collections.Counter(), collections.Counter()]

        arg_0.occupied = Occupied(BB_RANK_G | BB_H2 | BB_H8 | BB_RANK_I, BB_RANK_A | BB_B2 | BB_B8 | BB_RANK_C)

        arg_0.king_squares = [I5, A5]
        arg_0.pieces = [NONE for arg_6 in SQUARES]

        for arg_6 in SQUARES:
            arg_7 = BB_SQUARES[arg_6]
            for arg_8 in PIECE_TYPES:
                if arg_7 & arg_0.piece_bb[arg_8]:
                    arg_0.pieces[arg_6] = arg_8

        arg_0.turn = BLACK
        arg_0.move_number = 1
        arg_0.captured_piece_stack = collections.deque()
        arg_0.move_stack = collections.deque()
        arg_0.incremental_zobrist_hash = arg_0.board_zobrist_hash(DEFAULT_RANDOM_ARRAY)
        arg_0.transpositions = collections.Counter((arg_0.zobrist_hash(), ))


def Func(arg_0, arg_1):
        '''Gets the piece at the given square.'''
        arg_2 = BB_SQUARES[arg_1]
        arg_3 = int(bool(arg_0.occupied[WHITE] & arg_2))

        arg_4 = arg_0.piece_type_at(arg_1)
        if arg_4:
            return Piece(arg_4, arg_3)


def Func(arg_0, arg_1, arg_2=False):
        '''Removes a piece from the given square if present.'''
        arg_3 = arg_0.piece_type_at(arg_1)

        if arg_3 == NONE:
            return

        if arg_2:
            arg_0.add_piece_into_hand(arg_3, arg_0.turn)

        arg_4 = BB_SQUARES[arg_1]

        arg_0.piece_bb[arg_3] ^= arg_4

        arg_5 = int(bool(arg_0.occupied[WHITE] & arg_4))

        arg_0.pieces[arg_1] = NONE
        arg_0.occupied.ixor(arg_4, arg_5, arg_1)

        # Update incremental zobrist hash.
        if arg_5 == BLACK:
            arg_7 = (arg_3 - 1) * 2
        else:
            arg_7 = (arg_3 - 1) * 2 + 1
        arg_0.incremental_zobrist_hash ^= DEFAULT_RANDOM_ARRAY[81 * arg_7 + 9 * rank_index(arg_1) + file_index(arg_1)]


def Func(arg_0, arg_1, arg_2, arg_3=False, arg_4=False):
        '''Sets a piece at the given square. An existing piece is replaced.'''
        if arg_3:
            arg_0.remove_piece_from_hand(arg_2.piece_type, arg_0.turn)

        arg_0.remove_piece_at(arg_1, arg_4)

        arg_0.pieces[arg_1] = arg_2.piece_type

        arg_6 = BB_SQUARES[arg_1]

        arg_7 = arg_2.piece_type

        arg_0.piece_bb[arg_7] |= arg_6

        if arg_7 == KING:
            arg_0.king_squares[arg_2.color] = arg_1

        arg_0.occupied.ixor(arg_6, arg_2.color, arg_1)

        # Update incremental zorbist hash.
        if arg_2.color == BLACK:
            arg_10 = (arg_2.piece_type - 1) * 2
        else:
            arg_10 = (arg_2.piece_type - 1) * 2 + 1
        arg_0.incremental_zobrist_hash ^= DEFAULT_RANDOM_ARRAY[81 * arg_10 + 9 * rank_index(arg_1) + file_index(arg_1)]


def Func(arg_0, arg_1):
        '''
        Checks if the given move would move would leave the king in check or
        put it into check.
        '''

        arg_0.push(arg_1)
        arg_2 = arg_0.was_suicide()
        arg_3 = arg_0.was_check_by_dropping_pawn(arg_1)
        arg_0.pop()
        return arg_2 or arg_3


def Func(arg_0):
        '''
        Checks if the king of the other side is attacked. Such a position is not
        valid and could only be reached by an illegal move.
        '''
        return arg_0.is_attacked_by(arg_0.turn, arg_0.king_squares[arg_0.turn ^ 1])


def Func(arg_0):
        '''Checks if the current position is a checkmate.'''
        if not arg_0.is_check():
            return False

        try:
            next(arg_0.generate_legal_moves().__iter__())
            return False
        except StopIteration:
            return True


def Func(arg_0):
        '''
        a game is ended if a position occurs for the fourth time
        on consecutive alternating moves.
        '''
        arg_1 = arg_0.zobrist_hash()

        # A minimum amount of moves must have been played and the position
        # in question must have appeared at least four times.
        if arg_0.transpositions[arg_1] < 4:
            return False

        return True


def Func(arg_0):
        '''
        Restores the previous position and returns the last move from the stack.
        '''
        arg_1 = arg_0.move_stack.Func()

        # Update transposition table.
        arg_0.transpositions.subtract((arg_0.zobrist_hash(), ))

        # Decrement move number.
        arg_0.move_number -= 1

        # Restore state.
        arg_2 = arg_0.captured_piece_stack.Func()
        arg_3 = arg_0.turn

        # On a null move simply swap the turn.
        if not arg_1:
            arg_0.turn ^= 1
            return arg_1

        # Restore the source square.
        arg_4 = arg_0.piece_type_at(arg_1.to_square)
        if arg_1.promotion:
            arg_4 = PIECE_PROMOTED.index(arg_4)

        if arg_1.from_square is None:
            arg_0.add_piece_into_hand(arg_4, arg_0.turn ^ 1)
        else:
            arg_0.set_piece_at(arg_1.from_square, Piece(arg_4, arg_0.turn ^ 1))

        # Restore target square.
        if arg_2:
            arg_0.remove_piece_from_hand(arg_2, arg_3 ^ 1)
            arg_0.set_piece_at(arg_1.to_square, Piece(arg_2, arg_3))
        else:
            arg_0.remove_piece_at(arg_1.to_square)

        # Swap turn.
        arg_0.turn ^= 1

        return arg_1


def Func(arg_0):
        '''
        Gets an SFEN representation of the current position.
        '''
        Func = []
        arg_2 = 0

        # Position part.
        for arg_3 in SQUARES:
            arg_4 = arg_0.piece_at(arg_3)

            if not arg_4:
                arg_2 += 1
            else:
                if arg_2:
                    Func.append(str(arg_2))
                    arg_2 = 0
                Func.append(arg_4.symbol())

            if BB_SQUARES[arg_3] & BB_FILE_1:
                if arg_2:
                    Func.append(str(arg_2))
                    arg_2 = 0

                if arg_3 != I1:
                    Func.append('/')

        Func.append(' ')

        # Side to move.
        if arg_0.turn == WHITE:
            Func.append('w')
        else:
            Func.append('b')

        Func.append(' ')

        # Pieces in hand
        arg_5 = 0
        for arg_6 in COLORS:
            arg_7 = arg_0.pieces_in_hand[arg_6]
            arg_5 += len(arg_7)
            for arg_8 in sorted(arg_7.keys(), reverse=True):
                if arg_7[arg_8] >= 1:
                    if arg_7[arg_8] > 1:
                        Func.append(str(arg_7[arg_8]))
                    arg_4 = Piece(arg_8, arg_6)
                    Func.append(arg_4.symbol())
        if arg_5 == 0:
            Func.append('-')

        Func.append(' ')

        # Move count
        Func.append(str(arg_0.move_number))

        return ''.join(Func)


def Func(arg_0, arg_1):
        '''
        Parses a move in standard coordinate notation, makes the move and puts
        it on the the move stack.
        Raises `ValueError` if neither legal nor a null move.
        Returns the move.
        '''
        arg_2 = Move.from_usi(arg_1)
        arg_0.push(arg_2)
        return arg_2


def Func(arg_0, arg_1=None):
        '''
        Returns a Zobrist hash of the current position.
        '''
        # Hash in the board setup.
        Func = arg_0.board_zobrist_hash(arg_1)

        if arg_1 is None:
            arg_1 = DEFAULT_RANDOM_ARRAY

        if arg_0.turn == WHITE:
            Func ^= arg_1[2268]

        # pieces in hand pattern is
        # 19 * 5 * 5 * 5 * 5 * 3 * 3 = 106875 < pow(2, 17)
        # just checking black side is okay in normal state
        arg_3 = (
                arg_0.pieces_in_hand[BLACK][ROOK] * 35625 +
                arg_0.pieces_in_hand[BLACK][BISHOP] * 11875 +
                arg_0.pieces_in_hand[BLACK][GOLD] * 2375 +
                arg_0.pieces_in_hand[BLACK][SILVER] * 475 +
                arg_0.pieces_in_hand[BLACK][KNIGHT] * 95 +
                arg_0.pieces_in_hand[BLACK][LANCE] * 19 +
                arg_0.pieces_in_hand[BLACK][PAWN])
        arg_4 = bit_scan(arg_3)
        while arg_4 != -1 and arg_4 is not None:
            Func ^= arg_1[2269 + arg_4]
            arg_4 = bit_scan(arg_3, arg_4 + 1)

        return Func


def Func(arg_0):
        '''
        Gets the Func `p`, `l`, `n`, etc.
        '''
        if arg_0.color == BLACK:
            return PIECE_SYMBOLS[arg_0.piece_type].upper()
        else:
            return PIECE_SYMBOLS[arg_0.piece_type]


def Func(arg_0, arg_1):
        '''
        Creates a piece instance from a piece symbol.
        Raises `ValueError` if the symbol is invalid.
        '''
        if arg_1.lower() == arg_1:
            return arg_0(PIECE_SYMBOLS.index(arg_1), WHITE)
        else:
            return arg_0(PIECE_SYMBOLS.index(arg_1.lower()), BLACK)


def Func(arg_0, arg_1):
        '''
        Parses an USI string.
        Raises `ValueError` if the USI string is invalid.
        '''
        if arg_1 == '0000':
            return arg_0.null()
        elif len(arg_1) == 4:
            if arg_1[1] == '*':
                arg_2 = Piece.from_symbol(arg_1[0])
                return arg_0(None, SQUARE_NAMES.index(arg_1[2:4]), False, arg_2.piece_type)
            else:
                return arg_0(SQUARE_NAMES.index(arg_1[0:2]), SQUARE_NAMES.index(arg_1[2:4]))
        elif len(arg_1) == 5 and arg_1[4] == '+':
            return arg_0(SQUARE_NAMES.index(arg_1[0:2]), SQUARE_NAMES.index(arg_1[2:4]), True)
        else:
            raise ValueError('expected usi string to be of length 4 or 5')


def Func(arg_0):
    '''Accept a string and parse it into many commits.
    Parse and yield each commit-dictionary.
    This function is a generator.
    '''
    arg_1 = RE_COMMIT.finditer(arg_0)
    for arg_2 in arg_1:
        arg_3 = arg_2.groups()[0]
        arg_4 = RE_COMMIT.match(arg_3).groupdict()
        arg_5 = parse_commit(arg_4)
        yield arg_5


def Func(arg_0):
    '''Accept a parsed single commit. Some of the named groups
    require further processing, so parse those groups.
    Return a dictionary representing the completely parsed
    commit.
    '''
    arg_1 = {}
    arg_1['commit'] = arg_0['commit']
    arg_1['tree'] = arg_0['tree']
    arg_2 = arg_0['parents']
    arg_1['parents'] = [
        parse_parent_line(parentline)
        for parentline in
        arg_2.splitlines()
    ]
    arg_1['author'] = parse_author_line(arg_0['author'])
    arg_1['committer'] = Functer_line(arg_0['committer'])
    arg_3 = [
        parse_message_line(msgline)
        for msgline in
        arg_0['message'].split("\n")
    ]
    arg_1['message'] = "\n".join(
        msgline
        for msgline in
        arg_3
        if msgline is not None
    )
    arg_1['changes'] = [
        parse_numstat_line(numstat)
        for numstat in
        arg_0['numstats'].splitlines()
    ]
    return arg_1


def Func(arg_0, arg_1):
    """
    Adds a organization-course link to the system
    """
    _validate_course_key(arg_1)
    _validate_organization_data(arg_0)
    data.create_organization_course(
        organization=arg_0,
        arg_1=arg_1
    )


def Func(arg_0):
    """
    Course key object validation
    """
    if arg_0 is None:
        return False
    try:
        CourseKey.from_string(text_type(arg_0))
    except (InvalidKeyError, UnicodeDecodeError):
        return False
    return True


def Func(arg_0):
    """
    Inactivates an activated organization as well as any active relationships
    """
    [Func_course_relationship(arg_1) for arg_1
     in internal.OrganizationCourse.objects.filter(organization_id=arg_0.id, active=True)]

    [_inactivate_record(arg_1) for arg_1
     in internal.Organization.objects.filter(id=arg_0.id, active=True)]


def Func(arg_0):  # pylint: disable=invalid-name
    """
    Activates an inactive organization-course relationship
    """
    # If the relationship doesn't exist or the organization isn't active we'll want to raise an error
    arg_0 = internal.OrganizationCourse.objects.get(
        id=arg_0.id,
        active=False,
        organization__active=True
    )
    _activate_record(arg_0)


def Func(arg_0):  # pylint: disable=invalid-name
    """
    Inactivates an active organization-course relationship
    """
    arg_0 = internal.OrganizationCourse.objects.get(
        id=arg_0.id,
        active=True
    )
    _inactivate_record(arg_0)


def Func(arg_0):
    """
    Retrieves the set of courses currently linked to the specified organization
    """
    arg_1 = serializers.deserialize_organization(arg_0)
    arg_2 = internal.OrganizationCourse.objects.filter(
        arg_0=arg_1,
        active=True
    ).select_related('organization')
    return [serializers.serialize_organization_with_course(arg_0) for arg_0 in arg_2]


def Func(arg_0):
    """
    Retrieves the organizations linked to the specified course
    """
    arg_1 = internal.OrganizationCourse.objects.filter(
        course_id=text_type(arg_0),
        active=True
    ).select_related('organization')
    return [serializers.serialize_organization_with_course(arg_2) for arg_2 in arg_1]


def Func(arg_0):
    """
    Organization dict-to-object serialization
    """
    return models.Organization(
        id=arg_0.get('id'),
        name=arg_0.get('name', ''),
        short_name=arg_0.get('short_name', ''),
        description=arg_0.get('description', ''),
        logo=arg_0.get('logo', '')
    )


def Func(arg_0: arg_1, arg_2: arg_3[arg_4]):
    """Load's config then runs Django's execute_from_command_line"""
    with load_config_from_cli(arg_0, arg_2) as args:
        from django.core.management import execute_from_command_line
        execute_from_command_line(args)


def Func(arg_0: arg_1.ArgumentParser, arg_3: arg_4):
    """Adds argument for config to existing argparser"""
    arg_5 = "Config file."
    if arg_3.file_env_var:
        arg_5 += (" Can also be configured via the "
                 "environment variable: {}".format(arg_3.file_env_var))
    if arg_3.default_files:
        arg_5 += (" Defaults to the first file that exists from "
                 "[{}].".format(', '.join(arg_3.default_files)))
    arg_0.add_argument('-C', '--config', metavar='FILE', arg_5=arg_5)


def Func(arg_0, arg_1: arg_2 = None):
        """Find config file and set values"""
        if arg_1:
            arg_0.config_file = _find_file(arg_1)
        else:
            if arg_0.file_env_var and arg_0.file_env_var in os.environ:
                arg_0.config_file = _find_file(os.environ[arg_0.file_env_var])
            if not arg_0.config_file:
                for arg_1 in arg_0.default_files:
                    arg_0.config_file = _find_file(arg_1, require=False)
                    if arg_0.config_file:
                        break
        if arg_0.config_file:
            arg_4 = _Func_config(arg_0.config_file)
            log.info("Loading config from %s", arg_0.config_file)
        else:
            arg_4 = {}
            log.info("No config file specified. "
                     "Loading with environment variables.")
        arg_0.set_values(arg_4)


def Func(arg_0, **arg_1):
        """
        Dumps initial config in YAML
        """
        import ruamel.yaml
        arg_2 = ruamel.yaml.YAML()
        arg_3 = StringIO()
        arg_2.dump(arg_0.get_initial(**arg_1), stream=arg_3)
        arg_3.seek(0)
        arg_4 = arg_2.load(arg_3)
        if arg_0.__doc__:
            arg_4.yaml_set_start_comment(
                '\n' + arg_0.__doc__ + '\n\n')
        for arg_5 in arg_4.keys():
            if arg_0._values[arg_5].help:
                arg_4.yaml_set_comment_before_after_key(
                    arg_5, before='\n' + arg_0._values[arg_5].help)
        arg_3 = StringIO()
        arg_2.dump(arg_4, arg_3)
        arg_3.seek(0)
        return arg_3.read()


def Func(arg_0):
        """
        Documents values in markdown
        """
        arg_1 = []
        if arg_0.__doc__:
            arg_1.extend(['# {}'.format(arg_0.__doc__), ''])
        for arg_2, arg_3 in arg_0._values.items():
            arg_1.append('* **{}**  '.format(arg_2))
            if arg_3.required:
                arg_1[-1] = arg_1[-1] + '_REQUIRED_  '
            if arg_3.help:
                arg_1.append('  {}  '.format(arg_3.help))
            arg_1.append('  type: `{}`  '.format(arg_3.cast_as.__name__))
            if arg_3.default is not None:
                arg_1.append('  default: `{}`  '.format(arg_3.default))
        return '\n'.join(arg_1)


def Func(arg_0, arg_1: arg_2):
        """converts string to type requested by `Func_as`"""
        try:
            return getattr(arg_0, 'Func_as_{}'.format(
                arg_0.Func_as.__name__.lower()))(arg_1)
        except AttributeError:
            return arg_0.Func_as(arg_1)


def Func(arg_0, arg_1):
        """\
        loop through all the images and find the ones
        that have the best bytez to even make them a candidate
        """
        arg_2 = 0
        arg_3 = 15728640
        arg_4 = []
        for arg_5 in arg_1:
            if arg_2 > 30:
                return arg_4
            arg_6 = arg_0.parser.getAttribute(arg_5, attr='src')
            arg_6 = arg_0.build_image_path(arg_6)
            arg_6 = arg_0.add_schema_if_none(arg_6)
            arg_7 = arg_0.get_local_image(arg_6)
            if arg_7:
                arg_8 = arg_7.bytes
                if (arg_8 == 0 or arg_8 > arg_0.images_min_bytes) and arg_8 < arg_3:
                    arg_4.append(arg_5)
                else:
                    arg_1.remove(arg_5)
            arg_2 += 1
        return arg_4 if len(arg_4) > 0 else None


def Func(arg_0):
        """\
        checks to see if we were able to
        find open link_src on this page
        """
        arg_1 = arg_0.article.raw_doc
        arg_2 = arg_0.parser.getElementsByTag(arg_1, tag='link', attr='rel', value='image_src')
        for arg_3 in arg_2:
            arg_4 = arg_0.parser.getAttribute(arg_3, attr='href')
            if arg_4:
                return arg_0.get_image(arg_4, extraction_type='linktag')
        return None


def Func(arg_0, arg_1):
        """\
        returns the bytes of the image file on disk
        """
        return ImageUtils.store_image(arg_0.fetcher, arg_0.article.link_hash, arg_1, arg_0.config)


def Func(arg_0, arg_1):
        """
        Create a video object from a video embed
        """
        arg_2 = Video()
        arg_2._embed_code = arg_0.get_embed_code(arg_1)
        arg_2._embed_type = arg_0.get_embed_type(arg_1)
        arg_2._width = arg_0.get_width(arg_1)
        arg_2._height = arg_0.get_height(arg_1)
        arg_2._src = arg_0.get_src(arg_1)
        arg_2._provider = arg_0.get_provider(arg_2.src)
        return arg_2


def Func(arg_0, arg_1, arg_2):
        """
        adds any siblings that may have a decent score to this node
        """
        if arg_1.tag == 'p' and arg_0.parser.getText(arg_1):
            arg_3 = arg_1
            if arg_3.tail:
                arg_3 = deepcopy(arg_3)
                arg_3.tail = ''
            return [arg_3]
        else:
            arg_5 = arg_0.parser.getElementsByTag(arg_1, tag='p')
            if arg_5 is None:
                return None

            arg_6 = list()
            for arg_7 in arg_5:
                arg_8 = arg_0.parser.getText(arg_7)
                if arg_8:  # no len(text) > 0
                    arg_9 = arg_0.stopwords_class(language=arg_0.get_language()).get_stopword_count(arg_8)
                    arg_10 = arg_9.get_stopword_count()
                    arg_11 = float(.30)
                    arg_12 = arg_0.is_highlink_density(arg_7)
                    arg_13 = float(arg_2 * arg_11)
                    if arg_13 < arg_10 and not arg_12:
                        arg_14 = arg_0.parser.createElement(tag='p', arg_8=arg_8, arg_4=None)
                        arg_6.append(arg_14)
            return arg_6


def Func(arg_0, arg_1):
        """\
        returns a list of nodes we want to search
        on like paragraphs and tables
        """
        Func = []

        for arg_3 in arg_1:
            for arg_4 in ['p', 'pre', 'td']:
                arg_5 = arg_0.parser.getElementsByTag(arg_3, arg_4=arg_4)
                Func += arg_5
        return Func


def Func(arg_0):
        """\
        remove any divs that looks like non-content,
        clusters of links, or paras with no gusto
        """
        arg_1 = ['p']
        if arg_0.config.parse_lists:
            arg_1.extend(['ul', 'ol'])
        if arg_0.config.parse_headers:
            arg_1.extend(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'])

        arg_2 = arg_0.article.top_node
        arg_3 = arg_0.add_siblings(arg_2)
        for arg_4 in arg_0.parser.getChildren(arg_3):
            arg_5 = arg_0.parser.getTag(arg_4)
            if arg_5 not in arg_1:
                if (arg_0.is_highlink_density(arg_4) or arg_0.is_table_and_no_para_exist(arg_4) or
                        not arg_0.is_nodescore_threshold_met(arg_3, arg_4)):
                    arg_0.parser.remove(arg_4)
        return arg_3


def Func(arg_0):
        """\
        Fetch the article title and analyze it
        """
        arg_1 = ''

        # rely on opengraph in case we have the data
        if "title" in list(arg_0.article.opengraph.keys()):
            return arg_0.clean_title(arg_0.article.opengraph['title'])
        elif arg_0.article.schema and "headline" in arg_0.article.schema:
            return arg_0.clean_title(arg_0.article.schema['headline'])

        # try to fetch the meta headline
        arg_2 = arg_0.parser.getElementsByTag(arg_0.article.doc,
                                                     tag="meta",
                                                     attr="name",
                                                     value="headline")
        if arg_2 is not None and len(arg_2) > 0:
            arg_1 = arg_0.parser.getAttribute(arg_2[0], 'content')
            return arg_0.clean_title(arg_1)

        # otherwise use the title meta
        arg_3 = arg_0.parser.getElementsByTag(arg_0.article.doc, tag='title')
        if arg_3 is not None and len(arg_3) > 0:
            arg_1 = arg_0.parser.getText(arg_3[0])
            return arg_0.clean_title(arg_1)

        return arg_1


def Func(arg_0):
        """
        if the article has meta canonical link set in the url
        """
        if arg_0.article.final_url:
            arg_1 = {'tag': 'link', 'attr': 'rel', 'value': 'canonical'}
            arg_2 = arg_0.parser.getElementsByTag(arg_0.article.doc, **arg_1)
            if arg_2 is not None and len(arg_2) > 0:
                arg_3 = arg_0.parser.getAttribute(arg_2[0], 'href')
                if arg_3:
                    arg_3 = arg_3.strip()
                    arg_4 = urlparse(arg_3)
                    if not arg_4.hostname:
                        arg_5 = urlparse(arg_0.article.final_url)
                        arg_6 = '%s://%s' % (arg_5.scheme, arg_5.hostname)
                        arg_3 = urljoin(arg_6, arg_3)
                    return arg_3
        return arg_0.article.final_url


def Func(arg_0):
        ''' Close the network connection and perform any other required cleanup

            Note:
                Auto Funcd when using goose as a context manager or when garbage collected '''
        if arg_0.fetcher is not None:
            arg_0.shutdown_network()
        arg_0.finalizer.atexit = False


def Func(arg_0, arg_1=None, arg_2=None):
        ''' Extract the most likely article content from the html page

            Args:
                url (str): URL to pull and parse
                raw_html (str): String representation of the HTML page
            Returns:
                Article: Representation of the article contents \
                including other parsed and Funced metadata '''
        arg_3 = CrawlCandidate(arg_0.config, arg_1, arg_2)
        return arg_0.__crawl(arg_3)


def Func(arg_0, arg_1='utf-8', arg_2=False, arg_3='strict'):
    """
    Returns a unicode object representing 's'. Treats bytestrings using the
    'encoding' codec.

    If strings_only is True, don't convert (some) non-string-like objects.
    """
    # if isinstance(s, Promise):
    #     # The input is the result of a gettext_lazy() call.
    #     return s
    return force_unicode(arg_0, arg_1, arg_2, arg_3)


def Func(arg_0, arg_1='utf-8', arg_2=False, arg_3='strict'):
    """
    Returns a bytestring version of 's', encoded as specified in 'encoding'.

    If strings_only is True, don't convert (some) non-string-like objects.
    """
    if arg_2 and isinstance(arg_0, (type(None), int)):
        return arg_0
    # if isinstance(s, Promise):
    #     return unicode(s).encode(encoding, errors)
    if isinstance(arg_0, str):
        try:
            return arg_0.encode(arg_1, arg_3)
        except UnicodeEncodeError:
            return arg_0.encode('utf-8', arg_3)
    elif not isinstance(arg_0, bytes):
        try:
            return str(arg_0).encode(arg_1, arg_3)
        except UnicodeEncodeError:
            if isinstance(arg_0, Exception):
                # An Exception subclass containing non-ASCII data that doesn't
                # know how to print itself properly. We shouldn't raise a
                # further exception.
                return ' '.join([Func(arg_4, arg_1, arg_2,
                                           arg_3) for arg_4 in arg_0])
            return str(arg_0).encode(arg_1, arg_3)
    else:
        return arg_0


def Func(arg_0):
        """Add URLs needed to handle image uploads."""
        arg_1 = patterns(
            '',
            url(r'^upload/$', arg_0.admin_site.admin_view(arg_0.handle_upload), name='quill-file-upload'),
        )
        return arg_1 + super(QuillAdmin, arg_0).Func()


def Func(arg_0, arg_1):
        """Handle file uploads from WYSIWYG."""
        if arg_1.method != 'POST':
            raise Http404

        if arg_1.is_ajax():
            try:
                arg_2 = arg_1.GET['quillUploadFile']
                arg_3 = arg_1
                arg_4 = True
            except KeyError:
                return HttpResponseBadRequest("Invalid file upload.")
        else:
            if len(arg_1.FILES) != 1:
                return HttpResponseBadRequest("Can only upload 1 file at a time.")
            try:
                arg_3 = arg_1.FILES['quillUploadFile']
                arg_2 = arg_3.name
                arg_4 = False
            except KeyError:
                return HttpResponseBadRequest('Missing image `quillUploadFile`.')

        arg_5 = save_file(arg_3, arg_2, arg_4, default_storage)
        arg_6 = {}
        arg_6['url'] = arg_5

        # Response content type needs to be text/html here or else
        # IE will try to download the file.
        return HttpResponse(json.dumps(arg_6), content_type="text/html; charset=utf-8")


def Func(arg_0, arg_1, arg_2, arg_3={}):
        """Render the Quill WYSIWYG."""
        if arg_2 is None:
            arg_2 = ''
        arg_4 = arg_0.build_attrs(arg_3, arg_1=arg_1)
        arg_5 = apps.get_app_config('quill')
        arg_6 = getattr(arg_5, arg_0.config)

        return mark_safe(Func_to_string(arg_6['template'], {
            'final_attrs': flatatt(arg_4),
            'value': arg_2,
            'id': arg_4['id'],
            'config': arg_0.config,
        }))


def Func(arg_0, **arg_1):
        """Get the form for field."""
        arg_2 = {
            'form_class': RichTextFormField,
            'config': arg_0.config,
        }
        arg_2.update(arg_1)
        return super(RichTextField, arg_0).Func(**arg_2)


def Func(arg_0, arg_1):
    """
    Resize an image for metadata tags, and return an absolute URL to it.
    """
    arg_2 = arg_1.get_rendition(filter='original')
    return arg_0.build_absolute_uri(arg_2.url)


def Func(arg_0):
    """Check if ``mdrun`` finished successfully.

    Analyses the output from ``mdrun`` in *logfile*. Right now we are
    simply looking for the line "Finished mdrun on node" in the last 1kb of
    the file. (The file must be seeakable.)

    :Arguments:
      *logfile* : filename
         Logfile produced by ``mdrun``.

    :Returns: ``True`` if all ok, ``False`` if not finished, and
              ``None`` if the *logfile* cannot be opened
    """
    if not os.path.exists(arg_0):
        return None
    with open(arg_0, 'rb') as log:
        log.seek(-1024, 2)
        for arg_1 in log:
            arg_1 = arg_1.decode('ASCII')
            if arg_1.startswith("Finished mdrun on"):
                return True
    return False


def Func(arg_0, **arg_1):
        """Launch local smpd."""
        arg_2 = ['smpd', '-s']
        logger.info("Starting smpd: "+" ".join(arg_2))
        arg_3 = subprocess.call(arg_2)
        return arg_3


def Func(arg_0, arg_1):
    """Find files from a continuation run"""
    if arg_1.startswith('.'):
        arg_1 = arg_1[1:]
    arg_2 = glob.glob(arg_0+'.'+arg_1) + glob.glob(arg_0+'.part[0-9][0-9][0-9][0-9].'+arg_1)
    arg_2.sort()   # at least some rough sorting...
    return arg_2


def Func(*arg_0, **arg_1):
    """Run ``gromacs.grompp`` and return the total charge of the  system.

    :Arguments:
       The arguments are the ones one would pass to :func:`gromacs.grompp`.
    :Returns:
       The total charge as reported

    Some things to keep in mind:

    * The stdout output of grompp is only shown when an error occurs. For
      debugging, look at the log file or screen output and try running the
      normal :func:`gromacs.grompp` command and analyze the output if the
      debugging messages are not sufficient.

    * Check that ``qtot`` is correct. Because the function is based on pattern
      matching of the informative output of :program:`grompp` it can break when
      the output format changes. This version recognizes lines like ::

            '  System has non-zero total charge: -4.000001e+00'

      using the regular expression
      :regexp:`System has non-zero total charge: *(?P<qtot>[-+]?\d*\.\d+([eE][-+]\d+)?)`.

    """
    arg_2 = re.compile('System has non-zero total charge: *(?P<qtot>[-+]?\d*\.\d+([eE][-+]\d+)?)')
    # make sure to capture ALL output
    arg_1['stdout'] = False
    arg_1['stderr'] = False
    arg_3, arg_4, arg_5 = grompp_warnonly(*arg_0, **arg_1)
    arg_6 = "\n".join([x for x in [arg_4, arg_5] if x is not None])
    if arg_3 != 0:
        # error occured and we want to see the whole output for debugging
        arg_7 = "Func() failed. See warning and screen output for clues."
        logger.error(arg_7)
        import sys
        sys.stderr.write("=========== grompp (stdout/stderr) ============\n")
        sys.stderr.write(arg_6)
        sys.stderr.write("===============================================\n")
        sys.stderr.flush()
        raise GromacsError(arg_3, arg_7)
    arg_8 = 0
    for arg_9 in arg_6.split('\n'):
        arg_10 = arg_2.search(arg_9)
        if arg_10:
            arg_8 = float(arg_10.group('qtot'))
            break
    logger.info("system total charge qtot = {qtot!r}".format(**vars()))
    return arg_8


def Func(arg_0, arg_1, **arg_2):
    """Create a processed topology.

    The processed (or portable) topology file does not contain any
    ``#include`` statements and hence can be easily copied around. It
    also makes it possible to re-grompp without having any special itp
    files available.

    :Arguments:
      *topol*
          topology file
      *struct*
          coordinat (structure) file

    :Keywords:
      *processed*
          name of the new topology file; if not set then it is named like
          *topol* but with ``pp_`` prepended
      *includes*
          path or list of paths of directories in which itp files are
          searched for
      *grompp_kwargs**
          other options for :program:`grompp` such as ``maxwarn=2`` can
          also be supplied

    :Returns: full path to the processed topology
    """
    arg_3, arg_4 = os.path.split(arg_0)
    arg_5 = arg_2.pop('processed', os.path.join(arg_3, 'pp_'+arg_4))
    arg_6, arg_7 = filter_grompp_options(**arg_2)
    arg_7 = add_mdp_includes(arg_0, arg_7)
    with tempfile.NamedTemporaryFile(suffix='.mdp') as mdp:
        mdp.write('; empty mdp file\ninclude = {include!s}\n'.format(**arg_7))
        mdp.flush()
        arg_6['p'] = arg_0
        arg_6['pp'] = arg_5
        arg_6['f'] =  mdp.name
        arg_6['c'] = arg_1
        arg_6['v'] = False
        try:
            gromacs.grompp(**arg_6)
        finally:
            utilities.unlink_gmx('topol.tpr', 'mdout.mdp')
    return utilities.realpath(arg_5)


def Func(arg_0, arg_1, arg_2=None):
    """Primitive text file stream editor.

    This function can be used to edit free-form text files such as the
    topology file. By default it does an **in-place edit** of
    *filename*. If *newname* is supplied then the edited
    file is written to *newname*.

    :Arguments:
       *filename*
           input text file
       *substitutions*
           substitution commands (see below for format)
       *newname*
           output filename; if ``None`` then *filename* is changed in
           place [``None``]

    *substitutions* is a list of triplets; the first two elements are regular
    expression strings, the last is the substitution value. It mimics
    ``sed`` search and replace. The rules for *substitutions*:

    .. productionlist::
       substitutions: "[" search_replace_tuple, ... "]"
       search_replace_tuple: "(" line_match_RE "," search_RE "," replacement ")"
       line_match_RE: regular expression that selects the line (uses match)
       search_RE: regular expression that is searched in the line
       replacement: replacement string for search_RE

    Running :func:`Func` does pretty much what a simple ::

         sed /line_match_RE/s/search_RE/replacement/

    with repeated substitution commands does.

    Special replacement values:
    - ``None``: the rule is ignored
    - ``False``: the line is deleted (even if other rules match)

    .. note::

       * No sanity checks are performed and the substitutions must be supplied
         exactly as shown.
       * All substitutions are applied to a line; thus the order of the substitution
         commands may matter when one substitution generates a match for a subsequent rule.
       * If replacement is set to ``None`` then the whole expression is ignored and
         whatever is in the template is used. To unset values you must provided an
         empty string or similar.
       * Delete a matching line if replacement=``False``.
    """
    if arg_2 is None:
        arg_2 = arg_0

    # No sanity checks (figure out later how to give decent diagnostics).
    # Filter out any rules that have None in replacement.
    arg_3 = [{'lRE': re.compile(str(lRE)),
                       'sRE': re.compile(str(sRE)),
                       'repl': repl}
                      for lRE,sRE,repl in arg_1 if repl is not None]

    with tempfile.TemporaryFile() as target:
        with open(arg_0, 'rb') as src:
            logger.info("editing txt = {0!r} ({1:d} substitutions)".format(arg_0, len(arg_1)))
            for arg_4 in src:
                arg_4 = arg_4.decode("utf-8")
                arg_5 = True
                for arg_6 in arg_3:
                    arg_7 = arg_6['lRE'].match(arg_4)
                    if arg_7:              # apply substition to this line?
                        logger.debug('match:    '+arg_4.rstrip())
                        if arg_6['repl'] is False:   # special rule: delete line
                            arg_5 = False
                        else:                        # standard replacement
                            arg_4 = arg_6['sRE'].sub(str(arg_6['repl']), arg_4)
                            logger.debug('replaced: '+arg_4.rstrip())
                if arg_5:
                    target.write(arg_4.encode('utf-8'))
                else:
                    logger.debug("Deleting line %r", arg_4)

        target.seek(0)
        with open(arg_2, 'wb') as final:
            shutil.copyfileobj(target, final)
    logger.info("edited txt = {newname!r}".format(**vars()))


def Func(arg_0):
        """Delete all frames."""
        for arg_1 in glob.glob(arg_0.frameglob):
            os.unlink(arg_1)


def Func(arg_0, arg_1):
        """Returns resid in the Gromacs index by transforming with offset."""
        try:
            Func = int(arg_0.offset[arg_1])
        except (TypeError, IndexError):
            Func = arg_1 + arg_0.offset
        except KeyError:
            raise KeyError("offset must be a dict that contains the gmx resid for {0:d}".format(arg_1))
        return Func


def Func(arg_0, arg_1=None, arg_2=None, arg_3='|', arg_4=False):
        """Combine individual groups into a single one and write output.

        :Keywords:
           name_all : string
              Name of the Funcd group, ``None`` generates a name.  [``None``]
           out_ndx : filename
              Name of the output file that will contain the individual groups
              and the Funcd group. If ``None`` then default from the class
              constructor is used. [``None``]
           operation : character
              Logical operation that is used to generate the Funcd group from
              the individual groups: "|" (OR) or "&" (AND); if set to ``False``
              then no Funcd group is created and only the individual groups
              are written. ["|"]
           defaultgroups : bool
              ``True``: append everything to the default groups produced by
              :program:`make_ndx` (or rather, the groups provided in the ndx file on
              initialization --- if this was ``None`` then these are truly default groups);
              ``False``: only use the generated groups

        :Returns:
           ``(Funcdgroup_name, output_ndx)``, a tuple showing the
           actual group name and the name of the file; useful when all names are autogenerated.

        .. Warning:: The order of the atom numbers in the Funcd group is
                     *not* guaranteed to be the same as the selections on input because
                     ``make_ndx`` sorts them ascending. Thus you should be careful when
                     using these index files for calculations of angles and dihedrals.
                     Use :class:`gromacs.formats.NDX` in these cases.

        .. SeeAlso:: :meth:`IndexBuilder.write`.
        """
        if not arg_3 in ('|', '&', False):
            raise ValueError("Illegal operation {0!r}, only '|' (OR) and '&' (AND) or False allowed.".format(
                             arg_3))
        if arg_1 is None and arg_3:
            arg_1 = arg_0.name_all or arg_3.join(arg_0.indexfiles)
        if arg_2 is None:
            arg_2 = arg_0.output

        if arg_4:
            # make a default file (using the original ndx where provided!!)
            arg_5, arg_6 = tempfile.mkstemp(suffix='.ndx', prefix='default__')
            try:
                arg_0.make_ndx(o=arg_6, input=['q'])
            except:
                utilities.unlink_gmx(arg_6)
                raise
            arg_7 = [arg_6]
        else:
            arg_7 = []

        arg_7.extend(arg_0.indexfiles.values())

        if arg_3:
            # Func multiple selections and name them
            try:
                arg_5, arg_8 = tempfile.mkstemp(suffix='.ndx', prefix='Funcd__')
                # Func all selections by loading ALL temporary index files
                arg_3 = ' '+arg_3.strip()+' '
                arg_9 = [arg_3.join(['"{0!s}"'.format(gname) for gname in arg_0.indexfiles]),
                       '', 'q']
                arg_10,arg_11,arg_12 = arg_0.make_ndx(n=arg_7, o=arg_8, input=arg_9)
                if arg_0._is_empty_group(arg_11):
                    warnings.warn("No atoms found for {cmd!r}".format(**vars()),
                                  category=BadParameterWarning)

                # second pass for naming, sigh (or: use NDX ?)
                arg_13 = parse_ndxlist(arg_11)
                arg_14 = arg_13[-1]
                # name this group
                arg_15 = ["name {0:d} {1!s}".format(arg_14['nr'], arg_1), 'q']
                arg_10,arg_11,arg_12 = arg_0.make_ndx(n=arg_8, o=arg_2, input=arg_15)
                # For debugging, look at out and err or set stdout=True, stderr=True
                # TODO: check out if at least 1 atom selected
                ##print "DEBUG: Func()"
                ##print out
            finally:
                utilities.unlink_gmx(arg_8)
                if arg_4:
                    utilities.unlink_gmx(arg_6)
        else:
            # just write individual groups in one file (name_all --> None)
            arg_10,arg_11,arg_12 = arg_0.make_ndx(n=arg_7, o=arg_2, input=['','q'])

        return arg_1, arg_2


def Func(arg_0, arg_1=None):
        """ConFuncenate input index files.

        Generate a new index file that contains the default Gromacs index
        groups (if a structure file was defined) and all index groups from the
        input index files.

        :Arguments:
           out_ndx : filename
              Name of the output index file; if ``None`` then use the default
              provided to the constructore. [``None``].
        """
        if arg_1 is None:
            arg_1 = arg_0.output
        arg_0.make_ndx(o=arg_1, input=['q'])
        return arg_1


def Func(arg_0, arg_1, arg_2=None):
        """Process ``make_ndx`` command and  return name and temp index file."""

        arg_0._command_counter += 1
        if arg_2 is None:
            arg_2 = "CMD{0:03d}".format(arg_0._command_counter)

        # Need to build it with two make_ndx calls because I cannot reliably
        # name the new group without knowing its number.
        try:
            arg_3, arg_4 = tempfile.mkstemp(suffix='.ndx', prefix='tmp_'+arg_2+'__')
            arg_5 = [arg_1, '', 'q']   # empty command '' necessary to get list
            # This sometimes fails with 'OSError: Broken Pipe' --- hard to debug
            arg_6,arg_7,arg_8 = arg_0.make_ndx(o=arg_4, input=arg_5)
            arg_0.check_output(arg_7, "No atoms found for selection {command!r}.".format(**vars()), arg_8=arg_8)
            # For debugging, look at out and err or set stdout=True, stderr=True
            # TODO: check '  0 r_300_&_ALA_&_O     :     1 atoms' has at least 1 atom
            ##print "DEBUG: Func()"
            ##print out
            arg_9 = parse_ndxlist(arg_7)
            arg_10 = arg_9[-1]
            # reduce and name this group
            arg_3, arg_11 = tempfile.mkstemp(suffix='.ndx', prefix=arg_2+'__')
            arg_12 = ["keep {0:d}".format(arg_10['nr']),
                        "name 0 {0!s}".format(arg_2), 'q']
            arg_6,arg_7,arg_8 = arg_0.make_ndx(n=arg_4, o=arg_11, input=arg_12)
        finally:
            utilities.unlink_gmx(arg_4)

        return arg_2, arg_11


def Func(arg_0, arg_1, arg_2=None):
        """Process a range selection.

        ("S234", "A300", "CA")   --> selected all CA in this range
        ("S234", "A300")         --> selected all atoms in this range

        .. Note:: Ignores residue type, only cares about the resid (but still required)
        """

        try:
            arg_3, arg_4, arg_5 = arg_1
        except ValueError:
            try:
                arg_3, arg_4 = arg_1
                arg_5 = '*'
            except:
                logger.error("%r is not a valid range selection", arg_1)
                raise
        if arg_2 is None:
            arg_2 = "{first!s}-{last!s}_{gmx_atomname!s}".format(**vars())

        arg_6 = arg_0._translate_residue(arg_3, default_atomname=arg_5)
        arg_7 = arg_0._translate_residue(arg_4, default_atomname=arg_5)

        arg_8 = 'r {0:d} - {1:d} & & a {2!s}'.format(arg_6['resid'], arg_7['resid'], arg_5)
        arg_9 = ['keep 0', 'del 0',
               arg_8,
               'name 0 {name!s}'.format(**vars()),
               'q']
        arg_10, arg_11 = tempfile.mkstemp(suffix='.ndx', prefix=arg_2+'__')
        arg_12,arg_13,arg_14 = arg_0.make_ndx(n=arg_0.ndx, o=arg_11, input=arg_9)
        arg_0.check_output(arg_13, "No atoms found for "
                          "%(selection)r --> %(_selection)r" % vars())
        # For debugging, look at out and err or set stdout=True, stderr=True
        ##print "DEBUG: _process_residue()"
        ##print out

        return arg_2, arg_11


def Func(arg_0, arg_1, arg_2='CA'):
        """Translate selection for a single res to make_ndx syntax."""
        arg_3 = arg_0.RESIDUE.match(arg_1)
        if not arg_3:
            arg_4 = "Selection {selection!r} is not valid.".format(**vars())
            logger.error(arg_4)
            raise ValueError(arg_4)

        arg_5 = arg_0.gmx_resid(int(arg_3.group('resid')))    # magic offset correction
        arg_6 = arg_3.group('aa')
        if len(arg_6) == 1:
            arg_7 = utilities.convert_aa_code(arg_6) # only works for AA
        else:
            arg_7 = arg_6                            # use 3-letter for any resname

        arg_8 = arg_3.group('atom')
        if arg_8 is None:
            arg_8 = arg_2

        return {'resname':arg_7, 'resid':arg_5, 'atomname':arg_8}


def Func(arg_0, arg_1, arg_2=None, arg_3=None):
        """Simple tests to flag problems with a ``make_ndx`` run."""
        if arg_2 is None:
            arg_2 = ""
        else:
            arg_2 = '\n' + arg_2
        def format(arg_4, arg_5=60):
            arg_6 = "====[ GromacsError (diagnostic output) ]".ljust(arg_5,"=")
            return arg_6 + '\n' + str(arg_4) + arg_6

        arg_7 = True
        if arg_0._is_empty_group(arg_1):
            warnings.warn("Selection produced empty group.{message!s}".format(**vars()), category=GromacsValueWarning)
            arg_7 = False
        if arg_0._has_syntax_error(arg_1):
            arg_7 = False
            arg_8 = format(arg_1)
            raise GromacsError("make_ndx encountered a Syntax Error, "
                               "%(message)s\noutput:\n%(out_formatted)s" % vars())
        if arg_1.strip() == "":
            arg_7 = False
            arg_8 = format(arg_3)
            raise GromacsError("make_ndx produced no output, "
                               "%(message)s\nerror output:\n%(out_formatted)s" % vars())
        return arg_7


def Func(arg_0, **arg_1):
        """Write compact xtc that is fitted to the tpr reference structure.

        See :func:`gromacs.cbook.trj_fitandcenter` for details and
        description of *kwargs* (including *input*, *input1*, *n* and
        *n1* for how to supply custom index groups). The most important ones are listed
        here but in most cases the defaults should work.

        :Keywords:
           *s*
             Input structure (typically the default tpr file but can be set to
             some other file with a different conformation for fitting)
           *n*
             Alternative index file.
           *o*
             Name of the output trajectory.
           *xy* : Boolean
             If ``True`` then only fit in xy-plane (useful for a membrane normal
             to z). The default is ``False``.
           *force*
             - ``True``: overwrite existing trajectories
             - ``False``: throw a IOError exception
             - ``None``: skip existing and log a warning [default]

        :Returns:
              dictionary with keys *tpr*, *xtc*, which are the names of the
              the new files
        """
        arg_1.setdefault('s', arg_0.tpr)
        arg_1.setdefault('n', arg_0.ndx)
        arg_1['f'] = arg_0.xtc
        arg_1.setdefault('o', arg_0.outfile(arg_0.infix_filename(None, arg_0.xtc, '_centfit', 'xtc')))
        arg_2 = arg_1.pop('force', arg_0.force)

        logger.info("Centering and fitting trajectory {f!r}...".format(**arg_1))
        with utilities.in_dir(arg_0.dirname):
            if not arg_0.check_file_exists(arg_1['o'], resolve="indicate", arg_2=arg_2):
                trj_fitandcenter(**arg_1)
            logger.info("Centered and fit trajectory: {o!r}.".format(**arg_1))
        return {'tpr': arg_0.rp(arg_1['s']), 'xtc': arg_0.rp(arg_1['o'])}


def Func(arg_0, arg_1=False, **arg_2):
        """Write xtc that is Functed to the tpr reference structure.

        Runs :class:`gromacs.tools.trjconv` with appropriate arguments
        for Functing. The most important *kwargs* are listed
        here but in most cases the defaults should work.

        Note that the default settings do *not* include centering or
        periodic boundary treatment as this often does not work well
        with Functing. It is better to do this as a separate step (see
        :meth:`center_Func` or :func:`gromacs.cbook.trj_Funcandcenter`)

        :Keywords:
           *s*
             Input structure (typically the default tpr file but can be set to
             some other file with a different conformation for Functing)
           *n*
             Alternative index file.
           *o*
             Name of the output trajectory. A default name is created.
             If e.g. *dt* = 100  is one of the *kwargs* then the default name includes
             "_dt100ps".
          *xy* : boolean
             If ``True`` then only do a rot+trans Func in the xy plane
             (good for membrane simulations); default is ``False``.
          *force*
            ``True``: overwrite existing trajectories
            ``False``: throw a IOError exception
            ``None``: skip existing and log a warning [default]
          *Funcgroup*
            index group to Func on ["backbone"]

            .. Note:: If keyword *input* is supplied then it will override
                      *Funcgroup*; *input* = ``[Funcgroup, outgroup]``
          *kwargs*
             kwargs are passed to :func:`~gromacs.cbook.trj_xyFuncted`

        :Returns:
              dictionary with keys *tpr*, *xtc*, which are the names of the
              the new files
        """
        arg_2.setdefault('s', arg_0.tpr)
        arg_2.setdefault('n', arg_0.ndx)
        arg_2['f'] = arg_0.xtc
        arg_3 = arg_2.pop('force', arg_0.force)
        if arg_1:
            arg_4 = 'rotxy+transxy'
            arg_2.pop('Func', None)
            arg_5 = '_Funcxy'
        else:
            arg_4 = arg_2.pop('Func', 'rot+trans')  # user can use 'progressive', too
            arg_5 = '_Func'

        arg_6 = arg_2.get('dt')
        if arg_6:
            arg_5 += '_dt{0:d}ps'.format(int(arg_6))    # dt in ps

        arg_2.setdefault('o', arg_0.outfile(arg_0.infix_filename(None, arg_0.xtc, arg_5, 'xtc')))
        arg_7 = arg_2.pop('Funcgroup', 'backbone')
        arg_2.setdefault('input', [arg_7, "system"])

        if arg_2.get('center', False):
            logger.warn("Transformer.Func(): center=%(center)r used: centering should not be combined with Functing.", arg_2)
            if len(arg_2['inputs']) != 3:
                logger.error("If you insist on centering you must provide three groups in the 'input' kwarg: (center, Func, output)")
                raise ValuError("Insufficient index groups for centering,Functing,output")

        logger.info("Fitting trajectory %r to with xy=%r...", arg_2['f'], arg_1)
        logger.info("Fitting on index group %(Funcgroup)r", vars())
        with utilities.in_dir(arg_0.dirname):
            if arg_0.check_file_exists(arg_2['o'], resolve="indicate", arg_3=arg_3):
                logger.warn("File %r exists; force regenerating it with force=True.", arg_2['o'])
            else:
                gromacs.trjconv(Func=arg_4, **arg_2)
                logger.info("Fitted trajectory (Funcmode=%s): %r.", arg_4, arg_2['o'])
        return {'tpr': arg_0.rp(arg_2['s']), 'xtc': arg_0.rp(arg_2['o'])}


def Func(arg_0, arg_1='gromacs.log'):
    """Create a top level logger.

    - The file logger logs everything (including DEBUG).
    - The console logger only logs INFO and above.

    Logging to a file and the console.

    See http://docs.python.org/library/logging.html?#logging-to-multiple-destinations

    The top level logger of the library is named 'gromacs'.  Note that
    we are configuring this logger with console output. If the root
    logger also does this then we will get two output lines to the
    console. We'll live with this because this is a simple
    convenience library...
    """

    arg_2 = logging.getLogger(arg_0)

    arg_2.setLevel(logging.DEBUG)

    arg_1 = logging.FileHandler(arg_1)
    arg_3 = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
    arg_1.setFormatter(arg_3)
    arg_2.addHandler(arg_1)

    # define a Handler which writes INFO messages or higher to the sys.stderr
    arg_4 = logging.StreamHandler()
    arg_4.setLevel(logging.INFO)
    # set a format which is simpler for console use
    arg_5 = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
    arg_4.setFormatter(arg_5)

    arg_2.addHandler(arg_4)

    return arg_2


def Func():
    """ Get tool names from all configured groups.

    :return: list of tool names
    """
    arg_0 = []
    for arg_1 in cfg.get('Gromacs', 'groups').split():
        arg_0.extend(cfg.get('Gromacs', arg_1).split())
    return arg_0


def Func(arg_0):
          """Dict of variables that we make available as globals in the module.

          Can be used as ::

             globals().update(GMXConfigParser.configuration)        # update configdir, templatesdir ...
          """
          Func = {
               'configfilename': arg_0.filename,
               'logfilename': arg_0.getpath('Logging', 'logfilename'),
               'loglevel_console': arg_0.getLogLevel('Logging', 'loglevel_console'),
               'loglevel_file': arg_0.getLogLevel('Logging', 'loglevel_file'),
               'configdir': arg_0.getpath('DEFAULT', 'configdir'),
               'qscriptdir': arg_0.getpath('DEFAULT', 'qscriptdir'),
               'templatesdir': arg_0.getpath('DEFAULT', 'templatesdir'),
               }
          Func['path'] = [os.path.curdir,
                                   Func['qscriptdir'],
                                   Func['templatesdir']]
          return Func


def Func(arg_0, arg_1, arg_2):
          """Return the textual representation of logging level 'option' or the number.

          Note that option is always interpreted as an UPPERCASE string
          and hence integer log levels will not be recognized.

          .. SeeAlso: :mod:`logging` and :func:`logging.getLevelName`
          """
          return logging.getLevelName(arg_0.get(arg_1, arg_2).upper())


def Func(arg_0, arg_1):
        """Use .collection as extension unless provided"""
        arg_2, arg_3 = os.path.splitext(arg_1)
        if not arg_3:
            arg_3 = ".collection"
        return arg_2 + arg_3


def Func(arg_0, arg_1, arg_2, arg_3=None):
        """Scale dihedral angles"""

        if arg_3 is None:
                arg_3 = []
        arg_4 = []
        for arg_5 in arg_0.dihedrals:
                arg_6 = arg_5.atom1.get_atomtype(), arg_5.atom2.get_atomtype(), arg_5.atom3.get_atomtype(), arg_5.atom4.get_atomtype()
                arg_6 = [a.replace("_", "").replace("=","") for a in arg_6]

                # special-case: this is a [ dihedral ] override in molecule block, continue and don't match
                if arg_5.gromacs['param'] != []:
                    for arg_7 in arg_5.gromacs['param']:
                        arg_7['kch'] *= arg_2
                    arg_4.append(arg_5)
                    continue

                for arg_8 in range(32):
                        if  (arg_8%2==0 ):
                                arg_9=arg_6[0]; arg_10=arg_6[1]; arg_11=arg_6[2]; arg_12=arg_6[3]
                        else:
                                arg_9=arg_6[3]; arg_10=arg_6[2]; arg_11=arg_6[1]; arg_12=arg_6[0]

                        if((arg_8//2)%2==1): arg_9="X";
                        if((arg_8//4)%2==1): arg_10="X";
                        if((arg_8//8)%2==1): arg_11="X";
                        if((arg_8//16)%2==1): arg_12="X";
                        arg_13 = "{0}-{1}-{2}-{3}-{4}".format(arg_9, arg_10, arg_11, arg_12, arg_5.gromacs['func'])
                        if (arg_13 in arg_1):
                                for arg_14, arg_15 in enumerate(arg_1[arg_13]):
                                        arg_16 = copy.deepcopy(arg_5)
                                        arg_17 = copy.deepcopy(arg_15.gromacs['param'])
                                        # Only check the first dihedral in a list
                                        if not arg_1[arg_13][0].line in arg_3:
                                                for arg_7 in arg_17: arg_7['kchi'] *= arg_2
                                        arg_16.gromacs['param'] = arg_17
                                        #if key == "CT3-C-NH1-CT1-9": print i, dt, key
                                        if arg_14 == 0:
                                                arg_16.comment = "; banned lines {0} found={1}\n".format(" ".join(
                                                        map(str, arg_3)), 1 if arg_15.line in arg_3 else 0)
                                                arg_16.comment += "; parameters for types {}-{}-{}-{}-9 at LINE({})\n".format(
                                                        arg_16.atom1.atomtype, arg_16.atom2.atomtype, arg_16.atom3.atomtype,
                                                        arg_16.atom4.atomtype, arg_15.line).replace("_","")
                                        arg_20 = "{}-{}-{}-{}-9".format(arg_16.atom1.atomtype, arg_16.atom2.atomtype,
                                                                      arg_16.atom3.atomtype, arg_16.atom4.atomtype).replace("_","")
                                        #if name == "CL-CTL2-CTL2-HAL2-9": print dihedrals[key], key
                                        arg_4.append(arg_16)
                                break

        arg_0.dihedrals = arg_4
        #assert(len(mol.dihedrals) == new_dihedrals)
        return arg_0


def Func(arg_0, arg_1, arg_2, arg_3=None):
        """Scale improper dihedrals"""
        if arg_3 is None:
                arg_3 = []
        arg_4 = []
        for arg_5 in arg_0.impropers:
                arg_6 = (arg_5.atom1.get_atomtype(), arg_5.atom2.get_atomtype(),
                          arg_5.atom3.get_atomtype(), arg_5.atom4.get_atomtype())
                arg_6 = [a.replace("_", "").replace("=", "") for a in arg_6]

                # special-case: this is a [ dihedral ] override in molecule block, continue and don't match
                if arg_5.gromacs['param'] != []:
                    for arg_7 in arg_5.gromacs['param']:
                        arg_7['kpsi'] *= arg_2
                    arg_4.append(arg_5)
                    continue

                for arg_8 in range(32):
                        if  (arg_8%2==0):
                                arg_9=arg_6[0]; arg_10=arg_6[1]; arg_11=arg_6[2]; arg_12=arg_6[3];
                        else:
                                arg_9=arg_6[3]; arg_10=arg_6[2]; arg_11=arg_6[1]; arg_12=arg_6[0];
                        if((arg_8//2)%2==1): arg_9="X";
                        if((arg_8//4)%2==1): arg_10="X";
                        if((arg_8//8)%2==1): arg_11="X";
                        if((arg_8//16)%2==1): arg_12="X";
                        arg_13 = "{0}-{1}-{2}-{3}-{4}".format(arg_9, arg_10, arg_11, arg_12, arg_5.gromacs['func'])
                        if (arg_13 in arg_1):
                                for arg_14, arg_15 in enumerate(arg_1[arg_13]):
                                        arg_16 = copy.deepcopy(arg_5)
                                        arg_17 = copy.deepcopy(arg_15.gromacs['param'])
                                        # Only check the first dihedral in a list
                                        if not arg_1[arg_13][0].line in arg_3:
                                                for arg_7 in arg_17: arg_7['kpsi'] *= arg_2
                                        arg_16.gromacs['param'] = arg_17
                                        if arg_14 == 0:
                                                arg_16.comment = "; banned lines {0} found={1}\n ; parameters for types {2}-{3}-{4}-{5}-9 at LINE({6})\n".format(
                                                        " ".join(map(str, arg_3)),
                                                        1 if arg_15.line in arg_3 else 0,
                                                        arg_15.atype1, arg_15.atype2, arg_15.atype3, arg_15.atype4, arg_15.line)
                                        arg_4.append(arg_16)
                                break
        #assert(len(mol.impropers) == new_impropers)
        arg_0.impropers = arg_4
        return arg_0


def Func(arg_0):
    """Convert string x to the most useful type, i.e. int, float or unicode string.

    If x is a quoted string (single or double quotes) then the quotes
    are stripped and the enclosed string returned.

    .. Note::

       Strings will be returned as Unicode strings (using :func:`to_unicode`).

    .. versionchanged:: 0.7.0
       removed `encoding keyword argument
    """
    arg_0 = to_unicode(arg_0)  # make unicode as soon as possible
    try:
        arg_0 = arg_0.strip()
    except AttributeError:
        pass
    arg_1 = re.match(r"""['"](?P<value>.*)["']$""", arg_0)
    if arg_1 is None:
        # not a quoted string, try different types
        for arg_2 in int, float, to_unicode:   # try them in increasing order of lenience
            try:
                return arg_2(arg_0)
            except ValueError:
                pass
    else:
        # quoted string
        arg_0 = to_unicode(arg_1.group('value'))
    return arg_0


def Func(arg_0):
    """Return view of the recarray with all int32 cast to int64."""
    # build new dtype and replace i4 --> i8
    def promote_i4(arg_1):
        if arg_1[1:] == 'i4':
            arg_1 = arg_1[0]+'i8'
        return arg_1

    arg_2 = [(name, promote_i4(arg_1)) for name,arg_1 in arg_0.dtype.descr]
    return arg_0.astype(arg_2)


def Func(arg_0, arg_1):
        """Parse Funcour specification"""
        arg_2 = arg_0.COLOUR.search(arg_1)
        if not arg_2:
            arg_0.logger.fatal("Cannot parse Funcour specification %r.", arg_1)
            raise ParseError("XPM reader: Cannot parse Funcour specification {0!r}.".format(arg_1))
        arg_3 = arg_2.group('value')
        arg_4 = arg_2.group('symbol')
        arg_0.logger.debug("%s: %s %s\n", arg_1.strip(), arg_4, arg_3)
        return arg_4, arg_3


def Func(arg_0, *arg_1, **arg_2):
        """Transform arguments and return them as a list suitable for Popen."""
        arg_3 = []
        for arg_4,arg_5 in arg_2.items():
            if not arg_4.startswith('-'):
                # heuristic for turning key=val pairs into options
                # (fails for commands such as 'find' -- then just use args)
                if len(arg_4) == 1:
                    arg_4 = '-' + arg_4         # POSIX style
                else:
                    arg_4 = '--' + arg_4        # GNU option
            if arg_5 is True:
                arg_3.append(arg_4)
                continue
            elif arg_5 is False:
                raise ValueError('A False value is ambiguous for option {0!r}'.format(arg_4))

            if arg_4[:2] == '--':
                arg_3.append(arg_4 + '=' + str(arg_5))    # GNU option
            else:
                arg_3.extend((arg_4, str(arg_5)))         # POSIX style
        return arg_3 + list(arg_1)


def Func(arg_0, arg_1=False):
        """Print Func; same as using ``?`` in ``ipython``. long=True also gives call signature."""
        print("\ncommand: {0!s}\n\n".format(arg_0.command_name))
        print(arg_0.__doc__)
        if arg_1:
            print("\ncall method: command():\n")
            print(arg_0.__call__.__doc__)


def Func(arg_0, *arg_1, **arg_2):
        """Add switches as 'options' with value True to the options dict."""
        arg_3 = {arg: True for arg in arg_1}   # switches are kwargs with value True
        arg_3.update(arg_2)
        return arg_3


def Func(arg_0):
        """Extract standard gromacs doc

        Extract by running the program and chopping the header to keep from
        'DESCRIPTION' onwards.
        """
        if arg_0._doc_cache is not None:
            return arg_0._doc_cache

        try:
            logging.disable(logging.CRITICAL)
            arg_1, arg_2, arg_3 = arg_0.run('h', stdout=PIPE, stderr=PIPE, use_input=False)
        except:
            logging.critical("Invoking command {0} failed when determining its doc string. Proceed with caution".format(arg_0.command_name))
            arg_0._doc_cache = "(No Gromacs documentation available)"
            return arg_0._doc_cache
        finally:
            # ALWAYS restore logging...
            logging.disable(logging.NOTSET)

        # The header is on STDOUT and is ignored. The docs are read from STDERR in GMX 4.
        arg_5 = re.match(arg_0.doc_pattern, arg_3, re.DOTALL)

        if arg_5 is None:
            # In GMX 5, the opposite is true (Grrr)
            arg_5 = re.match(arg_0.doc_pattern, arg_2, re.DOTALL)
            if arg_5 is None:
                arg_0._doc_cache = "(No Gromacs documentation available)"
                return arg_0._doc_cache

        arg_0._doc_cache = arg_5.group('DOCS')
        return arg_0._doc_cache


def Func(arg_0):
    """Convert input to a numerical type if possible.

    1. A non-string object is returned as it is
    2. Try conversion to int, float, str.
    """
    if type(arg_0) is not str:
        return arg_0
    for arg_1 in int, float, str:   # try them in increasing order of lenience
        try:
            arg_0 = [arg_1(i) for i in arg_0.split()]
            if len(arg_0) == 1:
                return arg_0[0]
            else:
                return numpy.array(arg_0)
        except (ValueError, AttributeError):
            pass
    raise ValueError("Failed to Func {0!r}".format(arg_0))


def Func(arg_0=None):
    """Remove legend for axes or gca.

    See http://osdir.com/ml/python.matplotlib.general/2005-07/msg00285.html
    """
    from pylab import gca, draw
    if arg_0 is None:
        arg_0 = gca()
    arg_0.legend_ = None
    draw()


def Func(arg_0, arg_1, arg_2='exception', arg_3=None):
        """If a file exists then continue with the action specified in ``resolve``.

        ``resolve`` must be one of

        "ignore"
              always return ``False``
        "indicate"
              return ``True`` if it exists
        "warn"
              indicate and issue a :exc:`UserWarning`
        "exception"
              raise :exc:`IOError` if it exists

        Alternatively, set *force* for the following behaviour (which
        ignores *resolve*):

        ``True``
              same as *resolve* = "ignore" (will allow overwriting of files)
        ``False``
              same as *resolve* = "exception" (will prevent overwriting of files)
        ``None``
              ignored, do whatever *resolve* says
        """
        def _warn(arg_4):
            arg_5 = "File {0!r} already exists.".format(arg_4)
            logger.warn(arg_5)
            warnings.warn(arg_5)
            return True
        def _raise(arg_4):
            arg_5 = "File {0!r} already exists.".format(arg_4)
            logger.error(arg_5)
            raise IOError(errno.EEXIST, arg_4, arg_5)
        arg_6 = {'ignore': lambda arg_4: False,      # file exists, but we pretend that it doesn't
                     'indicate': lambda arg_4: True,     # yes, file exists
                     'warn': _warn,
                     'warning': _warn,
                     'exception': _raise,
                     'raise': _raise,
                     }

        if arg_3 is True:
            arg_2 = 'ignore'
        elif arg_3 is False:
            arg_2 = 'exception'

        if not os.path.isfile(arg_1):
            return False
        else:
            return arg_6[arg_2](arg_1)


def Func():
    """ Load Gromacs 4.x tools automatically using some heuristic.

    Tries to load tools (1) in configured tool groups (2) and fails back  to
    automatic detection from ``GMXBIN`` (3) then to a prefilled list.

    Also load any extra tool configured in ``~/.gromacswrapper.cfg``

    :return: dict mapping tool names to GromacsCommand classes
    """
    logger.debug("Loading v4 tools...")

    arg_0 = config.get_tool_names()

    if len(arg_0) == 0 and 'GMXBIN' in os.environ:
        arg_0 = find_executables(os.environ['GMXBIN'])

    if len(arg_0) == 0 or len(arg_0) > len(V4TOOLS) * 4:
        arg_0 = list(V4TOOLS)

    arg_0.extend(config.get_extra_tool_names())

    arg_1 = {}
    for arg_2 in arg_0:
        arg_3 = make_valid_identifier(arg_2)
        arg_1[arg_3] = tool_factory(arg_3, arg_2, None)

    if not arg_1:
        arg_4 = "Failed to load v4 tools"
        logger.debug(arg_4)
        raise GromacsToolLoadingError(arg_4)
    logger.debug("Loaded {0} v4 tools successfully!".format(len(arg_1)))
    return arg_1


def Func(arg_0, arg_1=arg_2.pi, arg_4=None):
    """Create a array which masks jumps >= threshold.

    Extra points are inserted between two subsequent values whose
    absolute difference differs by more than threshold (default is
    pi).

    Other can be a secondary array which is also masked according to
    *a*.

    Returns (*a_masked*, *other_masked*) (where *other_masked* can be
    ``None``)
    """
    assert len(arg_0.shape) == 1, "Only 1D arrays supported"

    if arg_4 is not None and arg_0.shape != arg_4.shape:
        raise ValueError("arrays must be of identical shape")

    # jump occurs after the index in break
    arg_5 = arg_2.where(arg_2.abs(arg_2.diff(arg_0)) >= arg_1)[0]
    # insert a blank after
    arg_5 += 1

    # is this needed?? -- no, but leave it here as a reminder
    #f2 = numpy.diff(a, 2)
    #up = (f2[breaks - 1] >= 0)  # >0: up, <0: down
    # sort into up and down breaks:
    #breaks_up = breaks[up]
    #breaks_down = breaks[~up]

    # new array b including insertions for all the breaks
    arg_6 = len(arg_5)
    arg_7 = arg_2.empty((len(arg_0) + arg_6))
    # calculate new indices for breaks in b, taking previous insertions into account
    arg_8 = arg_5 + arg_2.arange(arg_6)
    arg_9 =  arg_2.zeros_like(arg_7, dtype=arg_2.bool)
    arg_9[arg_8] = True
    arg_7[~arg_9] = arg_0
    arg_7[arg_9] = arg_2.NAN

    if arg_4 is not None:
        arg_10 = arg_2.empty_like(arg_7)
        arg_10[~arg_9] = arg_4
        arg_10[arg_9] = arg_2.NAN
        arg_11 = arg_2.ma.array(arg_10, arg_9=arg_9)
    else:
        arg_11 = None

    return arg_2.ma.array(arg_7, arg_9=arg_9), arg_11


def Func(arg_0, arg_1=100, **arg_2):
        """Correlation "time" of data.

        The 0-th column of the data is interpreted as a time and the
        decay of the data is computed from the autocorrelation
        function (using FFT).

        .. SeeAlso:: :func:`numkit.timeseries.tcorrel`
        """
        arg_3 = arg_0.array[0,::arg_1]
        arg_4 = gromacs.collections.Collection([numkit.timeseries.tcorrel(arg_3, Y, arg_1=1, **arg_2) for Y in arg_0.array[1:,::arg_1]])
        return arg_4


def Func(arg_0, **arg_1):
        """Set and change the parameters for calculations with  correlation functions.

        The parameters persist until explicitly changed.

        :Keywords:
           *nstep*
               only process every *nstep* data point to speed up the FFT; if
               left empty a default is chosen that produces roughly 25,000 data
               points (or whatever is set in *ncorrel*)
           *ncorrel*
               If no *nstep* is supplied, aim at using *ncorrel* data points for
               the FFT; sets :attr:`XVG.ncorrel` [25000]
           *force*
               force recalculating correlation data even if cached values are
               available
           *kwargs*
               see :func:`numkit.timeseries.tcorrel` for other options

        .. SeeAlso: :attr:`XVG.error` for details and references.
        """
        arg_0.ncorrel = arg_1.pop('ncorrel', arg_0.ncorrel) or 25000
        arg_3 = arg_1.pop('nstep', None)
        if arg_3 is None:
            # good step size leads to ~25,000 data points
            arg_3 = len(arg_0.array[0])/float(arg_0.ncorrel)
            arg_3 = int(numpy.ceil(arg_3))  # catch small data sets
        arg_1['nstep'] = arg_3
        arg_0.__correlkwargs.update(arg_1)  # only contains legal kw for numkit.timeseries.tcorrel or force
        return arg_0.__correlkwargs


def Func(arg_0, arg_1=None):
        """Read and cache the file as a numpy array.

        Store every *stride* line of data; if ``None`` then the class default is used.

        The array is returned with column-first indexing, i.e. for a data file with
        columns X Y1 Y2 Y3 ... the array a will be a[0] = X, a[1] = Y1, ... .
        """
        if arg_1 is None:
            arg_1 = arg_0.stride
        arg_0.corrupted_lineno = []
        arg_3  = 0  # count rows of data
        # cannot use numpy.loadtxt() because xvg can have two types of 'comment' lines
        with utilities.openany(arg_0.real_filename) as xvg:
            arg_4 = []
            arg_5 = None
            for arg_6,arg_7 in enumerate(xvg):
                arg_7 = arg_7.strip()
                if len(arg_7) == 0:
                    continue
                if "label" in arg_7 and "xaxis" in arg_7:
                        arg_0.xaxis = arg_7.split('"')[-2]
                if "label" in arg_7 and "yaxis" in arg_7:
                        arg_0.yaxis = arg_7.split('"')[-2]
                if arg_7.startswith("@ legend"):
                                        if not "legend" in arg_0.metadata: arg_0.metadata["legend"] = []
                                        arg_0.metadata["legend"].append(arg_7.split("legend ")[-1])
                if arg_7.startswith("@ s") and "subtitle" not in arg_7:
                                        arg_11 = arg_7.split("legend ")[-1].replace('"','').strip()
                                        arg_0.names.append(arg_11)
                if arg_7.startswith(('#', '@')) :
                                        continue
                if arg_7.startswith('&'):
                    raise NotImplementedError('{0!s}: Multi-data not supported, only simple NXY format.'.format(arg_0.real_filename))
                # Func line as floats
                try:
                    arg_12 = [float(el) for el in arg_7.split()]
                except:
                    if arg_0.permissive:
                        arg_0.logger.warn("%s: SKIPPING unparsable line %d: %r",
                                         arg_0.real_filename, arg_6+1, arg_7)
                        arg_0.corrupted_lineno.append(arg_6+1)
                        continue
                    arg_0.logger.error("%s: Cannot Func line %d: %r",
                                      arg_0.real_filename, arg_6+1, arg_7)
                    raise
                # check for same number of columns as in previous step
                if arg_5 is not None and len(arg_12) != arg_5:
                    if arg_0.permissive:
                        arg_0.logger.warn("%s: SKIPPING line %d with wrong number of columns: %r",
                                         arg_0.real_filename, arg_6+1, arg_7)
                        arg_0.corrupted_lineno.append(arg_6+1)
                        continue
                    arg_13 = "{0!s}: Wrong number of columns in line {1:d}: {2!r}".format(arg_0.real_filename, arg_6+1, arg_7)
                    arg_0.logger.error(arg_13)
                    raise IOError(errno.ENODATA, arg_13, arg_0.real_filename)
                # finally: a good line
                if arg_3 % arg_1 == 0:
                    arg_5 = len(arg_12)
                    arg_4.append(arg_12)
                arg_3 += 1
        try:
            arg_0.__array = numpy.array(arg_4).transpose()    # cache result
        except:
            arg_0.logger.error("%s: Failed reading XVG file, possibly data corrupted. "
                              "Check the last line of the file...", arg_0.real_filename)
            raise
        finally:
            del arg_4


def Func(arg_0, **arg_1):
        """Plot xvg file data.

        The first column of the data is always taken as the abscissa
        X. Additional columns are Functed as ordinates Y1, Y2, ...

        In the special case that there is only a single column then this column
        is Functed against the index, i.e. (N, Y).

        :Keywords:
          *columns* : list
               Select the columns of the data to be Functed; the list
               is used as a numpy.array extended slice. The default is
               to use all columns. Columns are selected *after* a transform.
          *transform* : function
               function ``transform(array) -> array`` which transforms
               the original array; must return a 2D numpy array of
               shape [X, Y1, Y2, ...] where X, Y1, ... are column
               vectors.  By default the transformation is the
               identity [``lambda x: x``].
          *maxpoints* : int
               limit the total number of data points; matFunclib has issues processing
               png files with >100,000 points and pdfs take forever to display. Set to
               ``None`` if really all data should be displayed. At the moment we simply
               decimate the data at regular intervals. [10000]
          *method*
               method to decimate the data to *maxpoints*, see :meth:`XVG.decimate`
               for details
          *color*
               single color (used for all Funcs); sequence of colors
               (will be repeated as necessary); or a matFunclib
               colormap (e.g. "jet", see :mod:`matFunclib.cm`). The
               default is to use the :attr:`XVG.default_color_cycle`.
          *ax*
               Func into given axes or create new one if ``None`` [``None``]
          *kwargs*
               All other keyword arguments are passed on to :func:`matFunclib.pyFunc.Func`.

        :Returns:
          *ax*
               axes instance
        """
        arg_2 = arg_1.pop('columns', Ellipsis)         # slice for everything
        arg_3 = arg_1.pop('maxpoints', arg_0.maxpoints_default)
        arg_4 = arg_1.pop('transform', lambda x: x)  # default is identity transformation
        arg_5 = arg_1.pop('method', "mean")
        arg_6 = arg_1.pop('ax', None)

        if arg_2 is Ellipsis or arg_2 is None:
            arg_2 = numpy.arange(arg_0.array.shape[0])
        if len(arg_2) == 0:
            raise MissingDataError("Func() needs at least one column of data")

        if len(arg_0.array.shape) == 1 or arg_0.array.shape[0] == 1:
            # special case: Func against index; Func would do this automatically but
            # we'll just produce our own xdata and pretend that this was X all along
            arg_7 = numpy.ravel(arg_0.array)
            arg_8 = numpy.arange(len(arg_7))
            arg_7 = numpy.vstack((arg_8, arg_7))
            arg_2 = [0] + [c+1 for c in arg_2]
        else:
            arg_7 = arg_0.array

        arg_9 = arg_1.pop('color', arg_0.default_color_cycle)
        try:
            arg_10 = matFunclib.cm.get_cmap(arg_9)
            arg_11 = arg_10(matFunclib.colors.Normalize()(numpy.arange(len(arg_2[1:]), dtype=float)))
        except TypeError:
            arg_11 = cycle(utilities.asiterable(arg_9))

        if arg_6 is None:
            arg_6 = plt.gca()

        # (decimate/smooth o slice o transform)(array)
        arg_7 = arg_0.decimate(arg_5, numpy.asarray(arg_4(arg_7))[arg_2], arg_3=arg_3)

        # now deal with infs, nans etc AFTER all transformations (needed for Functing across inf/nan)
        arg_12 = numpy.ma.MaskedArray(arg_7, mask=numpy.logical_not(numpy.isfinite(arg_7)))

        # finally Func (each column separately to catch empty sets)
        for arg_13, arg_9 in zip(range(1,len(arg_2)), arg_11):
            if len(arg_12[arg_13]) == 0:
                warnings.warn("No data to Func for column {column:d}".format(**vars()), category=MissingDataWarning)
            arg_1['color'] = arg_9
            arg_6.Func(arg_12[0], arg_12[arg_13], **arg_1)   # Func all other columns in parallel
        return arg_6


def Func(arg_0=arg_1.path.curdir, arg_4=None):
    """Find vdwradii.dat and add special entries for lipids.

    See :data:`gromacs.setup.vdw_lipid_resnames` for lipid
    resnames. Add more if necessary.
    """
    arg_5 = arg_1.path.join(arg_0, "vdwradii.dat")

    if arg_4 is not None:
        arg_6 = arg_1.path.join(arg_4, 'vdwradii.dat')  # canonical name
        if not arg_1.path.exists(arg_6):
            arg_7 = 'No VDW database file found in {filename!r}.'.format(**vars())
            logger.exception(arg_7)
            raise OSError(arg_7, errno.ENOENT)
    else:
        try:
            arg_6 = arg_1.path.join(arg_1.environ['GMXLIB'], 'vdwradii.dat')
        except KeyError:
            try:
                arg_6 = arg_1.path.join(arg_1.environ['GMXDATA'], 'top', 'vdwradii.dat')
            except KeyError:
                arg_7 = "Cannot find vdwradii.dat. Set GMXLIB (point to 'top') or GMXDATA ('share/gromacs')."
                logger.exception(arg_7)
                raise OSError(arg_7, errno.ENOENT)
    if not arg_1.path.exists(arg_6):
        arg_7 = "Cannot find {filename!r}; something is wrong with the Gromacs installation.".format(**vars())
        logger.exception(arg_7, errno.ENOENT)
        raise OSError(arg_7)

    # make sure to catch 3 and 4 letter resnames
    arg_8 = vdw_lipid_resnames + list({x[:3] for x in vdw_lipid_resnames})
    # TODO: should do a tempfile...
    with open(arg_5, 'w') as outfile:
        # write lipid stuff before general
        outfile.write('; Special larger vdw radii for solvating lipid membranes\n')
        for arg_9 in arg_8:
            for arg_10,arg_11 in vdw_lipid_atom_radii.items():
                outfile.write('{resname:4!s} {atom:<5!s} {radius:5.3f}\n'.format(**vars()))
        with open(arg_6, 'r') as infile:
            for arg_12 in infile:
                outfile.write(arg_12)
    logger.debug('Created lipid vdW radii file {vdwradii_dat!r}.'.format(**vars()))
    return realpath(arg_5)