Beispiel #1
0
def electron_count(reader,
                   darkreference,
                   number_of_samples=40,
                   background_threshold_n_sigma=4,
                   xray_threshold_n_sigma=10,
                   threshold_num_blocks=1,
                   scan_width=0,
                   scan_height=0):

    blocks = []
    for i in range(threshold_num_blocks):
        blocks.append(next(reader))

    background_threshold, xray_threshold = _image.calculate_thresholds(
        [b._block for b in blocks], darkreference._image, number_of_samples,
        background_threshold_n_sigma, xray_threshold_n_sigma)

    # Reset the reader
    reader.reset()

    events = _image.electron_count(reader.begin(), reader.end(),
                                   darkreference._image, background_threshold,
                                   xray_threshold, scan_width, scan_height)

    # Convert to numpy and return
    return np.array([np.array(x) for x in events])
Beispiel #2
0
def electron_count(reader,
                   darkreference=None,
                   number_of_samples=40,
                   background_threshold_n_sigma=4,
                   xray_threshold_n_sigma=10,
                   threshold_num_blocks=1,
                   scan_dimensions=(0, 0),
                   verbose=False,
                   gain=None):
    """Generate a list of coordinates of electron hits.

    :param reader: the file reader that has already opened the data.
    :type reader: stempy.io.reader
    :param darkreference: the dark reference to subtract, potentially generated
                          via stempy.image.calculate_average().
    :type darkreference: stempy.image.ImageArray or stempy::Image<double>
    :param number_of_samples: the number of samples to take when calculating
                              the thresholds.
    :type number_of_samples: int
    :param background_threshold_n_sigma: N-Sigma used for calculating the
                                         background threshold.
    :type background_threshold_n_sigma: int
    :param xray_threshold_n_sigma: N-Sigma used for calculating the X-Ray
                                   threshold
    :type xray_threshold_n_sigma: int
    :param threshold_num_blocks: The number of blocks of data to use when
                                 calculating the threshold.
    :type threshold_num_blocks: int
    :param scan_dimensions: the dimensions of the scan, where the order is
                            (width, height). Required if `data` is a
                            numpy.ndarray.
    :type scan_dimensions: tuple of ints of length 2
    :param verbose: whether or not to print out verbose output.
    :type verbose: bool
    :param gain: the gain mask to apply. Must match the frame dimensions
    :type gain: numpy.ndarray (2D)

    :return: the coordinates of the electron hits for each frame.
    :rtype: SparseArray
    """
    if gain is not None:
        # Invert, as we will multiply in C++
        # It also must be a float32
        gain = np.power(gain, -1)
        gain = _safe_cast(gain, np.float32, 'gain')

    if isinstance(darkreference, np.ndarray):
        # Must be float32 for correct conversions
        darkreference = _safe_cast(darkreference, np.float32, 'dark reference')

    # Special case for threaded reader
    if isinstance(reader,
                  (SectorThreadedReader, SectorThreadedMultiPassReader)):
        args = [reader]

        if darkreference is not None:
            args = args + [darkreference]

        # Now add the other args
        args = args + [
            threshold_num_blocks, number_of_samples,
            background_threshold_n_sigma, xray_threshold_n_sigma
        ]

        # add the gain arg if we have been given one.
        if gain is not None:
            args.append(gain)

        args = args + [scan_dimensions, verbose]

        data = _image.electron_count(*args)
    else:
        deprecation_message = (
            'Using a reader in electron_count() that is not a '
            'SectorThreadedReader or a SectorThreadedMultiPassReader is '
            'deprecated in stempy==1.1 and will be removed in stempy==1.2')
        warnings.warn(deprecation_message,
                      category=DeprecationWarning,
                      stacklevel=2)

        blocks = []
        for i in range(threshold_num_blocks):
            blocks.append(next(reader))

        if darkreference is not None and hasattr(darkreference, '_image'):
            darkreference = darkreference._image

        args = [[b._block for b in blocks]]
        if darkreference is not None:
            args.append(darkreference)

        args = args + [
            number_of_samples, background_threshold_n_sigma,
            xray_threshold_n_sigma
        ]

        if gain is not None:
            args.append(gain)

        res = _image.calculate_thresholds(*args)

        background_threshold = res.background_threshold
        xray_threshold = res.xray_threshold

        if verbose:
            print('****Statistics for calculating electron thresholds****')
            print('number of samples:', res.number_of_samples)
            print('min sample:', res.min_sample)
            print('max sample:', res.max_sample)
            print('mean:', res.mean)
            print('variance:', res.variance)
            print('std dev:', res.std_dev)
            print('number of bins:', res.number_of_bins)
            print('x-ray threshold n sigma:', res.xray_threshold_n_sigma)
            print('background threshold n sigma:',
                  res.background_threshold_n_sigma)
            print('optimized mean:', res.optimized_mean)
            print('optimized std dev:', res.optimized_std_dev)
            print('background threshold:', background_threshold)
            print('xray threshold:', xray_threshold)

        # Reset the reader
        reader.reset()

        args = [reader.begin(), reader.end()]

        if darkreference is not None:
            args.append(darkreference)

        args = args + [background_threshold, xray_threshold]

        if gain is not None:
            args.append(gain)

        args = args + [scan_dimensions]

        data = _image.electron_count(*args)

    # Convert to numpy array
    num_scans = len(data.data)
    frames_per_scan = len(data.data[0]) if data.data else 0

    np_data = np.empty((num_scans, frames_per_scan), dtype=object)
    for i, scan_frames in enumerate(data.data):
        for j, sparse_frame in enumerate(scan_frames):
            np_data[i, j] = np.array(sparse_frame, copy=False)

    metadata = _electron_counted_metadata_to_dict(data.metadata)

    kwargs = {
        'data': np_data,
        'scan_shape': data.scan_dimensions[::-1],
        'frame_shape': data.frame_dimensions,
        'metadata': {
            'electron_counting': metadata
        },
    }
    array = SparseArray(**kwargs)

    # Store a copy of the underlying C++ object in case we need it later
    array._electron_counted_data = data

    return array
Beispiel #3
0
def electron_count(reader,
                   darkreference=None,
                   number_of_samples=40,
                   background_threshold_n_sigma=4,
                   xray_threshold_n_sigma=10,
                   threshold_num_blocks=1,
                   scan_dimensions=(0, 0),
                   verbose=False,
                   gain=None):
    """Generate a list of coordinates of electron hits.

    :param reader: the file reader that has already opened the data.
    :type reader: stempy.io.reader
    :param darkreference: the dark reference to subtract, potentially generated
                          via stempy.image.calculate_average().
    :type darkreference: stempy.image.ImageArray or stempy::Image<double>
    :param number_of_samples: the number of samples to take when calculating
                              the thresholds.
    :type number_of_samples: int
    :param background_threshold_n_sigma: N-Sigma used for calculating the
                                         background threshold.
    :type background_threshold_n_sigma: int
    :param xray_threshold_n_sigma: N-Sigma used for calculating the X-Ray
                                   threshold
    :type xray_threshold_n_sigma: int
    :param threshold_num_blocks: The number of blocks of data to use when
                                 calculating the threshold.
    :type threshold_num_blocks: int
    :param scan_dimensions: the dimensions of the scan, where the order is
                            (width, height). Required if `data` is a
                            numpy.ndarray.
    :type scan_dimensions: tuple of ints of length 2
    :param verbose: whether or not to print out verbose output.
    :type verbose: bool
    :param gain: the gain mask to apply. Must match the frame dimensions
    :type gain: numpy.ndarray (2D)

    :return: the coordinates of the electron hits for each frame.
    :rtype: ElectronCountedData (named tuple with fields 'data',
            'scan_dimensions', and 'frame_dimensions')
    """
    if gain is not None:
        # Invert, as we will multiply in C++
        # It also must be a float32
        gain = np.power(gain, -1)
        gain = _safe_cast(gain, np.float32, 'gain')

    if isinstance(darkreference, np.ndarray):
        # Must be float32 for correct conversions
        darkreference = _safe_cast(darkreference, np.float32, 'dark reference')

    # Special case for threaded reader
    if isinstance(reader,
                  (SectorThreadedReader, SectorThreadedMultiPassReader)):
        args = [reader]

        if darkreference is not None:
            args = args + [darkreference]

        # Now add the other args
        args = args + [
            threshold_num_blocks, number_of_samples,
            background_threshold_n_sigma, xray_threshold_n_sigma
        ]

        # add the gain arg if we have been given one.
        if gain is not None:
            args.append(gain)

        args = args + [scan_dimensions, verbose]

        data = _image.electron_count(*args)
    else:
        blocks = []
        for i in range(threshold_num_blocks):
            blocks.append(next(reader))

        if darkreference is not None and hasattr(darkreference, '_image'):
            darkreference = darkreference._image

        args = [[b._block for b in blocks]]
        if darkreference is not None:
            args.append(darkreference)

        args = args + [
            number_of_samples, background_threshold_n_sigma,
            xray_threshold_n_sigma
        ]

        if gain is not None:
            args.append(gain)

        res = _image.calculate_thresholds(*args)

        background_threshold = res.background_threshold
        xray_threshold = res.xray_threshold

        if verbose:
            print('****Statistics for calculating electron thresholds****')
            print('number of samples:', res.number_of_samples)
            print('min sample:', res.min_sample)
            print('max sample:', res.max_sample)
            print('mean:', res.mean)
            print('variance:', res.variance)
            print('std dev:', res.std_dev)
            print('number of bins:', res.number_of_bins)
            print('x-ray threshold n sigma:', res.xray_threshold_n_sigma)
            print('background threshold n sigma:',
                  res.background_threshold_n_sigma)
            print('optimized mean:', res.optimized_mean)
            print('optimized std dev:', res.optimized_std_dev)
            print('background threshold:', background_threshold)
            print('xray threshold:', xray_threshold)

        # Reset the reader
        reader.reset()

        args = [reader.begin(), reader.end()]

        if darkreference is not None:
            args.append(darkreference)

        args = args + [background_threshold, xray_threshold]

        if gain is not None:
            args.append(gain)

        args = args + [scan_dimensions]

        data = _image.electron_count(*args)

    electron_counted_data = namedtuple(
        'ElectronCountedData', ['data', 'scan_dimensions', 'frame_dimensions'])

    # Convert to numpy array
    electron_counted_data.data = np.array(
        [np.array(x, copy=False) for x in data.data], dtype=np.object)
    electron_counted_data.scan_dimensions = data.scan_dimensions
    electron_counted_data.frame_dimensions = data.frame_dimensions

    # Store a copy of the underlying C++ object in case we need it later
    electron_counted_data._electron_counted_data = data

    return electron_counted_data