def main(ctx):
    which = "where" if sys.platform == "win32" else "which"
    if envoy.run(which + " git").status_code != 0:
        click.secho("fatal: git not found in PATH", fg="red")
        sys.exit(1)
    ctx.obj = Hydrogen()
def _create_2d3d_examples_myrorss(
        azimuthal_shear_file_names, reflectivity_file_names,
        full_id_strings, storm_times_unix_sec, target_matrix,
        sounding_file_name=None, sounding_field_names=None):
    """Creates hybrid 2D-3D examples for one file time.

    Fields in 2-D images: low-level and mid-level azimuthal shear
    Field in 3-D images: reflectivity

    :param azimuthal_shear_file_names: length-2 list of paths to storm-centered
        azimuthal-shear images.  The first (second) file should be (low)
        mid-level azimuthal shear.  Files will be read by
        `storm_images.read_storm_images`.
    :param reflectivity_file_names: length-H list of paths to storm-centered
        reflectivity images, where H = number of reflectivity heights.  Files
        will be read by `storm_images.read_storm_images`.
    :param full_id_strings: See doc for `_create_2d_examples`.
    :param storm_times_unix_sec: Same.
    :param target_matrix: Same.
    :param sounding_file_name: Same.
    :param sounding_field_names: Same.
    :return: example_dict: Same.
    """

    orig_full_id_strings = copy.deepcopy(full_id_strings)
    orig_storm_times_unix_sec = storm_times_unix_sec + 0

    print('Reading data from: "{0:s}"...'.format(reflectivity_file_names[0]))
    this_radar_image_dict = storm_images.read_storm_images(
        netcdf_file_name=reflectivity_file_names[0],
        full_id_strings_to_keep=full_id_strings,
        valid_times_to_keep_unix_sec=storm_times_unix_sec)

    if this_radar_image_dict is None:
        return None

    if sounding_file_name is None:
        sounding_matrix = None
        sounding_field_names = None
        sounding_heights_m_agl = None
    else:
        sounding_dict, this_radar_image_dict = _read_soundings(
            sounding_file_name=sounding_file_name,
            sounding_field_names=sounding_field_names,
            radar_image_dict=this_radar_image_dict)

        if this_radar_image_dict is None:
            return None
        if len(this_radar_image_dict[storm_images.FULL_IDS_KEY]) == 0:
            return None

        sounding_matrix = sounding_dict[soundings.SOUNDING_MATRIX_KEY]
        sounding_field_names = sounding_dict[soundings.FIELD_NAMES_KEY]
        sounding_heights_m_agl = sounding_dict[soundings.HEIGHT_LEVELS_KEY]

    full_id_strings = this_radar_image_dict[storm_images.FULL_IDS_KEY]
    storm_times_unix_sec = this_radar_image_dict[storm_images.VALID_TIMES_KEY]

    these_indices = tracking_utils.find_storm_objects(
        all_id_strings=orig_full_id_strings,
        all_times_unix_sec=orig_storm_times_unix_sec,
        id_strings_to_keep=full_id_strings,
        times_to_keep_unix_sec=storm_times_unix_sec, allow_missing=False)

    target_matrix = target_matrix[these_indices, :]

    azimuthal_shear_field_names = [
        storm_images.image_file_name_to_field(f)
        for f in azimuthal_shear_file_names
    ]
    reflectivity_heights_m_agl = numpy.array([
        storm_images.image_file_name_to_height(f)
        for f in reflectivity_file_names
    ], dtype=int)

    num_reflectivity_heights = len(reflectivity_file_names)
    tuple_of_image_matrices = ()

    for j in range(num_reflectivity_heights):
        if j != 0:
            print('Reading data from: "{0:s}"...'.format(
                reflectivity_file_names[j]
            ))

            this_radar_image_dict = storm_images.read_storm_images(
                netcdf_file_name=reflectivity_file_names[j],
                full_id_strings_to_keep=full_id_strings,
                valid_times_to_keep_unix_sec=storm_times_unix_sec)

        this_matrix = numpy.expand_dims(
            this_radar_image_dict[storm_images.STORM_IMAGE_MATRIX_KEY], axis=-1
        )
        tuple_of_image_matrices += (this_matrix,)

    example_dict = {
        FULL_IDS_KEY: full_id_strings,
        STORM_TIMES_KEY: storm_times_unix_sec,
        RADAR_FIELDS_KEY: azimuthal_shear_field_names,
        RADAR_HEIGHTS_KEY: reflectivity_heights_m_agl,
        ROTATED_GRIDS_KEY:
            this_radar_image_dict[storm_images.ROTATED_GRIDS_KEY],
        ROTATED_GRID_SPACING_KEY:
            this_radar_image_dict[storm_images.ROTATED_GRID_SPACING_KEY],
        REFL_IMAGE_MATRIX_KEY: dl_utils.stack_radar_heights(
            tuple_of_image_matrices),
        TARGET_MATRIX_KEY: target_matrix
    }

    if sounding_file_name is not None:
        example_dict.update({
            SOUNDING_FIELDS_KEY: sounding_field_names,
            SOUNDING_HEIGHTS_KEY: sounding_heights_m_agl,
            SOUNDING_MATRIX_KEY: sounding_matrix
        })

    num_az_shear_fields = len(azimuthal_shear_file_names)
    tuple_of_image_matrices = ()

    for j in range(num_az_shear_fields):
        print('Reading data from: "{0:s}"...'.format(
            azimuthal_shear_file_names[j]
        ))

        this_radar_image_dict = storm_images.read_storm_images(
            netcdf_file_name=azimuthal_shear_file_names[j],
            full_id_strings_to_keep=full_id_strings,
            valid_times_to_keep_unix_sec=storm_times_unix_sec)

        tuple_of_image_matrices += (
            this_radar_image_dict[storm_images.STORM_IMAGE_MATRIX_KEY],
        )

    example_dict.update({
        AZ_SHEAR_IMAGE_MATRIX_KEY: dl_utils.stack_radar_fields(
            tuple_of_image_matrices)
    })

    return example_dict