HFIRSCDSubtractBackground v1#

Summary#

Subtract from WAND or DEMAND data in detector space a background measured at a single goniometer angle, scaled to the integrated flux of each goniometer angle of the sample.

See Also#

LoadWANDSCD, HB3AAdjustSampleNorm, HFIRGoniometerIndependentBackground, ConvertHFIRSCDtoMDE, MDNorm

Properties#

Name

Direction

Type

Default

Description

InputWorkspace

Input

Workspace

Mandatory

Unnormalized sample in detector space, in counts. Either an MDHistoWorkspace with dimensions (y, x, goniometer angle), as returned by LoadWANDSCD or by HB3AAdjustSampleNorm with OutputType=’Detector’, or a WorkspaceGroup of such MDHistoWorkspaces, as returned by HB3AAdjustSampleNorm with OutputType=’Detector’ for several scans. Each member of a WorkspaceGroup is processed with its own flux logs.

InputBackground

Input

Workspace

Mandatory

Background in counts, from the instrument of the sample: either an MDHistoWorkspace with dimensions (y, x, goniometer angle) and a single goniometer angle, or a Workspace2D with one value per spectrum, whose spectra are matched to the pixels of the sample through their detector IDs.

InputGroupingWorkspace

Input

Workspace

Optional: GroupingWorkspace for a sample whose pixels were grouped while the background’s were not, such as the OutputGroupingWorkspace of LoadWANDSCD or HB3AAdjustSampleNorm. The intensities of the background are summed within each group before the subtraction. To be used only with an ungrouped background: a grouped background is rejected when InputGroupingWorkspace is provided.

NormalizedBy

Input

string

None

Flux used to scale the background to each goniometer angle of the sample: the monitor counts or the duration of each angle. With None, the background is subtracted unscaled. Allowed values: [‘None’, ‘Monitor’, ‘Time’]

NullifyNegativeValues

Input

boolean

True

Set to zero the signal of bins that become negative after the subtraction. Their errors are unchanged.

OutputWorkspace

Output

Workspace

Mandatory

Sample minus the scaled background. When it is the same workspace as InputWorkspace, the subtraction is done in place, member by member for a WorkspaceGroup. Otherwise, for a WorkspaceGroup, a new WorkspaceGroup with members named <OutputWorkspace>_<input member name>.

OutputBackgroundWorkspace

Output

Workspace

Optional: the background scaled to every goniometer angle of the sample. For a WorkspaceGroup sample, a WorkspaceGroup with members named <OutputBackgroundWorkspace>_<input member name>.

Description#

This algorithm subtracts a background from WAND or DEMAND single crystal data in detector space. The background is scaled to the integrated flux of each goniometer angle of the sample before it is subtracted. The result, Sample - Background, can then be converted to Q-sample with ConvertHFIRSCDtoMDE and normalized with MDNorm.

InputWorkspace is an MDHistoWorkspace with dimensions (y, x, goniometer angle), as returned by LoadWANDSCD or by HB3AAdjustSampleNorm with OutputType="Detector", or a WorkspaceGroup of such workspaces, such as the output of HB3AAdjustSampleNorm with OutputType="Detector" for several scans. With this output type, HB3AAdjustSampleNorm always returns several scans as a WorkspaceGroup. Each member of a WorkspaceGroup is processed with its own flux logs. The sample and the background must come from the same instrument.

Background#

InputBackground is in counts and takes one of two forms:

  • An MDHistoWorkspace with dimensions (y, x, goniometer angle) and a single goniometer angle, such as a background run loaded with LoadWANDSCD or HB3AAdjustSampleNorm. Without InputGroupingWorkspace, it has the pixel dimensions of the sample.

  • A Workspace2D with one value per spectrum, from the instrument of the sample. Its spectra are matched to the pixels of the sample through their detector IDs, using the detectorID sample log of the sample, which LoadWANDSCD and HB3AAdjustSampleNorm write. Without InputGroupingWorkspace, it has one spectrum per pixel of the sample. Its flux is read from its own sample logs, which hold a single value.

When the sample was loaded with pixel grouping (Grouping="2x2" or "4x4") and the background was not, provide the GroupingWorkspace that the loader returns in OutputGroupingWorkspace as InputGroupingWorkspace. The intensities and errors squared of the background are then summed within each group before the subtraction. The group of each pixel or spectrum of the background is that of its detector ID, read from the detectorID log of an MDHistoWorkspace background or from the spectra of a Workspace2D background.

For clarity, InputGroupingWorkspace is to be used only with an ungrouped background. The algorithm rejects a call that passes both a grouped background and InputGroupingWorkspace, whatever the grouping of the background: the same as that of the sample, finer, or coarser. When the sample and the background were loaded with the same grouping, subtract them without InputGroupingWorkspace.

The sample must not be normalized, because the background is in counts. The algorithm does not check this; load the sample with NormalizeData=False in LoadWANDSCD or HB3AAdjustSampleNorm.

Scaling and subtraction#

For each pixel and each goniometer angle \(\theta\) of the sample, the output is

\[O(\theta) = S(\theta) - r(\theta)\,B, \qquad r(\theta) = \frac{F_S(\theta)}{F_B}\]

where \(S\) is the sample, \(B\) the background, and \(F_S(\theta)\) and \(F_B\) the integrated flux of goniometer angle \(\theta\) of the sample and of the background. NormalizedBy selects the flux:

  • Monitor: the monitor counts, from the monitor_count log for WAND and the monitor log for DEMAND.

  • Time: the duration, from the duration log for WAND and the time log for DEMAND.

  • None: no scaling, \(r(\theta) = 1\).

The uncertainties are propagated as for any difference of independent measurements:

\[\sigma_O^2(\theta) = \sigma_S^2(\theta) + r(\theta)^2\,\sigma_B^2\]

Negative values#

Where the sample contains only background, the subtraction can give a negative signal. When NullifyNegativeValues is True (the default), the signal of such bins is set to zero and their errors keep the propagated value \(\sigma_O\): the sample and the scaled background are two independent measurements of the same background, and \(\sigma_O\) is the statistical uncertainty of their difference.

Output#

When OutputWorkspace is the same workspace as InputWorkspace, the subtraction is done in place and no copy of the sample is made; for a WorkspaceGroup, each member is modified in place. Otherwise OutputWorkspace is a new workspace and InputWorkspace is left unchanged; for a WorkspaceGroup, OutputWorkspace is a new WorkspaceGroup whose members are named <OutputWorkspace>_<input member name>, as in HB3AAdjustSampleNorm.

The optional OutputBackgroundWorkspace holds the background scaled to every goniometer angle of the sample, \(r(\theta)\,B\), with errors \(r(\theta)\,\sigma_B\), and the dimensions and sample logs of the sample. For a WorkspaceGroup sample, it is a WorkspaceGroup whose members are named <OutputBackgroundWorkspace>_<input member name>. It is created only when a name is given.

A sample of several scans can occupy a lot of memory. Doing the subtraction in place and leaving OutputBackgroundWorkspace empty avoids creating any workspace of the size of the sample. The members of a WorkspaceGroup are processed one after the other, and the background is subtracted one goniometer angle at a time, so the additional memory used is that of one copy of the signal of one member.

Workflow#

  1. Load the sample in counts (NormalizeData=False) with LoadWANDSCD or HB3AAdjustSampleNorm (OutputType="Detector"), with pixel grouping if wanted, and keep the GroupingWorkspace of a grouped sample (OutputGroupingWorkspace). For WAND, also keep the vanadium normalization (OutputNormalizationWorkspace).

  2. Load the background.

  3. Convert Sample - Background and the normalization to Q-sample with ConvertHFIRSCDtoMDE, directly for WAND, or through HB3AAdjustSampleNorm with OutputType="Q-sample events" for DEMAND.

  4. Normalize with MDNorm, giving the converted normalization as MonoSCDNormalizationWorkspace.

Usage#

The examples read data from the HFIR archive and are not run when the documentation is built.

Example - WAND, 4x4 grouped sample and ungrouped background

The background is the mean count rate of each pixel over the first 100 runs of the scan, in counts for the duration of the first run, with the flux logs of that run. An ungrouped WAND pixel records about 0.01 counts per run, so the median over the runs, as taken by HFIRGoniometerIndependentBackground, is zero. Unlike the median, the mean includes the Bragg peaks that cross a pixel during these runs. The sample is one run every 10 of the same 100 runs.

import numpy as np
from mantid.simpleapi import *

# Background: mean count rate of runs 26640-26739, ungrouped,
# in counts for the duration of the first run
runs = LoadWANDSCD(
    IPTS=7776,
    RunNumbers="26640-26739",
    OutputWorkspace="background_runs"
)
SliceMDHisto(
    InputWorkspace="background_runs",
    Start="0,0,0",
    End="512,3840,1",
    OutputWorkspace="background_slice"
)
# SliceMDHisto shares the sample logs of its input,
# so the slice is cloned before its flux logs are changed
background = CloneMDWorkspace(
    InputWorkspace="background_slice",
    OutputWorkspace="background"
)
logs = runs.getExperimentInfo(0).run()
duration = np.asarray(logs.getProperty("duration").value)
scale = duration[0] / duration.sum()
counts = runs.getSignalArray().sum(axis=2, keepdims=True)
errors_squared = runs.getErrorSquaredArray().sum(axis=2, keepdims=True)
background.setSignalArray(scale * counts)
background.setErrorSquaredArray(scale**2 * errors_squared)
run = background.getExperimentInfo(0).mutableRun()
for log in ("duration", "monitor_count"):
    run.addProperty(log, float(np.asarray(logs.getProperty(log).value)[0]), True)
DeleteWorkspaces(["background_runs", "background_slice"])

# Sample in counts, grouped 4x4, with the vanadium normalization and the GroupingWorkspace
LoadWANDSCD(
    IPTS=7776,
    RunNumbers=",".join(str(run) for run in range(26640, 26740, 10)),
    VanadiumIPTS=7776,
    VanadiumRunNumber=26509,
    NormalizeData=False,
    Grouping="4x4",
    OutputWorkspace="sample",
    OutputNormalizationWorkspace="norm",
    OutputGroupingWorkspace="grouping"
)

# Subtract in place; the ungrouped background is grouped 4x4 by InputGroupingWorkspace
HFIRSCDSubtractBackground(
    InputWorkspace="sample",
    InputBackground="background",
    InputGroupingWorkspace="grouping",
    NormalizedBy="Time",
    OutputWorkspace="sample"
)

# Convert to Q-sample and normalize; LoadWANDSCD has set the goniometer of each angle
for name in ("sample", "norm"):
    ConvertHFIRSCDtoMDE(
        InputWorkspace=name,
        Wavelength=1.488,
        OutputWorkspace=f"{name}_md"
    )
# Horizontal plane, Q_sample_y between -0.5 and 0.5, over the Q range of these runs
MDNorm(
    InputWorkspace="sample_md",
    MonoSCDNormalizationWorkspace="norm_md",
    RLU=False,
    Dimension0Binning="0,0.05,5",
    Dimension1Binning="-0.5,0.5",
    Dimension2Binning="-7,0.05,1",
    OutputWorkspace="result",
    OutputDataWorkspace="result_data",
    OutputNormalizationWorkspace="result_norm"
)

Example - DEMAND, WorkspaceGroup sample

Scans 0187 and 0188 of experiment 724, loaded together, are a WorkspaceGroup of two members, each with its own monitor counts. The background is the mean count rate per monitor count of each pixel over the 6 frames of scan 0188, which show no Bragg peak, in counts for the monitor of its first frame. As for WAND, a pixel records too few counts per frame for a median.

import numpy as np
from mantid.simpleapi import *

directory = "/HFIR/HB3A/IPTS-24655/shared/autoreduce"

# Background: mean count rate per monitor count of scan 0188, ungrouped,
# in counts for the monitor of its first frame
frames = HB3AAdjustSampleNorm(
    Filename=f"{directory}/HB3A_exp0724_scan0188.nxs",
    OutputType="Detector",
    NormalizeData=False,
    OutputWorkspace="background_frames"
)
SliceMDHisto(
    InputWorkspace="background_frames",
    Start="0,0,0",
    End="1536,512,1",
    OutputWorkspace="background_slice"
)
# SliceMDHisto shares the sample logs of its input,
# so the slice is cloned before its flux logs are changed
background = CloneMDWorkspace(
    InputWorkspace="background_slice",
    OutputWorkspace="background"
)
logs = frames.getExperimentInfo(0).run()
monitor = np.asarray(logs.getProperty("monitor").value)
scale = monitor[0] / monitor.sum()
counts = frames.getSignalArray().sum(axis=2, keepdims=True)
errors_squared = frames.getErrorSquaredArray().sum(axis=2, keepdims=True)
background.setSignalArray(scale * counts)
background.setErrorSquaredArray(scale**2 * errors_squared)
run = background.getExperimentInfo(0).mutableRun()
for log in ("time", "monitor"):
    run.addProperty(log, float(np.asarray(logs.getProperty(log).value)[0]), True)
DeleteWorkspaces(["background_frames", "background_slice"])

sample_files = ",".join(f"{directory}/HB3A_exp0724_scan{scan:04d}.nxs" for scan in (187, 188))
HB3AAdjustSampleNorm(
    Filename=sample_files,
    OutputType="Detector",
    NormalizeData=False,
    OutputWorkspace="sample"
)

# Subtract in place, member by member
HFIRSCDSubtractBackground(
    InputWorkspace="sample",
    InputBackground="background",
    NormalizedBy="Monitor",
    OutputWorkspace="sample"
)

# Convert to Q-sample, merging the members, with the vanadium normalization
HB3AAdjustSampleNorm(
    InputWorkspaces=",".join(mtd["sample"].getNames()),
    VanadiumFile="/HFIR/HB3A/IPTS-24612/shared/autoreduce/HB3A_exp0722_scan0220.nxs",
    NormalizeData=False,
    OutputType="Q-sample events",
    MergeInputs=True,
    OutputWorkspace="sample_md",
    OutputNormalizationWorkspace="norm_md"
)
# Q_sample_x between -1 and 1, over the Q range of these scans
MDNorm(
    InputWorkspace="sample_md",
    MonoSCDNormalizationWorkspace="norm_md",
    RLU=False,
    Dimension0Binning="-1,1",
    Dimension1Binning="-4,0.05,1",
    Dimension2Binning="-5,0.05,-2",
    OutputWorkspace="result",
    OutputDataWorkspace="result_data",
    OutputNormalizationWorkspace="result_norm"
)

Categories: AlgorithmIndex | Diffraction\Reduction

Source#

Python: HFIRSCDSubtractBackground.py