diff --git a/bliss/controllers/lima/lima_base.py b/bliss/controllers/lima/lima_base.py index bdb4059978bcb2412e07bd3e99c954fb15e8adc6..b0b4e1995c405fdf815538dada9d616d7daf0c70 100644 --- a/bliss/controllers/lima/lima_base.py +++ b/bliss/controllers/lima/lima_base.py @@ -567,8 +567,14 @@ class Lima(CounterController, HasMetadataForScanExclusive): ) raise ValueError(msg) - def get_mapped_path(self, path): + def get_mapped_path(self, path, check_validity=False): + """ Return mapped path depending on camera configuration. + Without configured mapping it returns the path argument unmodified. + If check_validity is True, it checks if the mapped path exists + and returns the answer as an extra boolean flag. + """ path = os.path.normpath(path) + validity = True for mapping in reversed(self.directories_mapping): base_path = mapping["path"] replace_with = mapping["replace-with"] @@ -576,9 +582,14 @@ class Lima(CounterController, HasMetadataForScanExclusive): # characters, that may not form a valid directory path: hence # the use of a custom common_prefix function if common_prefix([path, base_path]) == base_path: - return os.path.join(replace_with, os.path.relpath(path, base_path)) + path = os.path.join(replace_with, os.path.relpath(path, base_path)) + validity = os.path.exists(replace_with) + break - return path + if check_validity: + return path, validity + else: + return path @autocomplete_property def proxy(self): diff --git a/bliss/scanning/acquisition/lima.py b/bliss/scanning/acquisition/lima.py index f0eeb9059505f6bd99a46680eaa29ff7cafb5d2e..540c2ed2cbc4e85fc1cef71074496b614695ac69 100644 --- a/bliss/scanning/acquisition/lima.py +++ b/bliss/scanning/acquisition/lima.py @@ -10,6 +10,7 @@ import gevent from gevent import event from gevent import lock import numpy +import os from collections import OrderedDict from bliss.scanning.chain import AcquisitionMaster @@ -240,11 +241,20 @@ class LimaAcquisitionMaster(AcquisitionMaster): "saving_mode", "AUTO_FRAME" ) assert self.acq_params["saving_mode"] != "NOSAVING" - self.acq_params["saving_directory"] = self._lima_controller.get_mapped_path( - directory + + # get saving directory and handle a possible mapping of the root path + # check_validity option returns True if the root exist or if there is no mapping + self.acq_params[ + "saving_directory" + ], validity = self._lima_controller.get_mapped_path( + directory, check_validity=True ) + if validity: # if path is valid, create directory (if it doesnt exist yet) + os.makedirs(self.acq_params["saving_directory"], exist_ok=True) + self._unmapped_path = directory self.acq_params.setdefault("saving_prefix", prefix) + else: self.acq_params["saving_mode"] = "NOSAVING" diff --git a/bliss/scanning/writer/file.py b/bliss/scanning/writer/file.py index 0dbfcc2ce66b9fea330d24432df0a7f22b28dcd0..ce6cb20849fc28c880c7dd1c88eb2837c31f0931 100644 --- a/bliss/scanning/writer/file.py +++ b/bliss/scanning/writer/file.py @@ -98,13 +98,7 @@ class FileWriter: ) def create_path(self, full_path): - try: - os.makedirs(full_path) - except OSError as exc: # Python >2.5 - if exc.errno == errno.EEXIST and os.path.isdir(full_path): - pass - else: - raise + os.makedirs(full_path, exist_ok=True) def new_file(self, scan_name, scan_info): """Create a new scan file @@ -131,7 +125,6 @@ class FileWriter: if any_image and self._save_images: directory = os.path.dirname(images_path) prefix = os.path.basename(images_path) - self.create_path(directory) device.set_image_saving(directory, prefix) else: device.set_image_saving(None, None, force_no_saving=True) diff --git a/tests/controllers_sw/test_lima_simulator.py b/tests/controllers_sw/test_lima_simulator.py index 5e1fd9d9269f8055100b76890a386cc8a2f31534..02abc37c60a8f53b0fd9e5de31ee70cca9be80a6 100755 --- a/tests/controllers_sw/test_lima_simulator.py +++ b/tests/controllers_sw/test_lima_simulator.py @@ -13,6 +13,7 @@ import pytest import gevent import logging import numpy +import shutil from unittest import mock import bliss.common.plot as plot_module @@ -849,7 +850,7 @@ def test_lima_geometry_and_arc_roi_bounding_box( def test_directories_mapping(beacon, lima_simulator): simulator = beacon.get("lima_simulator") - assert simulator.directories_mapping_names == ["identity", "fancy"] + assert simulator.directories_mapping_names == ["identity", "fancy", "windows"] assert simulator.current_directories_mapping == "identity" assert simulator.get_mapped_path("/tmp/scans/bla") == "/tmp/scans/bla" @@ -881,7 +882,20 @@ def test_lima_mapping_and_saving(session, lima_simulator): saving_directory = None try: - simulator.select_directories_mapping("fancy") + simulator.select_directories_mapping( + "fancy" + ) # selects a linux compatible mapping + replace_root_dir() + # ensure the mapped root path exist (i.e. directories_mapping => 'replace-with' folder musst pre-exist) + mapped_root = simulator.directories_mapping[0]["replace-with"] + os.makedirs(mapped_root, exist_ok=True) + mapped_directory = simulator.get_mapped_path(scan_saving.get_path()) + ct_scan = sct(0.1, simulator, save=True, run=True) + shutil.rmtree(mapped_root) # clean and remove the mapped_directory + + simulator.select_directories_mapping( + "windows" + ) # selects a windows compatible mapping replace_root_dir() mapped_directory = simulator.get_mapped_path(scan_saving.get_path()) ct_scan = sct(0.1, simulator, save=True, run=False) @@ -889,7 +903,7 @@ def test_lima_mapping_and_saving(session, lima_simulator): try: ct_scan.run() except Exception as e: - # this will fail because directory is not likely to exist + # this will fail because the mapped_root ('Z:\\') does not exist (and cannot be created within a Linux test env) saving_directory = e.args[0].desc.split("Directory :")[-1].split()[0] finally: scan_saving.from_dict(scan_saving_dump) diff --git a/tests/test_configuration/lima.yml b/tests/test_configuration/lima.yml index fb3b558589e19860394bfac5c5dd66bae6515c65..d1943f5cb3d0187e60dfa838f871262274e0e2e8 100644 --- a/tests/test_configuration/lima.yml +++ b/tests/test_configuration/lima.yml @@ -9,7 +9,8 @@ fancy: - path: /tmp/scans replace-with: /tmp/fancy - - path: /tmp/scans/test + windows: + - path: /tmp/scans replace-with: Z:\ saving: mode: ONE_FILE_PER_FRAME