Exemple #1
0
def test_compute_dsm_with_roi_ventoux():
    """
    Dask compute dsm processing with input roi (cars_stereo)
    """
    # Force max RAM to 1000 to get stable tiling in tests
    os.environ['OTB_MAX_RAM_HINT'] = '1000'

    input_json = read_input_parameters(
        absolute_data_path("input/phr_ventoux/preproc_input.json"))

    with tempfile.TemporaryDirectory(dir=temporary_dir()) as directory:
        out_preproc = os.path.join(directory, "out_preproc")
        prepare.run(
            input_json,
            out_preproc,
            epi_step=30,
            region_size=250,
            disparity_margin=0.25,
            epipolar_error_upper_bound=43.,
            elevation_delta_lower_bound=-20.,
            elevation_delta_upper_bound=20.,
            mode="local_dask",  # Run on a local cluster
            nb_workers=4,
            walltime="00:10:00",
            check_inputs=True)

        preproc_json = os.path.join(out_preproc, "content.json")
        out_stereo = os.path.join(directory, "out_preproc")
        final_epsg = 32631
        resolution = 0.5

        roi = [5.194, 44.2059, 5.195, 44.2064]
        roi_epsg = 4326

        corr_config = corr_cfg.configure_correlator()

        compute_dsm.run(
            [read_preprocessing_content_file(preproc_json)],
            out_stereo,
            resolution=resolution,
            epsg=final_epsg,
            sigma=0.3,
            dsm_radius=3,
            dsm_no_data=-999,
            color_no_data=0,
            corr_config=corr_config,
            mode="local_dask",  # Run on a local cluster
            nb_workers=4,
            walltime="00:10:00",
            roi=(roi, roi_epsg))

        # Uncomment the 2 following instructions to update reference data
        #copy2(os.path.join(out_stereo, 'dsm.tif'),
        #      absolute_data_path("ref_output/dsm_end2end_ventoux_with_roi.tif"))
        #copy2(os.path.join(out_stereo, 'clr.tif'),
        #      absolute_data_path("ref_output/clr_end2end_ventoux_with_roi.tif"))

        assert_same_images(
            os.path.join(out_stereo, "dsm.tif"),
            absolute_data_path("ref_output/dsm_end2end_ventoux_with_roi.tif"),
            atol=0.0001,
            rtol=1e-6)
        assert_same_images(
            os.path.join(out_stereo, "clr.tif"),
            absolute_data_path("ref_output/clr_end2end_ventoux_with_roi.tif"),
            rtol=1.e-7,
            atol=1.e-7)

        # check final bounding box
        # create reference
        [roi_xmin, roi_ymin, roi_xmax, roi_ymax] = roi
        roi_poly = Polygon([(roi_xmin, roi_ymin), (roi_xmax, roi_ymin),
                            (roi_xmax, roi_ymax), (roi_xmin, roi_ymax),
                            (roi_xmin, roi_ymin)])

        project = pyproj.Transformer.from_proj(
            pyproj.Proj(init='epsg:{}'.format(roi_epsg)),
            pyproj.Proj(init='epsg:{}'.format(final_epsg)))
        ref_roi_poly = transform(project.transform, roi_poly)

        [ref_xmin, ref_ymin, ref_xmax, ref_ymax] = ref_roi_poly.bounds

        # retrieve bounding box of computed dsm
        data = rasterio.open(os.path.join(out_stereo, "dsm.tif"))
        xmin = min(data.bounds.left, data.bounds.right)
        ymin = min(data.bounds.bottom, data.bounds.top)
        xmax = max(data.bounds.left, data.bounds.right)
        ymax = max(data.bounds.bottom, data.bounds.top)

        assert math.floor(ref_xmin / resolution) * resolution == xmin
        assert math.ceil(ref_xmax / resolution) * resolution == xmax
        assert math.floor(ref_ymin / resolution) * resolution == ymin
        assert math.ceil(ref_ymax / resolution) * resolution == ymax
Exemple #2
0
def test_correct_right_grid():
    """
    Call right grid correction method and check outputs properties
    """
    matches_file = absolute_data_path(
        "input/preprocessing_input/matches_ventoux.npy")
    grid_file = absolute_data_path(
        "input/preprocessing_input/right_epipolar_grid_uncorrected_ventoux.tif")
    origin = [0, 0]
    spacing = [30, 30]

    matches = np.load(matches_file)
    matches = np.array(matches)

    matches_filtered = preprocessing.remove_epipolar_outliers(matches)

    with rio.open(grid_file) as rio_grid:
        grid = rio_grid.read()
        grid = np.transpose(grid, (1, 2, 0))

        corrected_grid, corrected_matches, in_stats, out_stats = \
            preprocessing.correct_right_grid(
                matches_filtered, grid, origin, spacing)

        # Uncomment to update ref
        # np.save(absolute_data_path("ref_output/corrected_right_grid.npy"),
        # corrected_grid)
        corrected_grid_ref = np.load(
            absolute_data_path("ref_output/corrected_right_grid.npy"))
        np.testing.assert_allclose(corrected_grid, corrected_grid_ref,
                                   atol=0.05, rtol=1.0e-6)

        assert corrected_grid.shape == grid.shape

        # Assert that we improved all stats
        assert abs(
            out_stats["mean_epipolar_error"][0]) < abs(
            in_stats["mean_epipolar_error"][0])
        assert abs(
            out_stats["mean_epipolar_error"][1]) < abs(
            in_stats["mean_epipolar_error"][1])
        assert abs(
            out_stats["median_epipolar_error"][0]) < abs(
            in_stats["median_epipolar_error"][0])
        assert abs(
            out_stats["median_epipolar_error"][1]) < abs(
            in_stats["median_epipolar_error"][1])
        assert out_stats["std_epipolar_error"][0] \
             < in_stats["std_epipolar_error"][0]
        assert out_stats["std_epipolar_error"][1] \
             < in_stats["std_epipolar_error"][1]
        assert out_stats["rms_epipolar_error"] \
             < in_stats["rms_epipolar_error"]
        assert out_stats["rmsd_epipolar_error"] \
             < in_stats["rmsd_epipolar_error"]

        # Assert absolute performances

        assert abs(out_stats["median_epipolar_error"][0]) < 0.1
        assert abs(out_stats["median_epipolar_error"][1]) < 0.1

        assert abs(out_stats["mean_epipolar_error"][0]) < 0.1
        assert abs(out_stats["mean_epipolar_error"][1]) < 0.1
        assert out_stats["rms_epipolar_error"] < 0.5

        # Assert corrected matches are corrected
        assert np.fabs(
            np.mean(corrected_matches[:, 1] - corrected_matches[:, 3])) < 0.1
Exemple #3
0
def test_end2end_ventoux_with_color():
    """
    End to end processing with p+xs fusion
    """
    # Force max RAM to 1000 to get stable tiling in tests
    os.environ['OTB_MAX_RAM_HINT'] = '1000'

    input_json = read_input_parameters(
        absolute_data_path(
            "input/phr_ventoux/preproc_input_with_pxs_fusion.json"))

    with tempfile.TemporaryDirectory(dir=temporary_dir()) as directory:
        out_preproc = os.path.join(directory, "out_preproc")
        prepare.run(
            input_json,
            out_preproc,
            epi_step=30,
            region_size=250,
            disparity_margin=0.25,
            epipolar_error_upper_bound=43.,
            elevation_delta_lower_bound=-20.,
            elevation_delta_upper_bound=20.,
            mode="local_dask",  # Run on a local cluster
            nb_workers=4,
            walltime="00:10:00",
            check_inputs=True)

        # Check preproc properties
        preproc_json = os.path.join(out_preproc, "content.json")
        assert os.path.isfile(preproc_json)

        with open(preproc_json, 'r') as f:
            preproc_data = json.load(f)
            assert preproc_data["preprocessing"]["output"][
                "epipolar_size_x"] == 612
            assert preproc_data["preprocessing"]["output"][
                "epipolar_size_y"] == 612
            assert - \
                20 < preproc_data["preprocessing"]["output"]["minimum_disparity"] < -18
            assert 14 < preproc_data["preprocessing"]["output"][
                "maximum_disparity"] < 15
            for img in [
                    "matches", "right_epipolar_grid", "left_epipolar_grid"
            ]:
                assert os.path.isfile(
                    os.path.join(out_preproc,
                                 preproc_data["preprocessing"]["output"][img]))

        out_stereo = os.path.join(directory, "out_preproc")

        corr_config = corr_cfg.configure_correlator()

        compute_dsm.run(
            [read_preprocessing_content_file(preproc_json)],
            out_stereo,
            resolution=0.5,
            epsg=32631,
            sigma=0.3,
            dsm_radius=3,
            dsm_no_data=-999,
            color_no_data=0,
            corr_config=corr_config,
            mode="local_dask",  # Run on a local cluster
            nb_workers=4,
            walltime="00:10:00",
            use_sec_disp=True)

        # Uncomment the following instruction to update reference data
        #copy2(os.path.join(out_stereo, 'dsm.tif'),
        #      absolute_data_path("ref_output/dsm_end2end_ventoux.tif"))
        #copy2(os.path.join(out_stereo, 'clr.tif'),
        #      absolute_data_path("ref_output/clr_end2end_ventoux_4bands.tif"))

        assert_same_images(
            os.path.join(out_stereo, "dsm.tif"),
            absolute_data_path("ref_output/dsm_end2end_ventoux.tif"),
            atol=0.0001,
            rtol=1e-6)
        assert_same_images(
            os.path.join(out_stereo, "clr.tif"),
            absolute_data_path("ref_output/clr_end2end_ventoux_4bands.tif"),
            rtol=1.e-7,
            atol=1.e-7)
Exemple #4
0
def test_end2end_paca_with_mask():
    """
    End to end processing
    """
    # Force max RAM to 1000 to get stable tiling in tests
    os.environ['OTB_MAX_RAM_HINT'] = '1000'

    input_json = read_input_parameters(
        absolute_data_path("input/phr_paca/preproc_input.json"))

    with tempfile.TemporaryDirectory(dir=temporary_dir()) as directory:
        out_preproc = os.path.join(directory, "out_preproc")
        prepare.run(
            input_json,
            out_preproc,
            epi_step=30,
            region_size=250,
            disparity_margin=0.25,
            epipolar_error_upper_bound=43.,
            elevation_delta_lower_bound=-20.,
            elevation_delta_upper_bound=20.,
            mode="local_dask",  # Run on a local cluster
            nb_workers=4,
            walltime="00:10:00",
            check_inputs=True)

        # Check preproc properties
        preproc_json = os.path.join(out_preproc, "content.json")

        out_stereo = os.path.join(directory, "out_stereo")

        corr_config = corr_cfg.configure_correlator()

        compute_dsm.run(
            [read_preprocessing_content_file(preproc_json)],
            out_stereo,
            resolution=0.5,
            epsg=32631,
            sigma=0.3,
            dsm_radius=3,
            dsm_no_data=-999,
            color_no_data=0,
            msk_no_data=65534,
            corr_config=corr_config,
            mode="local_dask",  # Run on a local cluster,
            output_stats=True,
            nb_workers=4,
            walltime="00:10:00",
            use_sec_disp=True)

        # Uncomment the 2 following instructions to update reference data
        # copy2(os.path.join(out_stereo, 'dsm.tif'),
        #      absolute_data_path("ref_output/dsm_end2end_paca.tif"))
        # copy2(os.path.join(out_stereo, 'clr.tif'),
        #       absolute_data_path("ref_output/clr_end2end_paca.tif"))
        # copy2(os.path.join(out_stereo, 'msk.tif'),
        #      absolute_data_path("ref_output/msk_end2end_paca.tif"))

        assert_same_images(os.path.join(out_stereo, "dsm.tif"),
                           absolute_data_path(
                               "ref_output/dsm_end2end_paca.tif"),
                           atol=0.0001, rtol=1e-6)
        assert_same_images(os.path.join(out_stereo, "clr.tif"),
                           absolute_data_path(
                               "ref_output/clr_end2end_paca.tif"),
                           rtol=1.e-7, atol=1.e-7)
        assert_same_images(os.path.join(out_stereo, "msk.tif"),
                           absolute_data_path(
                               "ref_output/msk_end2end_paca.tif"),
                           rtol=1.e-7, atol=1.e-7)

        # Test we have the same results with multiprocessing
        with tempfile.TemporaryDirectory(dir=temporary_dir()) as directory:
            out_preproc = os.path.join(directory, "out_preproc")
            prepare.run(
                input_json,
                out_preproc,
                epi_step=30,
                region_size=250,
                disparity_margin=0.25,
                epipolar_error_upper_bound=43.,
                elevation_delta_lower_bound=-20.,
                elevation_delta_upper_bound=20.,
                mode="local_dask",  # Run on a local cluster
                nb_workers=4,
                walltime="00:10:00",
                check_inputs=True)

            # Check preproc properties
            preproc_json = os.path.join(out_preproc, "content.json")

            out_stereo = os.path.join(directory, "out_stereo")

            corr_config = corr_cfg.configure_correlator()

            compute_dsm.run(
                [read_preprocessing_content_file(preproc_json)],
                out_stereo,
                resolution=0.5,
                epsg=32631,
                sigma=0.3,
                dsm_radius=3,
                dsm_no_data=-999,
                color_no_data=0,
                msk_no_data=65534,
                corr_config=corr_config,
                mode="mp",
                output_stats=True,
                nb_workers=4,
                walltime="00:10:00",
                use_sec_disp=True)

            # Uncomment the 2 following instructions to update reference data
            # copy2(os.path.join(out_stereo, 'dsm.tif'),
            #      absolute_data_path("ref_output/dsm_end2end_paca.tif"))
            # copy2(os.path.join(out_stereo, 'clr.tif'),
            #       absolute_data_path("ref_output/clr_end2end_paca.tif"))
            # copy2(os.path.join(out_stereo, 'msk.tif'),
            #      absolute_data_path("ref_output/msk_end2end_paca.tif"))

            assert_same_images(os.path.join(out_stereo, "dsm.tif"),
                               absolute_data_path(
                                   "ref_output/dsm_end2end_paca.tif"),
                               atol=0.0001, rtol=1e-6)
            assert_same_images(os.path.join(out_stereo, "clr.tif"),
                               absolute_data_path(
                                   "ref_output/clr_end2end_paca.tif"),
                               rtol=1.e-7, atol=1.e-7)
            assert_same_images(os.path.join(out_stereo, "msk.tif"),
                               absolute_data_path(
                                   "ref_output/msk_end2end_paca.tif"),
                               rtol=1.e-7, atol=1.e-7)
Exemple #5
0
def test_compute_dsm_with_snap_to_img1():
    """
    Dask compute dsm processing with input roi (cars_stereo)
    """
    # Force max RAM to 1000 to get stable tiling in tests
    os.environ['OTB_MAX_RAM_HINT'] = '1000'

    input_json = read_input_parameters(
        absolute_data_path("input/phr_ventoux/preproc_input.json"))


    with tempfile.TemporaryDirectory(dir=temporary_dir()) as directory:
        out_preproc = os.path.join(directory, "out_preproc")
        prepare.run(
            input_json,
            out_preproc,
            epi_step=30,
            region_size=250,
            disparity_margin=0.25,
            epipolar_error_upper_bound=43.,
            elevation_delta_lower_bound=-20.,
            elevation_delta_upper_bound=20.,
            mode="local_dask",  # Run on a local cluster
            nb_workers=4,
            walltime="00:10:00")

        # Check preproc properties
        preproc_json = os.path.join(out_preproc, "content.json")
        assert os.path.isfile(preproc_json)

        out_stereo = os.path.join(directory, "out_preproc")
        final_epsg = 32631
        resolution = 0.5
        corr_config = corr_cfg.configure_correlator()

        compute_dsm.run(
            [read_preprocessing_content_file(preproc_json)],
            out_stereo,
            resolution=resolution,
            epsg=final_epsg,
            sigma=0.3,
            dsm_radius=3,
            dsm_no_data=-999,
            color_no_data=0,
            corr_config=corr_config,
            mode="local_dask",  # Run on a local cluster
            nb_workers=4,
            walltime="00:10:00",
            snap_to_img1 = True)

        # Uncomment the 2 following instructions to update reference data
        #copy2(os.path.join(out_stereo, 'dsm.tif'),
        #      absolute_data_path(
        #      "ref_output/dsm_end2end_ventoux_with_snap_to_img1.tif"))
        #copy2(os.path.join(out_stereo, 'clr.tif'),
        #      absolute_data_path(
        #      "ref_output/clr_end2end_ventoux_with_snap_to_img1.tif"))

        assert_same_images(os.path.join(out_stereo, "dsm.tif"),
                           absolute_data_path(
                    "ref_output/dsm_end2end_ventoux_with_snap_to_img1.tif"),
                               atol=0.0001, rtol=1e-6)
        assert_same_images(os.path.join(out_stereo, "clr.tif"),
                           absolute_data_path(
                    "ref_output/clr_end2end_ventoux_with_snap_to_img1.tif"),
                    rtol=1.e-7, atol=1.e-7)
        assert os.path.exists(os.path.join(out_stereo, "msk.tif")) is False
Exemple #6
0
def test_compute_disparity_1_msk_ref(
                images_and_grids_conf): #pylint: disable=redefined-outer-name
    """
    Test compute_disparity on ventoux dataset with pandora
    """
    left_input = xr.open_dataset(
        absolute_data_path(
            "input/intermediate_results/data1_ref_left_masked.nc"))
    right_input = xr.open_dataset(
        absolute_data_path(
            "input/intermediate_results/data1_ref_right.nc"))
    # Pandora configuration
    corr_cfg = create_corr_conf()

    disp_min = -13
    disp_max = 14

    output = stereo.compute_disparity(left_input,
                                      right_input,
                                      images_and_grids_conf,
                                      corr_cfg,
                                      disp_min,
                                      disp_max,
                                      verbose=True)

    assert output[cst.STEREO_REF][cst.DISP_MAP].shape == (120, 110)
    assert output[cst.STEREO_REF][cst.DISP_MSK].shape == (120, 110)

    np.testing.assert_allclose(output[cst.STEREO_REF].attrs[cst.ROI],
                               np.array([420, 200, 530, 320]))

    # Uncomment to update baseline
    # output[cst.STEREO_REF].to_netcdf(absolute_data_path(
    # "ref_output/disp1_ref_pandora_msk_ref.nc"))
    # output[cst.STEREO_SEC].to_netcdf(absolute_data_path(
    # "ref_output/disp1_sec_pandora_msk_ref.nc"))

    ref = xr.open_dataset(
        absolute_data_path(
            "ref_output/disp1_ref_pandora_msk_ref.nc"))
    assert_same_datasets(output[cst.STEREO_REF],ref,atol=5.e-6)

    sec = xr.open_dataset(
        absolute_data_path(
            "ref_output/disp1_sec_pandora_msk_ref.nc"))
    assert_same_datasets(output[cst.STEREO_SEC], sec, atol=5.e-6)

    # test multi-classes left mask
    left_input[cst.EPI_MSK].values[10, 10] = 1 # valid class
    left_input[cst.EPI_MSK].values[10, 140] = 2 # nonvalid class
    conf = deepcopy(images_and_grids_conf)
    conf['input']['mask1_classes'] = absolute_data_path(
        "input/intermediate_results/data1_ref_left_mask_classes.json")

    output = stereo.compute_disparity(left_input,
                                      right_input,
                                      conf,
                                      corr_cfg,
                                      disp_min,
                                      disp_max,
                                      verbose=True)

    assert output[cst.STEREO_REF][cst.DISP_MAP].shape == (120, 110)
    assert output[cst.STEREO_REF][cst.DISP_MSK].shape == (120, 110)

    np.testing.assert_allclose(output[cst.STEREO_REF].attrs[cst.ROI],
                               np.array([420, 200, 530, 320]))

    assert_same_datasets(output[cst.STEREO_REF],ref,atol=5.e-6)
    assert_same_datasets(output[cst.STEREO_SEC], sec, atol=5.e-6)
Exemple #7
0
def test_prepare_args(prepare_default_args):
    parser = cars_cli_parser()

    with tempfile.TemporaryDirectory(dir=temporary_dir()) as directory:
        prepare_default_args.outdir = directory

        # test default args
        main_cli(prepare_default_args, parser, check_inputs=True)

        prepare_default_args.loglevel = 'info'
        main_cli(prepare_default_args, parser, check_inputs=True)

        # degraded cases injson
        args_bad_json = copy(prepare_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_json.injson = absolute_data_path(
                'input/cars_cli_input/test.json')
            main_cli(args_bad_json, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases disparity_margin
        args_bad_disp_margin = copy(prepare_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_disp_margin.disparity_margin = -1.0
            main_cli(args_bad_disp_margin, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_disp_margin.disparity_margin = 1.5
            main_cli(args_bad_disp_margin, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases elevation bounds
        args_bad_elev_delta_bounds = copy(prepare_default_args)
        args_bad_elev_delta_bounds.elevation_delta_lower_bound = 50
        args_bad_elev_delta_bounds.elevation_delta_upper_bound = -50
        with pytest.raises(SystemExit) as e:
            main_cli(args_bad_elev_delta_bounds, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases epi_step
        args_bad_epi_step = copy(prepare_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_epi_step.epi_step = 0
            main_cli(args_bad_epi_step, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases epipolar_error_upper_bound
        args_bad_epi_error_bound = copy(prepare_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_epi_error_bound.epipolar_error_upper_bound = -10
            main_cli(args_bad_epi_error_bound, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases log level
        args_bad_loglevel = copy(prepare_default_args)
        with pytest.raises(ValueError):
            args_bad_loglevel.loglevel = 'TEST'
            main_cli(args_bad_loglevel, parser, check_inputs=True)

        # degraded cases number of workers
        args_bad_nb_workers = copy(prepare_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_nb_workers.nb_workers = -1
            main_cli(args_bad_nb_workers, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases wall time
        args_bad_wall_time = copy(prepare_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_wall_time.walltime = '000:00:00'
            main_cli(args_bad_wall_time, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_wall_time.walltime = 'bb:bb:bb'
            main_cli(args_bad_wall_time, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1
Exemple #8
0
def test_dsm_compute_roi_arg(compute_dsm_default_args):
    parser = cars_cli_parser()

    with tempfile.TemporaryDirectory(dir=temporary_dir()) as directory:
        compute_dsm_default_args.outdir = directory

        # test with default args
        main_cli(compute_dsm_default_args, parser, check_inputs=True)

        # test with mp (multiprocessing)
        compute_dsm_default_args.mode = "mp"
        main_cli(compute_dsm_default_args, parser, check_inputs=True)
        compute_dsm_default_args.dask = "local_dask"

        # test [xmin, ymin, xmax, ymax] roi argument
        compute_dsm_default_args.roi = ['1.0', '2.0', '3.0', '4.0']
        main_cli(compute_dsm_default_args, parser, check_inputs=True)

        # test image roi argument
        compute_dsm_default_args.roi = [
            absolute_data_path('input/cars_cli_input/roi_image.tif')
        ]
        main_cli(compute_dsm_default_args, parser, check_inputs=True)

        # test vector roi argument
        compute_dsm_default_args.roi = [
            absolute_data_path('input/cars_cli_input/roi_vector.gpkg')
        ]
        main_cli(compute_dsm_default_args, parser, check_inputs=True)

        # degraded cases input jsons
        args_bad_jsons = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_jsons.injsons = [
                absolute_data_path('input/cars_cli_input/test.txt')
            ]
            main_cli(args_bad_jsons, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_jsons.injsons = []
            main_cli(args_bad_jsons, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases sigma
        args_bad_sigma = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_sigma.sigma = -10
            main_cli(args_bad_sigma, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases dsm radius
        args_bad_dsm_radius = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_dsm_radius.dsm_radius = -10
            main_cli(args_bad_dsm_radius, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases resolution
        args_bad_resolution = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_resolution.resolution = 0
            main_cli(args_bad_resolution, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        args_bad_resolution = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_resolution.resolution = -1
            main_cli(args_bad_resolution, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases epsg
        args_bad_epsg = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_epsg.epsg = -1
            main_cli(args_bad_epsg, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases input ROI
        args_bad_roi = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_roi.roi = [
                absolute_data_path('input/cars_cli_input/test.txt')
            ]
            main_cli(args_bad_roi, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_roi.roi = [
                absolute_data_path(
                    'input/phr_ventoux/preproc_output/content.json')
            ]
            main_cli(args_bad_roi, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_roi.roi = ['1.0', '2.0']
            main_cli(args_bad_roi, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_roi.roi = ['1.0', '2.0', '3.0', '4.0', '5.0']
            main_cli(args_bad_roi, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_roi.roi = ['1.0', '2.0', '3.0', 'b']
            main_cli(args_bad_roi, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        with pytest.raises(SystemExit) as e:
            args_bad_roi.roi = [
                absolute_data_path('input/phr_ventoux/left_image.tif')
            ]
            main_cli(args_bad_roi, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases correlator config file
        args_bad_correlator_conf = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_correlator_conf.corr_config = absolute_data_path(
                'input/cars_cli_input/test.txt')
            main_cli(args_bad_correlator_conf, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases elevation offsets
        args_bad_elevation_offsets = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_elevation_offsets.min_elevation_offset = 10
            args_bad_elevation_offsets.max_elevation_offset = -10
            main_cli(args_bad_elevation_offsets, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases log level
        args_bad_loglevel = copy(compute_dsm_default_args)
        with pytest.raises(ValueError):
            args_bad_loglevel.loglevel = 'TEST'
            main_cli(args_bad_loglevel, parser, check_inputs=True)

        # degraded cases number of workers
        args_bad_nb_workers = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_nb_workers.nb_workers = -1
            main_cli(args_bad_nb_workers, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1

        # degraded cases wall time
        args_bad_wall_time = copy(compute_dsm_default_args)
        with pytest.raises(SystemExit) as e:
            args_bad_wall_time.walltime = '000:00:00'
            main_cli(args_bad_wall_time, parser, check_inputs=True)
        assert e.type == SystemExit
        assert e.value.code == 1