Esempio n. 1
0
 def test_allowedvalues_correct(self):
     self.assertTrue(valid.valid_1d_array(array=self.data,
                                          allowed_values=1))
Esempio n. 2
0
def load_cdi_data(
    scan_number,
    setup,
    bin_during_loading=False,
    flatfield=None,
    hotpixels=None,
    background=None,
    normalize="skip",
    debugging=False,
    **kwargs,
):
    """
    Load forward CDI data and preprocess it.

    It applies beam stop correction and an optional photon threshold, normalization
    and binning.

    :param scan_number: the scan number to load
    :param setup: an instance of the class Setup
    :param bin_during_loading: True to bin the data during loading (faster)
    :param flatfield: the 2D flatfield array
    :param hotpixels: the 2D hotpixels array. 1 for a hotpixel, 0 for normal pixels.
    :param background: the 2D background array to subtract to the data
    :param normalize: 'skip' to skip, 'monitor'  to normalize by the default monitor,
     'sum_roi' to normalize by the integrated intensity in the region of interest
     defined by detector.sum_roi
    :param debugging:  set to True to see plots
    :param kwargs:
     - 'photon_threshold': float, photon threshold to apply before binning
     - 'frames_pattern': 1D array of int, of length data.shape[0]. If
       frames_pattern is 0 at index, the frame at data[index] will be skipped,
       if 1 the frame will added to the stack.

    :return:
     - the 3D data and mask arrays
     - frames_logical: array of initial length the number of measured frames.
       In case of padding the length changes. A frame whose index is set to 1 means
       that it is used, 0 means not used, -1 means padded (added) frame.
     - the monitor values used for the intensity normalization

    """
    valid.valid_item(bin_during_loading,
                     allowed_types=bool,
                     name="bin_during_loading")
    # check and load kwargs
    valid.valid_kwargs(
        kwargs=kwargs,
        allowed_kwargs={"photon_threshold", "frames_pattern"},
        name="kwargs",
    )
    photon_threshold = kwargs.get("photon_threshold", 0)
    valid.valid_item(
        photon_threshold,
        allowed_types=Real,
        min_included=0,
        name="photon_threshold",
    )
    frames_pattern = kwargs.get("frames_pattern")
    valid.valid_1d_array(frames_pattern,
                         allow_none=True,
                         allowed_values={0, 1},
                         name="frames_pattern")

    rawdata, rawmask, monitor, frames_logical = setup.loader.load_check_dataset(
        scan_number=scan_number,
        setup=setup,
        frames_pattern=frames_pattern,
        bin_during_loading=bin_during_loading,
        flatfield=flatfield,
        hotpixels=hotpixels,
        background=background,
        normalize=normalize,
        debugging=debugging,
    )

    #################################
    # apply the beamstop correction #
    #################################
    rawdata = beamstop_correction(data=rawdata,
                                  setup=setup,
                                  debugging=debugging)

    #####################################################
    # apply an optional photon threshold before binning #
    #####################################################
    if photon_threshold != 0:
        rawmask[rawdata < photon_threshold] = 1
        rawdata[rawdata < photon_threshold] = 0
        print("Applying photon threshold before binning: < ", photon_threshold)

    ####################################################################################
    # bin data and mask in the detector plane if not already done during loading       #
    # binning in the stacking dimension is done at the very end of the data processing #
    ####################################################################################
    if not bin_during_loading and ((setup.detector.binning[1] != 1) or
                                   (setup.detector.binning[2] != 1)):
        print(
            "Binning the data: detector vertical axis by",
            setup.detector.binning[1],
            ", detector horizontal axis by",
            setup.detector.binning[2],
        )
        rawdata = util.bin_data(
            rawdata,
            (1, setup.detector.binning[1], setup.detector.binning[2]),
            debugging=False,
        )
        rawmask = util.bin_data(
            rawmask,
            (1, setup.detector.binning[1], setup.detector.binning[2]),
            debugging=False,
        )
        rawmask[np.nonzero(rawmask)] = 1

    ################################################
    # pad the data to the shape defined by the ROI #
    ################################################
    rawdata, rawmask = util.pad_from_roi(
        arrays=(rawdata, rawmask),
        roi=setup.detector.roi,
        binning=setup.detector.binning[1:],
        pad_value=(0, 1),
    )

    return rawdata, rawmask, frames_logical, monitor
Esempio n. 3
0
 def test_allowedvalues_set(self):
     self.assertTrue(
         valid.valid_1d_array(array=self.data, allowed_values={0, 1}))
Esempio n. 4
0
 def test_allowedvalues_array(self):
     self.assertTrue(
         valid.valid_1d_array(array=self.data,
                              allowed_values=np.array([0, 1])))
Esempio n. 5
0
 def test_allowedtypes_integral(self):
     self.assertTrue(
         valid.valid_1d_array(array=self.data, allowed_types=Integral))
Esempio n. 6
0
 def test_allowedtypes_float(self):
     self.assertTrue(
         valid.valid_1d_array(array=np.ones(4, dtype=float),
                              allowed_types=(int, float)))
Esempio n. 7
0
 def test_allow_none_true(self):
     self.assertTrue(valid.valid_1d_array(None, allow_none=True))
Esempio n. 8
0
 def test_allowedtypes_none(self):
     self.assertTrue(
         valid.valid_1d_array(array=self.data, allowed_types=None))
Esempio n. 9
0
 def test_minlength_equal_length(self):
     self.assertTrue(valid.valid_1d_array(self.data, min_length=7))
Esempio n. 10
0
 def test_minlength_None(self):
     self.assertTrue(valid.valid_1d_array(self.data, min_length=None))
Esempio n. 11
0
 def test_minlength_null(self):
     self.assertTrue(valid.valid_1d_array(self.data, min_length=0))
Esempio n. 12
0
 def test_length_null(self):
     self.assertTrue(valid.valid_1d_array(np.empty(0), length=0))
Esempio n. 13
0
def valid_param(key: str, value: Any) -> Tuple[Any, bool]:
    """
    Validate a key value pair corresponding to an input parameter.

    It will raise an exception if the check fails.

    :param key: name of the parameter
    :param value: the value of the parameter
    :return: a tuple (formatted_value, is_valid). is_valid is True if the key
     is valid, False otherwise.
    """
    is_valid = True
    allowed: Any = None

    # convert 'None' to None
    if value == "None":
        value = None

    # convert 'True' to True
    if isinstance(value, str) and value.lower() == "true":
        value = True

    # convert 'False' to False
    if isinstance(value, str) and value.lower() == "false":
        value = False

    # test the booleans first
    if key in {
            "align_axis",
            "align_q",
            "apodize",
            "bin_during_loading",
            "correct_refraction",
            "custom_scan",
            "debug",
            "flag_interact",
            "flip_reconstruction",
            "get_temperature",
            "grey_background",
            "invert_phase",
            "is_series",
            "keep_size",
            "mask_zero_event",
            "reload_orthogonal",
            "reload_previous",
            "save",
            "save_as_int",
            "save_rawdata",
            "save_support",
            "save_to_mat",
            "save_to_npz",
            "save_to_vti",
            "simulation",
            "use_rawdata",
    }:
        valid.valid_item(value, allowed_types=bool, name=key)
    elif key == "absorption":
        valid.valid_item(value, allowed_types=Real, min_excluded=0, name=key)
    elif key == "actuators":
        valid.valid_container(value,
                              container_types=dict,
                              allow_none=True,
                              name=key)
    elif key == "apodization_alpha":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=Real,
            min_included=0,
            name=key,
        )
        value = np.asarray(value)
    elif key == "apodization_mu":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=Real,
            min_included=0,
            name=key,
        )
        value = np.asarray(value)
    elif key == "apodization_sigma":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=Real,
            min_included=0,
            name=key,
        )
        value = np.asarray(value)
    elif key == "apodization_window":
        allowed = {"blackman", "tukey", "normal"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "averaging_space":
        allowed = {"reciprocal_space", "direct_space"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "axis_to_align":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=Real,
            name=key,
        )
        value = np.asarray(value)
    elif key == "backend":
        allowed = {
            "Agg", "Qt5Agg", "module://matplotlib_inline.backend_inline"
        }
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "background_file":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              allow_none=True,
                              name=key)
    elif key == "background_plot":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              name=key)
    elif key == "beam_direction":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=Real,
            name=key,
        )
        value = np.asarray(value)
    elif key == "beamline":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              name=key)
    elif key == "bragg_peak":
        valid.valid_container(
            value,
            container_types=(tuple, list),
            item_types=Real,
            min_included=0,
            length=3,
            allow_none=True,
            name=key,
        )
    elif key == "cch1":
        valid.valid_item(value, allowed_types=Real, name=key)
    elif key == "cch2":
        valid.valid_item(value, allowed_types=Real, name=key)
    elif key == "center_fft":
        allowed = {
            "crop_sym_ZYX",
            "crop_asym_ZYX",
            "pad_asym_Z_crop_sym_YX",
            "pad_sym_Z_crop_asym_YX",
            "pad_sym_Z",
            "pad_asym_Z",
            "pad_sym_ZYX",
            "pad_asym_ZYX",
            "skip",
        }
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "centering_method":
        allowed = {"com", "max", "max_com", "do_nothing"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "center_roi_x":
        valid.valid_item(value, allowed_types=int, allow_none=True, name=key)
    elif key == "center_roi_y":
        valid.valid_item(value, allowed_types=int, allow_none=True, name=key)
    elif key == "colormap":
        if value not in ["turbo", "custom"] and value not in cc.cm:
            raise ValueError(f"unknow colormap '{value}'")
    elif key == "comment":
        valid.valid_container(value, container_types=str, name=key)
        if value and not value.startswith("_"):
            value += "_"
    elif key == "config_file":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              name=key)
        if not os.path.isfile(value):
            raise ValueError(f"The file {value} does not exist")
    elif key == "correlation_threshold":
        valid.valid_item(value,
                         allowed_types=Real,
                         min_included=0,
                         max_included=1,
                         name=key)
    elif key == "custom_images":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            item_types=int,
            min_included=0,
            allow_none=True,
            name=key,
        )
    elif key == "custom_monitor":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            item_types=Real,
            min_included=0,
            allow_none=True,
            name=key,
        )
    elif key == "custom_motors":
        valid.valid_container(value,
                              container_types=dict,
                              allow_none=True,
                              name=key)
    elif key == "custom_pixelsize":
        valid.valid_item(value,
                         allowed_types=Real,
                         min_excluded=0,
                         allow_none=True,
                         name=key)
    elif key == "data_dir":
        if value is not None:
            valid.valid_container(value,
                                  container_types=str,
                                  min_length=1,
                                  name=key)
            if not os.path.isdir(value):
                raise ValueError(f"The directory {value} does not exist")
    elif key == "data_frame":
        allowed = {"detector", "crystal", "laboratory"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "dirbeam_detector_angles":
        valid.valid_container(
            value,
            container_types=(list, tuple),
            item_types=Real,
            length=2,
            allow_none=True,
            name=key,
        )
    elif key == "direct_beam":
        valid.valid_container(
            value,
            container_types=(list, tuple),
            item_types=Real,
            length=2,
            allow_none=True,
            name=key,
        )
    elif key == "detector":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              name=key)
    elif key == "detrot":
        valid.valid_item(value, allowed_types=Real, name=key)
    elif key == "dispersion":
        valid.valid_item(value, allowed_types=Real, min_excluded=0, name=key)
    elif key == "energy":
        if value is None or isinstance(value, Number):
            valid.valid_item(value,
                             allowed_types=Real,
                             min_excluded=0,
                             allow_none=True,
                             name=key)
        else:
            valid.valid_container(
                value,
                container_types=(tuple, list, np.ndarray),
                min_length=1,
                item_types=Real,
                min_excluded=0,
                name=key,
            )
    elif key == "fill_value_mask":
        allowed = (0, 1)
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "fix_size":
        valid.valid_container(
            value,
            container_types=(tuple, list),
            length=6,
            item_types=int,
            allow_none=True,
            name=key,
        )
    elif key == "fix_voxel":
        valid.valid_item(value,
                         allowed_types=Real,
                         min_excluded=0,
                         allow_none=True,
                         name=key)
    elif key == "flatfield_file":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              allow_none=True,
                              name=key)
    elif key == "frames_pattern":
        if value is not None:
            value = np.asarray(value)
            valid.valid_1d_array(value,
                                 allow_none=False,
                                 allowed_values={0, 1},
                                 name=key)
    elif key == "half_width_avg_phase":
        valid.valid_item(value, allowed_types=int, min_included=0, name=key)
    elif key == "hotpixels_file":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              allow_none=True,
                              name=key)
    elif key == "inplane_angle":
        valid.valid_item(value, allowed_types=Real, allow_none=True, name=key)
    elif key == "interpolation_method":
        allowed = {"xrayutilities", "linearization"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "isosurface_strain":
        valid.valid_item(value, allowed_types=Real, min_excluded=0, name=key)
    elif key == "linearity_func":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=5,
            item_types=Real,
            allow_none=True,
            name=key,
        )
    elif key == "median_filter":
        allowed = {"median", "interp_isolated", "mask_isolated", "skip"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "median_filter_order":
        valid.valid_item(value, allowed_types=int, min_included=0, name=key)
    elif key == "normalize_flux":
        allowed = {"monitor", "skip"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "offset_inplane":
        valid.valid_item(value, allowed_types=Real, name=key)
    elif key == "offset_method":
        allowed = {"com", "mean"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "optical_path_method":
        allowed = {"threshold", "defect"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "original_size":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=int,
            min_excluded=0,
            allow_none=True,
            name=key,
        )
    elif key == "outofplane_angle":
        valid.valid_item(value, allowed_types=Real, allow_none=True, name=key)
    elif key == "output_size":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=int,
            min_excluded=0,
            allow_none=True,
            name=key,
        )
    elif key == "pad_size":
        valid.valid_container(
            value,
            container_types=(tuple, list),
            length=3,
            item_types=int,
            allow_none=True,
            name=key,
        )
    elif key == "phase_offset":
        valid.valid_item(value, allowed_types=Real, allow_none=True, name=key)
    elif key == "phase_offset_origin":
        valid.valid_item(value, allowed_types=Real, allow_none=True, name=key)
    elif key == "phase_ramp_removal":
        allowed = {"gradient", "upsampling"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "phase_range":
        valid.valid_item(value, allowed_types=Real, min_excluded=0, name=key)
    elif key == "phasing_binning":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=int,
            min_excluded=0,
            name=key,
        )
    elif key == "photon_filter":
        allowed = {"loading", "postprocessing"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "photon_threshold":
        valid.valid_item(value, allowed_types=Real, min_included=0, name=key)
    elif key == "preprocessing_binning":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=int,
            min_excluded=0,
            name=key,
        )
    elif key == "reconstruction_file":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              allow_none=True,
                              name=key)
        if value is not None and not os.path.isfile(value):
            raise ValueError(f"The file {value} does not exist")
    elif key in {"ref_axis_q", "ref_axis"}:
        allowed = {"x", "y", "z"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "reference_spacing":
        valid.valid_item(value,
                         allowed_types=Real,
                         min_included=0,
                         allow_none=True,
                         name=key)
    elif key == "reference_temperature":
        valid.valid_item(value,
                         allowed_types=Real,
                         min_included=0,
                         allow_none=True,
                         name=key)
    elif key == "reflection":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=Real,
            name=key,
        )
        value = np.asarray(value)
    elif key == "rocking_angle":
        allowed = {"outofplane", "inplane", "energy"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "roi_detector":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=4,
            item_types=int,
            allow_none=True,
            name=key,
        )
    elif key == "roll_modes":
        valid.valid_container(
            value,
            container_types=(tuple, list, np.ndarray),
            length=3,
            item_types=int,
            name=key,
        )
    elif key == "root_folder":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              name=key)
        if not os.path.isdir(value):
            raise ValueError(f"The directory {value} does not exist")
    elif key == "sample_inplane":
        valid.valid_container(
            value,
            container_types=(tuple, list),
            length=3,
            item_types=Real,
            name=key,
        )
    elif key == "sample_name":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              name=key)
    elif key == "sample_offsets":
        valid.valid_container(value,
                              container_types=(tuple, list, np.ndarray),
                              allow_none=True,
                              name=key)
    elif key == "sample_outofplane":
        valid.valid_container(
            value,
            container_types=(tuple, list),
            length=3,
            item_types=Real,
            name=key,
        )
    elif key == "save_dir":
        valid.valid_container(value,
                              container_types=str,
                              min_length=1,
                              allow_none=True,
                              name=key)
        if isinstance(value, str) and not value.endswith("/"):
            value += "/"
    elif key == "save_frame":
        allowed = {"laboratory", "crystal", "lab_flat_sample"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "scan":
        valid.valid_item(value, allowed_types=int, min_included=0, name=key)
    elif key == "scans":
        if isinstance(value, Real):
            value = (value, )
        valid.valid_container(value,
                              container_types=(tuple, list, np.ndarray),
                              min_length=1,
                              name=key)

    elif key == "sdd":
        valid.valid_item(value,
                         allowed_types=Real,
                         min_excluded=0,
                         allow_none=True,
                         name=key)
    elif key == "sort_method":
        allowed = {"mean_amplitude", "variance", "variance/mean", "volume"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "specfile_name":
        valid.valid_container(value,
                              container_types=str,
                              allow_none=True,
                              name=key)
    elif key == "strain_method":
        allowed = {"default", "defect"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "strain_range":
        valid.valid_item(value, allowed_types=Real, min_excluded=0, name=key)
    elif key == "template_imagefile":
        valid.valid_container(value,
                              container_types=str,
                              min_length=0,
                              allow_none=True,
                              name=key)
    elif key == "threshold_gradient":
        valid.valid_item(value, allowed_types=Real, min_excluded=0, name=key)
    elif key == "threshold_unwrap_refraction":
        valid.valid_item(value, allowed_types=Real, min_included=0, name=key)
    elif key == "tick_direction":
        allowed = {"out", "in", "inout"}
        if value not in allowed:
            raise ParameterError(key, value, allowed)
    elif key == "tick_length":
        valid.valid_item(value, allowed_types=int, min_included=1, name=key)
    elif key == "tick_spacing":
        valid.valid_item(value, allowed_types=Real, min_excluded=0, name=key)
    elif key == "tick_width":
        valid.valid_item(value, allowed_types=int, min_included=1, name=key)
    elif key == "tilt_angle":
        valid.valid_item(value, allowed_types=Real, allow_none=True, name=key)
    elif key == "tiltazimuth":
        valid.valid_item(value, allowed_types=Real, name=key)
    elif key == "tilt_detector":
        valid.valid_item(value, allowed_types=Real, name=key)
    else:
        # this key is not in the known parameters
        is_valid = False

    return value, is_valid