Exemple #1
0
    def run_udf(self,
                dataset: DataSet,
                udf: UDF,
                roi: np.ndarray = None,
                corrections: CorrectionSet = None,
                progress: bool = False,
                backends=None) -> Dict[str, BufferWrapper]:
        """
        Run :code:`udf` on :code:`dataset`, restricted to the region of interest :code:`roi`.

        .. versionchanged:: 0.5.0
            Added the :code:`progress` parameter

        .. versionchanged:: 0.6.0
            Added the :code:`corrections` and :code:`backends` parameter

        Parameters
        ----------
        dataset
            The dataset to work on

        udf
            UDF instance you want to run

        roi : numpy.ndarray
            Region of interest as bool mask over the navigation axes of the dataset

        progress : bool
            Show progress bar

        corrections
            Corrections to apply while running the UDF. If none are given,
            the corrections that are part of the :code:`DataSet` are used,
            if there are any.

        backends : None or iterable containing 'numpy', 'cupy' and/or 'cuda'
            Restrict the back-end to a subset of the capabilities of the UDF.
            This can be useful for testing hybrid UDFs.

        Returns
        -------
        dict
            Return value of the UDF containing the result buffers of
            type :class:`libertem.common.buffers.BufferWrapper`. Note that a
            :class:`~libertem.common.buffers.BufferWrapper` can be used like
            a :class:`numpy.ndarray` in many cases because it implements
            :meth:`__array__`. You can access the underlying numpy array using the
            :attr:`~libertem.common.buffers.BufferWrapper.data` property.
        """
        if corrections is None:
            corrections = dataset.get_correction_data()
        results = UDFRunner([udf]).run_for_dataset(
            dataset=dataset,
            executor=self.executor,
            roi=roi,
            progress=progress,
            corrections=corrections,
            backends=backends,
        )
        return results[0]
Exemple #2
0
 def _make_udf_tasks(self, dataset: DataSet, roi):
     for idx, partition in enumerate(dataset.get_partitions()):
         if roi is not None:
             roi_for_part = self._roi_for_partition(roi, partition)
             if np.count_nonzero(roi_for_part) == 0:
                 # roi is empty for this partition, ignore
                 continue
         udf = self._udf.copy_for_partition(partition, roi)
         yield UDFTask(partition=partition, idx=idx, udf=udf, roi=roi)
Exemple #3
0
 def _make_udf_tasks(self, dataset: DataSet, roi, corrections, backends):
     for idx, partition in enumerate(dataset.get_partitions()):
         if roi is not None:
             roi_for_part = self._roi_for_partition(roi, partition)
             if np.count_nonzero(roi_for_part) == 0:
                 # roi is empty for this partition, ignore
                 continue
         udfs = [
             udf.copy_for_partition(partition, roi)
             for udf in self._udfs
         ]
         yield UDFTask(
             partition=partition, idx=idx, udfs=udfs, roi=roi, corrections=corrections,
             backends=backends,
         )
Exemple #4
0
    def _run_sync(
        self,
        dataset: DataSet,
        udf: Union[UDF, Iterable[UDF]],
        roi: Optional[np.ndarray],
        corrections: Optional[CorrectionSet],
        progress: bool,
        backends,
        plots,
        iterate: bool,
    ):
        """
        Run the given UDF(s), either returning the final result (when
        :code:`iterate=False` is given), or a generator that yields partial results.
        """
        enable_plotting = bool(plots)

        udf_is_list = isinstance(udf, Iterable)
        if not isinstance(udf, Iterable):
            udfs = [udf]
        else:
            udfs = list(udf)

        if enable_plotting:
            plots = self._prepare_plots(udfs, dataset, roi, plots)

        if corrections is None:
            corrections = dataset.get_correction_data()

        if (roi is not None) and (roi.dtype is not np.dtype(bool)):
            warnings.warn(
                f"ROI dtype is {roi.dtype}, expected bool. Attempting cast to bool."
            )
            roi = roi.astype(bool)

        def _run_sync_wrap() -> Generator[UDFResults, None, None]:
            runner_cls = self.executor.get_udf_runner()
            result_iter = runner_cls(udfs).run_for_dataset_sync(
                dataset=dataset,
                executor=self.executor,
                roi=roi,
                progress=progress,
                corrections=corrections,
                backends=backends,
                iterate=(iterate or enable_plotting))
            for udf_results in result_iter:
                yield udf_results
                if enable_plotting:
                    self._update_plots(plots,
                                       udfs,
                                       udf_results.buffers,
                                       udf_results.damage.data,
                                       force=False)
            if enable_plotting:
                self._update_plots(plots,
                                   udfs,
                                   udf_results.buffers,
                                   udf_results.damage.data,
                                   force=True)

        if iterate:
            return _run_sync_wrap()
        else:
            udf_results = run_gen_get_last(_run_sync_wrap())
            if udf_is_list:
                return udf_results.buffers
            else:
                return udf_results.buffers[0]
Exemple #5
0
    def _run_sync(
        self,
        dataset: DataSet,
        udf: UDF,
        roi: np.ndarray = None,
        corrections: CorrectionSet = None,
        progress: bool = False,
        backends=None,
        plots=None,
        iterate=False,
    ):
        """
        Run the given UDF(s), either returning the final result (when
        :code:`iterate=False` is given), or a generator that yields partial results.
        """
        enable_plotting = bool(plots)

        udf_is_list = isinstance(udf, (tuple, list))
        if not udf_is_list:
            udfs = [udf]
        else:
            udfs = list(udf)

        if enable_plotting:
            plots = self._prepare_plots(udfs, dataset, roi, plots)

        if corrections is None:
            corrections = dataset.get_correction_data()

        if (roi is not None) and (roi.dtype is not np.dtype(bool)):
            warnings.warn(
                f"ROI dtype is {roi.dtype}, expected bool. Attempting cast to bool."
            )
            roi = roi.astype(bool)

        def _run_sync_wrap():
            result_iter = UDFRunner(udfs).run_for_dataset_sync(
                dataset=dataset,
                executor=self.executor,
                roi=roi,
                progress=progress,
                corrections=corrections,
                backends=backends,
            )
            for udf_results in result_iter:
                yield udf_results
                if enable_plotting:
                    self._update_plots(plots,
                                       udfs,
                                       udf_results.buffers,
                                       udf_results.damage,
                                       force=False)
            if enable_plotting:
                self._update_plots(plots,
                                   udfs,
                                   udf_results.buffers,
                                   udf_results.damage,
                                   force=True)

        if iterate:
            return _run_sync_wrap()
        else:
            for udf_results in _run_sync_wrap():
                pass
            if udf_is_list:
                return udf_results.buffers
            else:
                return udf_results.buffers[0]