def _getSmartIndenter(indenterName, qpart, indenter):
    """Get indenter by name.
    Available indenters are none, normal, cstyle, haskell, lilypond, lisp, python, ruby, xml
    Indenter name is not case sensitive
    Raise KeyError if not found
    indentText is indentation, which shall be used. i.e. '\t' for tabs, '    ' for 4 space symbols
    """
    indenterName = indenterName.lower()

    if indenterName in ('haskell', 'lilypond'):  # not supported yet
        logger.warning('Smart indentation for %s not supported yet. But you could be a hero who implemented it' % indenterName)
        from qutepart.indenter.base import IndentAlgNormal as indenterClass
    elif 'none' == indenterName:
        from qutepart.indenter.base import IndentAlgBase as indenterClass
    elif 'normal' == indenterName:
        from qutepart.indenter.base import IndentAlgNormal as indenterClass
    elif 'cstyle' == indenterName:
        from qutepart.indenter.cstyle import IndentAlgCStyle as indenterClass
    elif 'python' == indenterName:
        from qutepart.indenter.python import IndentAlgPython as indenterClass
    elif 'ruby' == indenterName:
        from qutepart.indenter.ruby import IndentAlgRuby as indenterClass
    elif 'xml' == indenterName:
        from qutepart.indenter.xmlindent import IndentAlgXml as indenterClass
    elif 'haskell' == indenterName:
        from qutepart.indenter.haskell import IndenterHaskell as indenterClass
    elif 'lilypond' == indenterName:
        from qutepart.indenter.lilypond import IndenterLilypond as indenterClass
    elif 'lisp' == indenterName:
        from qutepart.indenter.lisp import IndentAlgLisp as indenterClass
    elif 'scheme' == indenterName:
        from qutepart.indenter.scheme import IndentAlgScheme as indenterClass
    else:
        raise KeyError("Indenter %s not found" % indenterName)

    return indenterClass(qpart, indenter)
def _subset_sounding_data(
        example_dict, netcdf_dataset_object, example_indices_to_keep,
        field_names_to_keep, heights_to_keep_m_agl):
    """Subsets sounding data by field and height.

    :param example_dict: See doc for `_subset_radar_data`.
    :param netcdf_dataset_object: Same.
    :param example_indices_to_keep: Same.
    :param field_names_to_keep: 1-D list of field names to keep.  If None, will
        keep all fields.
    :param heights_to_keep_m_agl: 1-D numpy array of heights to keep.  If None,
        will keep all heights.
    :return: example_dict: Same as input but with the following exceptions.

    [1] Keys "sounding_field_names" and "sounding_heights_m_agl" may have
        different values.
    [2] Key "sounding_matrix" has been added.
    """

    if field_names_to_keep is None:
        field_names_to_keep = copy.deepcopy(example_dict[SOUNDING_FIELDS_KEY])
    if heights_to_keep_m_agl is None:
        heights_to_keep_m_agl = example_dict[SOUNDING_HEIGHTS_KEY] + 0

    error_checking.assert_is_numpy_array(
        numpy.array(field_names_to_keep), num_dimensions=1
    )

    heights_to_keep_m_agl = numpy.round(heights_to_keep_m_agl).astype(int)
    error_checking.assert_is_numpy_array(
        heights_to_keep_m_agl, num_dimensions=1)

    sounding_matrix = numpy.array(
        netcdf_dataset_object.variables[SOUNDING_MATRIX_KEY][
            example_indices_to_keep, ...
        ],
        dtype=float
    )

    # TODO(thunderhoser): This is a HACK.
    spfh_index = example_dict[SOUNDING_FIELDS_KEY].index(
        soundings.SPECIFIC_HUMIDITY_NAME)
    temp_index = example_dict[SOUNDING_FIELDS_KEY].index(
        soundings.TEMPERATURE_NAME)
    pressure_index = example_dict[SOUNDING_FIELDS_KEY].index(
        soundings.PRESSURE_NAME)
    theta_v_index = example_dict[SOUNDING_FIELDS_KEY].index(
        soundings.VIRTUAL_POTENTIAL_TEMPERATURE_NAME)

    sounding_matrix[..., spfh_index][
        numpy.isnan(sounding_matrix[..., spfh_index])
    ] = 0.

    nan_example_indices, nan_height_indices = numpy.where(numpy.isnan(
        sounding_matrix[..., theta_v_index]
    ))

    if len(nan_example_indices) > 0:
        this_temp_matrix_kelvins = sounding_matrix[..., temp_index][
            nan_example_indices, nan_height_indices]

        this_pressure_matrix_pa = sounding_matrix[..., pressure_index][
            nan_example_indices, nan_height_indices]

        this_thetav_matrix_kelvins = (
            temp_conversion.temperatures_to_potential_temperatures(
                temperatures_kelvins=this_temp_matrix_kelvins,
                total_pressures_pascals=this_pressure_matrix_pa)
        )

        sounding_matrix[..., theta_v_index][
            nan_example_indices, nan_height_indices
        ] = this_thetav_matrix_kelvins

    these_indices = numpy.array([
        example_dict[SOUNDING_FIELDS_KEY].index(f)
        for f in field_names_to_keep
    ], dtype=int)

    sounding_matrix = sounding_matrix[..., these_indices]

    these_indices = numpy.array([
        numpy.where(example_dict[SOUNDING_HEIGHTS_KEY] == h)[0][0]
        for h in heights_to_keep_m_agl
    ], dtype=int)

    sounding_matrix = sounding_matrix[..., these_indices, :]

    example_dict[SOUNDING_FIELDS_KEY] = field_names_to_keep
    example_dict[SOUNDING_HEIGHTS_KEY] = heights_to_keep_m_agl
    example_dict[SOUNDING_MATRIX_KEY] = sounding_matrix

    return example_dict