Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group workspace masking error in MaskDetectors #18417

Merged
merged 13 commits into from
Jan 23, 2017

Conversation

samueljackson92
Copy link
Contributor

@samueljackson92 samueljackson92 commented Jan 12, 2017

See the two scripts in the bug report for examples of how to reproduce the issue.

To test:
Two cases to check that didn't work before:

  • Check that a workspace (NOT a masked workspace) where
    • masked workspace has a number of spectra == the number of detectors in the input workspace
    • masked workspace has a number of spectra > the number of spectra in the input workspace
  • Check the above works when specifying a StartWorkspaceIndex and EndWorkspaceIndex
  • Code review.

Fixes #14793 .


Reviewer

Please comment on the following (full description):

Code Review
  • Is the code of an acceptable quality?
  • Does the code conform to the coding standards? Is it well structured with small focussed classes/methods/functions?
  • Are there unit/system tests in place? Are the unit tests small and test the a class in isolation?
  • If there are changes in the release notes then do they describe the changes appropriately?
Functional Tests
  • Do changes function as described? Add comments below that describe the tests performed?

  • How do the changes handle unexpected situations, e.g. bad input?

  • Has the relevant documentation been added/updated?

  • Is user-facing documentation written in a user-friendly manner?

  • Has developer documentation been updated if required?

  • Does everything look good? Comment with the ship it emoji but don't merge. A member of @mantidproject/gatekeepers will take care of it.

In some cases the hardware grouping can cause a workspace to have more
than on detector per spectrum. When we have a mask where each spectrum
corresponds to a detector and the workspace to be masked has a smaller
number of spectra we should append the indicies to the detectorList.
This adds the ability to pass a workspace which is not a mask workspace
but a list of spectra corresponding to detectors to be masked. This is
useful in the case where the number of spectra do not match but the
number of detectors do, i.e. when some grouping has been applied to the
workspace.
@samueljackson92 samueljackson92 added the Framework Issues and pull requests related to components in the Framework label Jan 12, 2017
@samueljackson92 samueljackson92 added this to the Release 3.9 milestone Jan 12, 2017
@NickDraper NickDraper self-assigned this Jan 16, 2017
Copy link
Contributor

@NickDraper NickDraper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#we also need some changes to MaskDetectors.rst to make it explicit what will happen when passing in a MaskedWorkspace, as there are several options.

<< prevMasking->getNumberHistograms()
<< " histograms. \n";
throw std::runtime_error("Size mismatch between two input workspaces.");
if (nHist > WS->getNumberHistograms()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if does not fit the comment above it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to consider what should happen if it is <, probably handle it this way

if (instrument && maskInstrument &&
maskInstrument->getNumberDetectors() ==
instrument->getNumberDetectors() &&
nHist == instrument->getNumberDetectors()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should have the number of detectors == nhist restriction.

auto maskInstrument = prevMasking->getInstrument();
if (instrument && maskInstrument &&
maskInstrument->getNumberDetectors() ==
instrument->getNumberDetectors() &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the number of detectors in the instruments do not match we should just warn but continue, not refuse.

appendToDetectorListFromWS(detectorList, WS, prevMasking,
ranges_info);
} else {
// We have more spectra in the mask than in the workspace and we also
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we should only refuse if one of the WS's does not have an instrument.

throw std::runtime_error(
"Size mismatch between two input workspaces.");
}
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This else should be more explicit of when it is being called (when workspace indices match)


for (size_t i = 0; i < maskWs->getNumberHistograms(); ++i) {
if (maskWs->y(i)[0] == 0) {
auto id = maskWs->getDetector(i)->getID();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a methods that will return a vector of all of the IDs (i think getIDs) that will allow this to work for none 1-1 mapping.

@samueljackson92
Copy link
Contributor Author

@NickDraper Please review again when you have time.

if (nHist == WS->getNumberHistograms()) {
appendToIndexListFromWS(indexList, maskWs, rangeInfo);
// Check they both have instrument and then use detector based masking
} else if (instrument && maskInstrument) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should check the instrument->name, not pointer address, but it also should only log as warning if they do not match, still go ahead and apply the masking.

g_log.warning() << "Number of detectors does not match between "
"mask workspace and input workspace";

appendToDetectorListFromWS(detectorList, WS, maskWs, rangeInfo);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should log at info that the masking is being applied by detector ids

// Check the provided workspace has the same number of spectra as the
// input, if so assume index list
if (nHist == WS->getNumberHistograms()) {
appendToIndexListFromWS(indexList, maskWs, rangeInfo);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should log at info that the masking is being applied by workspace index

forceDetIDs) {
extractMaskedWSDetIDs(detectorList, maskWs);
} else {
appendToIndexListFromMaskWS(indexList, maskWs, rangeInfo);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should log at info that the masking is being applied by workspace index

bool forceDetIDs = getProperty("ForceInstrumentMasking");
if (maskWs->getNumberHistograms() != WS->getNumberHistograms() ||
forceDetIDs) {
extractMaskedWSDetIDs(detectorList, maskWs);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should log at info that the masking is being applied by detector ids

@NickDraper
Copy link
Contributor

Tested using the following script

wsUnmasked = CreateSampleWorkspace()
wsMasked = CloneWorkspace(wsUnmasked)

def GeneratePattern(ws,noToGroup):
    groupingPattern = []
    for i in range(0,ws.getNumberHistograms(),noToGroup):
         groupingPattern.append(str(i) + '+' + str(i+1))
    groupingPatternString = ", ".join(groupingPattern)
    return groupingPatternString
    
wsGrouped2 = GroupDetectors(wsUnmasked,GroupingPattern = GeneratePattern(wsUnmasked,2))

# Define an infinite cylinder with its axis parallel to the Z-axis
# and the radius of 0.04
shapeXML = \
"""
<infinite-cylinder id="A" >
    <centre x="0" y="0" z="0" />
    <axis x="0" y="0" z="1" />
    <radius val="0.04" />
</infinite-cylinder>
"""
# Mask all detectors inside this cylinder
wsMasked = CloneWorkspace(wsUnmasked)
MaskDetectorsInShape( wsMasked, shapeXML )


wsGrouped2Masked = CloneWorkspace(wsGrouped2)
MaskDetectorsInShape( wsGrouped2Masked, shapeXML )


wsTestGrouped2MaskCopy = CloneWorkspace(wsUnmasked)
MaskDetectors(wsTestGrouped2MaskCopy,MaskedWorkspace=wsGrouped2Masked)

wsTestGroupedMaskCopy = CloneWorkspace(wsGrouped2)
MaskDetectors(wsTestGroupedMaskCopy,MaskedWorkspace=wsMasked)

Then the instrument views of the workspaces were compared.

Seems to work well :shipit:

@martyngigg martyngigg self-assigned this Jan 23, 2017
@martyngigg
Copy link
Member

@samueljackson92 There was a trivial conflict in the release notes. I've resolved it in the browser and I'll merge this assuming the builds pass.

@martyngigg
Copy link
Member

Failing Windows test is unrelated slice viewer failure.

@martyngigg martyngigg merged commit 6a3f2b1 into master Jan 23, 2017
@martyngigg martyngigg deleted the 14793_group_masking_error branch January 23, 2017 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Framework Issues and pull requests related to components in the Framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants