Skip to content

Commit

Permalink
Move to UngroupDetectors option
Browse files Browse the repository at this point in the history
  • Loading branch information
rosswhitfield committed Oct 21, 2024
1 parent 4405f95 commit 76f1984
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 52 deletions.
1 change: 0 additions & 1 deletion Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ class MANTID_ALGORITHMS_DLL ExtractMask : public Mantid::API::Algorithm {
const std::vector<std::string> seeAlso() const override { return {"ExtractMaskToTable"}; }
/// Algorithm's category for identification
const std::string category() const override { return "Transforms\\Masking"; }
std::map<std::string, std::string> validateInputs() override;

private:
/// Initialisation code
Expand Down
46 changes: 15 additions & 31 deletions Framework/Algorithms/src/ExtractMask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@ using namespace Kernel;
* Declare the algorithm properties
*/
void ExtractMask::init() {
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input,
PropertyMode::Optional),
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
"A workspace whose masking is to be extracted");
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InstrumentDonor", "", Direction::Input,
PropertyMode::Optional),
"Optional: A workspace whose instrument will be used for the output instead of the InputWorkspace");
declareProperty("UngroupDetectors", false, "If true, the spectra will be ungrouped and masked individually.");
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
"A workspace containing the masked spectra as zeroes and ones.");

Expand All @@ -41,21 +38,11 @@ void ExtractMask::init() {
"detector ID's");
}

std::map<std::string, std::string> ExtractMask::validateInputs() {
std::map<std::string, std::string> errors;
if (isDefault("InputWorkspace") && isDefault("InstrumentDonor")) {
errors["InputWorkspace"] = "Either InputWorkspace or InstrumentDonor is required";
errors["InstrumentDonor"] = "Either InputWorkspace or InstrumentDonor is required";
}
return errors;
}

/**
* Execute the algorithm
*/
void ExtractMask::exec() {
MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
MatrixWorkspace_const_sptr donorWS = getProperty("InstrumentDonor");

// convert input to a mask workspace
auto inputMaskWS = std::dynamic_pointer_cast<const DataObjects::MaskWorkspace>(inputWS);
Expand All @@ -66,34 +53,31 @@ void ExtractMask::exec() {

// List masked of detector IDs
std::vector<detid_t> detectorList;
if (inputWS) {
const auto &detInfo = inputWS->detectorInfo();
const auto &detIds = detInfo.detectorIDs();
for (size_t i = 0; i < detInfo.size(); ++i) {
if ((inputWSIsSpecial && inputMaskWS->isMasked(detIds[i])) || detInfo.isMasked(i)) {
detectorList.emplace_back(detIds[i]);
}
const auto &detInfo = inputWS->detectorInfo();
const auto &detIds = detInfo.detectorIDs();
for (size_t i = 0; i < detInfo.size(); ++i) {
if ((inputWSIsSpecial && inputMaskWS->isMasked(detIds[i])) || detInfo.isMasked(i)) {
detectorList.emplace_back(detIds[i]);
}
}

// Create a new workspace for the results, copy from the input to ensure
// that we copy over the instrument and current masking
std::shared_ptr<DataObjects::MaskWorkspace> maskWS;
if (donorWS) {
maskWS = std::make_shared<DataObjects::MaskWorkspace>(donorWS->getInstrument());
maskWS->setTitle(donorWS->getTitle());
} else {
if (getProperty("UngroupDetectors"))
maskWS = std::make_shared<DataObjects::MaskWorkspace>(inputWS->getInstrument());
else
maskWS = std::make_shared<DataObjects::MaskWorkspace>(inputWS);
maskWS->setTitle(inputWS->getTitle());
}

maskWS->setTitle(inputWS->getTitle());

// set mask from from detectorList
for (auto detectorID : detectorList) {
for (auto detectorID : detectorList)
try {
maskWS->setMasked(detectorID);
} catch (std::invalid_argument const &) {
g_log.warning() << "Detector ID = " << detectorID << " is masked but does not exist in any output spectra\n";
g_log.warning() << "Detector ID = " << detectorID << " is masked but does not exist in any output spectra\n ";
}
}

g_log.information() << maskWS->getNumberMasked() << " spectra are masked\n";
g_log.information() << detectorList.size() << " detectors are masked\n";
Expand Down
20 changes: 6 additions & 14 deletions Framework/Algorithms/test/ExtractMaskTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ExtractMaskTest : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(properties.size(), 4);
if (properties.size() == 4) {
TS_ASSERT_EQUALS(properties[0]->name(), "InputWorkspace");
TS_ASSERT_EQUALS(properties[1]->name(), "InstrumentDonor");
TS_ASSERT_EQUALS(properties[1]->name(), "UngroupDetectors");
TS_ASSERT_EQUALS(properties[2]->name(), "OutputWorkspace");
}
}
Expand Down Expand Up @@ -119,7 +119,7 @@ class ExtractMaskTest : public CxxTest::TestSuite {
AnalysisDataService::Instance().remove(inputName);
}

void test_donor_instrument() {
void test_ungroup_detectors() {
// Create a simple test workspace with grouped detectors
const std::string inputName("inputWS");
auto createWS = AlgorithmFactory::Instance().create("CreateSampleWorkspace", -1);
Expand All @@ -129,11 +129,6 @@ class ExtractMaskTest : public CxxTest::TestSuite {
createWS->setPropertyValue("OutputWorkspace", inputName);
createWS->execute();

auto inputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(inputName);
Workspace_sptr donorWS = inputWS->clone();
const std::string donorName("donorWS");
AnalysisDataService::Instance().add(donorName, donorWS);

const std::string groupName("groupWS");
auto createGroupWS = AlgorithmFactory::Instance().create("CreateGroupingWorkspace", -1);
createGroupWS->initialize();
Expand All @@ -156,11 +151,11 @@ class ExtractMaskTest : public CxxTest::TestSuite {
mask->setPropertyValue("WorkspaceIndexList", "0,2");
mask->execute();

inputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(inputName);
auto inputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(inputName);
TS_ASSERT_EQUALS(inputWS->getNumberHistograms(), 4);

MaskWorkspace_sptr outputWS;
TS_ASSERT_THROWS_NOTHING(outputWS = runExtractMask(inputName, donorName));
TS_ASSERT_THROWS_NOTHING(outputWS = runExtractMask(inputName, true));
TS_ASSERT(outputWS);
if (outputWS) {
TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 16);
Expand All @@ -176,20 +171,17 @@ class ExtractMaskTest : public CxxTest::TestSuite {
}

AnalysisDataService::Instance().remove(inputName);
AnalysisDataService::Instance().remove(donorName);
AnalysisDataService::Instance().remove(groupName);
AnalysisDataService::Instance().remove(outputWS->getName());
}

private:
// The input workspace should be in the analysis data service
MaskWorkspace_sptr runExtractMask(const std::string &inputName, const std::string &donorName = "") {
MaskWorkspace_sptr runExtractMask(const std::string &inputName, const bool ungroupDetectors = false) {
ExtractMask maskExtractor;
maskExtractor.initialize();
maskExtractor.setPropertyValue("InputWorkspace", inputName);
if (!donorName.empty()) {
maskExtractor.setPropertyValue("InstrumentDonor", donorName);
}
maskExtractor.setProperty("UngroupDetectors", ungroupDetectors);
const std::string outputName("masking");
maskExtractor.setPropertyValue("OutputWorkspace", outputName);
maskExtractor.setRethrows(true);
Expand Down
8 changes: 3 additions & 5 deletions docs/source/algorithms/ExtractMask-v1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ link is preserved so that the instrument view functions correctly.
A list of masked detector IDs is also output. Note this contains the detector IDs which
are masked rather than the index or spectrum number.

Using Instrument donor
----------------------
Ungroup Detectors
-----------------

The ``InstrumentDonor`` parameter can be used to specify a workspace from which the ``MaskWorkspace`` creation instrument is based on. The masking will still be copied from the ``InputWorkspace`` but will be applied by matching the detector IDs from the ``InstrumentDonor`` workspace.

You can specify the ``InstrumentDonor`` without the ``InputWorkspace``. In this case, the output ``MaskWorkspace`` will have all spectra unmasked.
If ``UngroupDetectors`` is set to True, the detector IDs are ungrouped. This means that if the input workspace has a grouped detector, the output workspace will have a single spectra for each detector.

Usage
-----
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- A new property ``InstrumentDonor`` was added to :ref:`ExtractMask <algm-ExtractMask>` allowing you to specify which instrument is used when creating the ``MaskWorkspace``.
- A new property ``UngroupDetectors`` was added to :ref:`ExtractMask <algm-ExtractMask>` allowing the output ``MaskWorkspace`` to expand the spectra to individal detectors.

0 comments on commit 76f1984

Please sign in to comment.