From cad226617b8e5ef4e1c2808b391f0e9635179000 Mon Sep 17 00:00:00 2001 From: paugier Date: Tue, 5 Mar 2024 16:56:09 +0100 Subject: [PATCH] Fix and test run_from_xml --- src/fluidimage/run_from_xml.py | 157 ++++++++++++++++------------ src/fluidimage/test_run_from_xml.py | 57 +++++++--- 2 files changed, 134 insertions(+), 80 deletions(-) diff --git a/src/fluidimage/run_from_xml.py b/src/fluidimage/run_from_xml.py index bed2ed40..a7514260 100644 --- a/src/fluidimage/run_from_xml.py +++ b/src/fluidimage/run_from_xml.py @@ -14,6 +14,7 @@ import argparse import os +from abc import ABC, abstractmethod from time import time import numpy as np @@ -80,55 +81,67 @@ def tidy_uvmat_instructions(params): params._set_attrib("ind_start", ind_start) -class ActionBase: - def __init__(self, instructions, args): - self.instructions = instructions - - # create the serie of arrays - logger.info("Create the serie of arrays") - self.serie_arrays = SerieOfArraysFromFiles( - path=instructions.path_dir_input, - slicing_tuples=instructions.slicing_tuples, - ) - +class ActionBase(ABC): -class ActionAverage(ActionBase): - """Compute the average and save as a png file.""" + @abstractmethod + def __init__(self, instructions, args): + """Initialize the action class""" + @abstractmethod def compute(self): - instructions = self.instructions - serie = self.serie_arrays - # compute the average - logger.info("Compute the average") - a = serie.get_array_from_index(0) - mean = np.zeros_like(a, dtype=np.float32) - nb_fields = 0 - for a in serie.iter_arrays(): - mean += a - nb_fields += 1 - mean /= nb_fields - - strindices_first_file = serie.compute_strindices_from_indices( - *[indices[0] for indices in instructions.slicing_tuples] - ) - strindices_last_file = serie.compute_strindices_from_indices( - *[indices[1] - 1 for indices in instructions.slicing_tuples] - ) - - name_file = ( - serie.base_name - + serie.get_separator_base_index() - + strindices_first_file - + "-" - + strindices_last_file - + "." - + serie.extension_file - ) - - path_save = os.path.join(instructions.path_dir_output, name_file) - logger.info("Save in file:\n%s", path_save) - scipy.misc.imsave(path_save, mean) - return mean + """Perform the computation""" + + +# class ActionAverage(ActionBase): +# """Compute the average and save as a png file.""" + +# def __init__(self, instructions, args): +# self.instructions = instructions + +# # create the serie of arrays +# logger.info("Create the serie of arrays") +# self.serie_arrays = SerieOfArraysFromFiles( +# path=instructions.path_dir_input, +# slicing=instructions.slicing, +# ) + +# def compute(self): +# instructions = self.instructions +# serie = self.serie_arrays + +# slicing_tuples = serie.get_slicing_tuples() + +# # create output name +# strindices_first_file = serie.compute_str_indices_from_indices( +# *[indices[0] for indices in slicing_tuples] +# ) +# strindices_last_file = serie.compute_str_indices_from_indices( +# *[indices[1] - 1 for indices in slicing_tuples] +# ) +# name_file = ( +# serie.base_name +# + serie.get_separator_base_index() +# + strindices_first_file +# + "-" +# + strindices_last_file +# + "." +# + serie.extension_file +# ) +# path_save = os.path.join(instructions.path_dir_output, name_file) + +# # compute the average +# logger.info("Compute the average") +# a = serie.get_array_from_index(0) +# mean = np.zeros_like(a, dtype=np.float32) +# nb_fields = 0 +# for a in serie.iter_arrays(): +# mean += a +# nb_fields += 1 +# mean /= nb_fields + +# logger.info("Save in file:\n%s", path_save) +# scipy.misc.imsave(path_save, mean) +# return mean def params_piv_from_uvmat_xml(instructions, args): @@ -163,24 +176,25 @@ def params_piv_from_uvmat_xml(instructions, args): return params -class ActionPIV(ActionBase): +class ActionPIVFromUvmatXML(ActionBase): """Compute the average and save as a png file.""" def __init__(self, instructions, args): self.instructions = instructions self.params = params_piv_from_uvmat_xml(instructions, args) - logger.info("Initialize fluidimage computations with parameters:") + logger.info("Initialize Fluidimage computations with parameters:") logger.info(self.params._make_xml_text()) self.topology = TopologyPIV(self.params) def compute(self): t = time() - self.topology.compute(sequential=False) + self.topology.compute() t = time() - t - print(f"ellapsed time: {t}s") + print(f"elapsed time: {t} s") -actions_classes = {"aver_stat": ActionAverage, "civ_series": ActionPIV} +# actions_classes = {"aver_stat": ActionAverage, "civ_series": ActionPIVFromUvmatXML} +actions_classes = {"civ_series": ActionPIVFromUvmatXML} programs = ["uvmat", "fluidimage"] @@ -215,33 +229,29 @@ def main(): args = parse_args() path_instructions_xml = args.path - logger.info( - "\nFrom Python, start with instructions in xml file:\n%s", - path_instructions_xml, - ) params = ParamContainer(path_file=path_instructions_xml) program = None - try: params.Action.ActionName except AttributeError: - pass + try: + program = params._value_text["program"] + except (AttributeError, KeyError): + pass else: program = "uvmat" - try: - program = params._value_text["program"] - except (AttributeError, KeyError): - pass - if program not in programs: raise ValueError("Can not detect the program to launch.") - print(args) + logger.info( + "\nUsing instructions in xml file:\n%s", + path_instructions_xml, + ) - print(f"using input file from {program}") + kwargs_compute = {} if program == "uvmat": tidy_uvmat_instructions(params) @@ -264,7 +274,24 @@ def main(): modif_fluidimage_params(params, args) action = cls(params) - return action.compute() + try: + compute_args = params.compute_args + except AttributeError: + pass + else: + for key in ( + "executor", + "nb_max_workers", + "sleep_time", + "sequential", + "stop_if_error", + ): + try: + kwargs_compute[key] = compute_args[key] + except (KeyError, AttributeError): + pass + + return action.compute(**kwargs_compute) if __name__ == "__main__": diff --git a/src/fluidimage/test_run_from_xml.py b/src/fluidimage/test_run_from_xml.py index 5d9fdbdc..a475b859 100644 --- a/src/fluidimage/test_run_from_xml.py +++ b/src/fluidimage/test_run_from_xml.py @@ -1,29 +1,56 @@ -import os +import shutil import sys import unittest from fluidimage import get_path_image_samples +from fluidimage.piv import TopologyPIV from fluidimage.run_from_xml import main path_image_samples = get_path_image_samples() -on_linux = sys.platform == "linux" +@unittest.skipIf(sys.platform != "linux", "Only supported on Linux") +def test_main(monkeypatch): -class TestRunFromXML(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.current_dir = os.getcwd() - os.chdir(path_image_samples) + monkeypatch.chdir(path_image_samples) - @classmethod - def tearDownClass(cls): - os.chdir(cls.current_dir) + path = path_image_samples / "Karman/Images.civ/0_XML/Karman_1-4.xml" + command = f"run {path} --mode recompute" - @unittest.skipIf(not on_linux, "Only supported on Linux") - def test_main(self): - path = path_image_samples / "Karman/Images.civ/0_XML/Karman_1-4.xml" - command = f"run {str(path)} --mode recompute" - sys.argv = command.split() + with monkeypatch.context() as ctx: + ctx.setattr(sys, "argv", command.split()) + main() + + +def test_piv_sequential(tmp_path, monkeypatch): + + path_dir_images = tmp_path / "Images" + path_dir_images.mkdir() + + for path_im in (path_image_samples / "Jet/Images").glob("*"): + shutil.copy(path_im, path_dir_images) + + params = TopologyPIV.create_default_params() + + params.series.path = str(path_dir_images) + + params.piv0.shape_crop_im0 = 128 + params.multipass.number = 2 + params.multipass.use_tps = False + + params.saving.how = "recompute" + params.saving.postfix = "test_piv_run_from_xml" + + params._set_child( + "compute_args", + attribs={"executor": "exec_async_sequential", "nb_max_workers": 1}, + ) + + path_params = path_dir_images.parent / "params.xml" + + params._save_as_xml(path_file=path_params) + assert path_params.exists() + with monkeypatch.context() as ctx: + ctx.setattr(sys, "argv", ["run", str(path_params)]) main()