Exemple #1
0
def set_byte_map(class_list, raster, process, output):
    """
    reclassify a map using the provided class list
    
    Args: 
        class_list (list(list(int))): each list of the root list represent a byte value starting at 1. 
            each nested list is the value of the class that need to be included into each byte value.
        raster (pathlib.Path): the path to the original image
    """
    # check that the inputs are all separated
    if is_overlap(class_list):
        raise Exception(cm.bin.overlap)

    # output for the user
    output.add_live_msg(cm.bin.running)

    # get the final file name
    filename = Path(raster).stem
    bin_map = cp.get_result_dir(process).joinpath(f'{filename}_bin_map.tif')

    if bin_map.is_file():
        output.add_live_msg(cm.bin.file_exist.format(bin_map), 'warning')
        return bin_map

    # create the bin map using the values provided by the end user
    with rio.open(raster) as src:

        out_meta = src.meta.copy()
        out_meta.update(compress='lzw', dtype=np.uint8)
        raw_data = src.read()

        if class_list == []:
            data = raw_data
        else:
            data = np.zeros_like(raw_data, dtype=np.uint8)
            total_class = sum([len(c) for c in class_list])
            c = 0
            output.update_progress(0)
            for index, class_ in enumerate(class_list):

                bool_data = np.zeros_like(raw_data, dtype=np.bool_)
                for val in class_:
                    bool_data = bool_data + (raw_data == val)

                    # display the advancement
                    c += 1
                    output.update_progress(c / total_class)

                data_value = (bool_data * (index + 1)).astype(np.uint8)
                data = data + data_value

            data = data.astype(out_meta['dtype'])

        with rio.open(bin_map, 'w', **out_meta) as dst:
            dst.write(data)

    output.add_live_msg(cm.bin.finished, 'success')

    return bin_map
Exemple #2
0
def run_gwb_process(process, raster, params_list, title, output, offset):
    """
    run all the processes of the GWB suit according to the io
    The input and output folder will be created on the fly and deleted right afterward
    The result will be saved in the result_dir of the parameter component
    The log will be displayed to the end user and then removed

    Args:
        io (GWBIo): any io inheriting from the GWBIo object

    Return:
        (pathlib.Path) : the path to the final .image
        (pathlib.Path) : the path to the final .csv
    """

    # create the tmp directories
    tmp_dir = cp.get_tmp_dir()
    in_dir = tmp_dir / "input"
    in_dir.mkdir(exist_ok=True)
    out_dir = tmp_dir / "output"
    out_dir.mkdir(exist_ok=True)

    # fill the tmp dir with the raster
    shutil.copy(raster, in_dir)

    # create the input file
    parameter_file = in_dir / f"{process}-parameters.txt"
    with parameter_file.open("w") as f:
        star_line = ["*" * 76 + "\n"]
        offset_lines = ["\n" for i in range(offset - 2)]
        params_lines = [str(p) + "\n" for p in params_list]
        finish_lines = ["\n"]
        f.writelines(offset_lines + star_line + params_lines + star_line + finish_lines)

    # create the command
    command = [f"GWB_{process.upper()}", f"-i={in_dir}", f"-o={out_dir}"]

    # set the argument of the process
    kwargs = {
        "args": command,
        "cwd": Path.home(),  # launch from home to avoid permissions bugs
        "stdout": subprocess.PIPE,
        "stderr": subprocess.PIPE,
        "universal_newlines": True,
    }

    # start the process
    output.add_live_msg(cm.gwb.start.format(process.upper()))

    with subprocess.Popen(**kwargs) as p:
        for line in p.stdout:
            output.append_msg(line)

    # file in the output directory
    folder = cp.gwb[process]["folder"]
    out_log = list(out_dir.glob(f"*.log"))

    # if log is not there, the comutation didn't even started
    # I let the display in its current state and change the color of the output to red
    if len(out_log) == 0:
        output.type = "error"
        return []

    # read the log
    with open(out_log[0]) as f:
        log = f.read()
        output.add_live_msg(
            v.Html(tag="pre", class_="info--text d-inline", children=[log])
        )

    # if the log file is the only file then it has crashed
    try:
        if folder == "":
            out_files = [f for f in out_dir.glob("*.*") if not f.stem == ".log"]
        else:
            out_files = next(out_dir.glob(f"{raster.stem}_{folder}*/")).glob("*.*")
    except:
        output.add_live_msg(
            v.Html(tag="pre", class_="error--text d-inline", children=[log]), "error"
        )
        return []

    # copy the files in the result directory
    files = []
    for f in out_files:
        final_f = shutil.copy(f, cp.get_result_dir(process))
        files.append(Path(final_f))

    # display the final log
    output.add_live_msg(
        v.Html(tag="pre", class_="success--text d-inline", children=[log]), "success"
    )

    return files
Exemple #3
0
def run_gwb_process(process, raster, params_list, title, output, offset):
    """
    run all the processes of the GWB suit according to the io
    The input and output folder will be created on the fly and deleted right afterward
    The result will be saved in the result_dir of the parameter component
    The log will be displayed to the end user and then removed
    
    Args: 
        io (GWBIo): any io inheriting from the GWBIo object
        
    Return:
        (pathlib.Path) : the path to the final .image
        (pathlib.Path) : the path to the final .csv
    """
    
    # create the tmp directories 
    tmp_dir = cp.get_tmp_dir()
    in_dir = tmp_dir.joinpath('input')
    in_dir.mkdir()
    out_dir = tmp_dir.joinpath('output')
    out_dir.mkdir()
    
    # fill the tmp dir with the raster 
    shutil.copy(raster, in_dir)
    
    # create the input file
    parameter_file = in_dir.joinpath(f'{process}-parameters.txt')
    with parameter_file.open('w') as f:
        offset_lines = ['\n' for i in range(offset-1)]
        params_lines = [str(p) + '\n' for p in params_list]
        finish_lines = ['\n']
        f.writelines(offset_lines + params_lines +finish_lines)
            
    # create the command 
    command = [
        f'GWB_{process.upper()}',
        f'-i={in_dir}',
        f'-o={out_dir}'
    ]
    
    # set the argument of the process
    kwargs = {
        'args' : command,
        'cwd' : Path('~').expanduser(), # launch from home to avoid permissions bugs
        'stdout' : subprocess.PIPE,
        'stderr' : subprocess.PIPE,
        'universal_newlines' : True
    }
    
    # start the process 
    output.add_live_msg(cm.gwb.start.format(process.upper()))
    
    with subprocess.Popen(**kwargs) as p:
        for line in p.stdout:
            output.append_msg(line)
            
    # file in the output directory
    folder = cp.gwb[process]["folder"]
    if folder == '':
        out_log = list(out_dir.glob(f'*.log'))
        out_files = [f for f in out_dir.glob("*.*") if not f.stem == '.log']
    else:
        out_log = list(out_dir.glob(f'*.log'))
        out_files = next(out_dir.glob(f'{raster.stem}_{folder}*/')).glob('*.*') 
    
    
    # if log is not there, the comutation didn't even started 
    # I let the display in its current state and change the color of the output to red
    if len(out_log) == 0:
        output.type = 'error'
        return []
    
    # if the log file is the only file then it has crashed
    
    # read the log 
    with open(out_log[0]) as f:
        log = f.read()
        
    # copy the files in the result directory 
    files = []
    for f in out_files:
        final_f = shutil.copy(f, cp.get_result_dir(process))
        files.append(Path(final_f))
        
    # display the final log 
    output.add_live_msg(v.Html(tag='pre', class_='success--text d-inline', children=[log]), 'success')
    
    return files
        
    
    
Exemple #4
0
def set_byte_map(class_list, raster, band, process, output):
    """
    reclassify a map using the provided class list

    Args:
        class_list (list(list(int))): each list of the root list represent a byte value starting at 1.
            each nested list is the value of the class that need to be included into each byte value.
        raster (pathlib.Path): the path to the original image
    """
    # check that the inputs are all separated
    if is_overlap(class_list):
        raise Exception(cm.bin.overlap)

    # output for the user
    output.add_live_msg(cm.bin.running)

    # get the final file name
    filename = Path(raster).stem
    bin_map = cp.get_result_dir(process) / f"{filename}_bin_map.tif"

    if bin_map.is_file():
        output.add_live_msg(cm.bin.file_exist.format(bin_map), "warning")
        return bin_map

    # create the bin map using the values provided by the end user
    with rio.open(raster) as src:

        out_meta = src.meta.copy()
        out_meta.update(count=1,
                        compress="lzw",
                        dtype=np.uint8,
                        driver="GTiff")

        with rio.open(bin_map, "w", **out_meta) as dst:

            # loop on windows
            # I assume windows are the same on each band
            output.update_progress(0)
            nb_windows = sum(1 for _ in src.block_windows(1))
            for iw, block in enumerate(src.block_windows(1)):

                # get the raw data on the window
                window = block[1]
                raw_data = src.read(band, window=window)

                # reclassify data using the class_list
                data = np.zeros_like(raw_data, dtype=np.uint8)
                total_class = sum([len(c) for c in class_list])

                for ic, class_ in enumerate(class_list):

                    bool_data = np.isin(raw_data, class_)
                    data_value = (bool_data * (ic + 1)).astype(np.uint8)
                    data = data + data_value

                data = data.astype(out_meta["dtype"])
                dst.write(data, 1, window=window)
                output.update_progress((iw + 1) / nb_windows)

    output.add_live_msg(cm.bin.finished, "success")

    return bin_map