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
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
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
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