Exemple #1
0
def poisson_noise(measurement: Measurement, dose: float):
    """
    Add Poisson noise to a measurment.

    Parameters
    ----------
    measurement: Measurement object
        The measurement to add noise to.
    dose: float
        The irradiation dose in electrons per Å^2.

    Returns
    -------
    measurement: Measurement object
        The noisy measurement.
    """

    pixel_area = np.product([calibration.sampling for calibration in measurement.calibrations[:2]])

    measurement = measurement.copy()
    array = measurement.array

    electrons_per_pixel = dose * pixel_area

    measurement.array[:] = array * electrons_per_pixel
    measurement.array[:] = np.random.poisson(array).astype(np.float)
    return measurement
Exemple #2
0
def poisson_noise(measurement: Measurement,
                  dose: float,
                  pixel_area: float = None,
                  negative_values='clip'):
    """
    Add Poisson noise to a measurment.

    Parameters
    ----------
    measurement: Measurement object
        The measurement to add noise to.
    dose: float
        The irradiation dose in electrons per Å^2.
    pixel_area: float, optional
        Pixel area in Å^2. If not provided this will be calculated from the calibraions when possible.

    Returns
    -------
    measurement: Measurement object
        The noisy measurement.
    """

    if pixel_area is None:
        pixel_areas = []
        for calibration in measurement.calibrations:
            if calibration is not None:
                if calibration.units.lower() in ('angstrom', 'å'):
                    pixel_areas.append(calibration.sampling)

        if len(pixel_areas) != 2:
            raise RuntimeError(
                'Real space pixel size not recognized from calibrations.')

        pixel_area = np.product(pixel_areas)

    measurement = measurement.copy()
    array = measurement.array

    if negative_values == 'clip':
        array = np.clip(array, a_min=1e-12, a_max=None)
    elif negative_values != 'raise':
        if np.any(array < 0.):
            raise ValueError('Measurement values must be positive.')

    electrons_per_pixel = dose * pixel_area
    array = array * electrons_per_pixel
    measurement.array[:] = np.random.poisson(array).astype(np.float)
    return measurement
Exemple #3
0
def add_scan_noise(measurement: Measurement,
                   dwell_time: float,
                   flyback_time: float,
                   max_frequency: float,
                   rms_power: float,
                   num_components: int = 200):
    """
    Add scan noise to a measurement.

    Parameters
    ----------
    measurement: Measurement object or 2d array
        The measurement to add noise to.
    dwell_time: float
        Dwell time on a single pixel in s.
    flyback_time: float
        Flyback time for the scanning probe at the end of each scan line in s.
    max_frequency: float
        Maximum noise frequency in 1 / s.
    rms_power: float
        Root-mean-square power of the distortion in unit of percent.
    num_components: int, optional
        Number of frequency components. More components will be more 'white' but will take longer.

    Returns
    -------
    measurement: Measurement object
        The noisy measurement.
    """

    measurement = measurement.copy()
    if isinstance(measurement, Measurement):
        array = measurement.array
    else:
        array = measurement

    time = _pixel_times(dwell_time, flyback_time, array.T.shape)
    displacement_x, displacement_y = _make_displacement_field(
        time, max_frequency, num_components, rms_power)
    array[:] = _apply_displacement_field(array.T, displacement_x,
                                         displacement_y).T

    return measurement