Skip to content

Commit

Permalink
Refs #10623. SeqDomainSpectrumCreator takes masking into account
Browse files Browse the repository at this point in the history
When the detector corresponding to a spectrum of the matrix workspace is masked, it's not added to the domain.
  • Loading branch information
Michael Wedel committed Dec 4, 2014
1 parent 0d23d95 commit 9a553ab
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 9 deletions.
Expand Up @@ -65,6 +65,8 @@ class DLLExport SeqDomainSpectrumCreator : public API::IDomainCreator
void setParametersFromPropertyManager();
void setMatrixWorkspace(API::MatrixWorkspace_sptr matrixWorkspace);

bool histogramIsUsable(size_t i) const;

std::string m_workspacePropertyName;
API::MatrixWorkspace_sptr m_matrixWorkspace;
};
Expand Down
Expand Up @@ -52,11 +52,13 @@ void SeqDomainSpectrumCreator::createDomain(boost::shared_ptr<FunctionDomain> &d

size_t numberOfHistograms = m_matrixWorkspace->getNumberHistograms();
for(size_t i = 0; i < numberOfHistograms; ++i) {
FunctionDomain1DSpectrumCreator *spectrumDomain = new FunctionDomain1DSpectrumCreator;
spectrumDomain->setMatrixWorkspace(m_matrixWorkspace);
spectrumDomain->setWorkspaceIndex(i);
if(histogramIsUsable(i)) {
FunctionDomain1DSpectrumCreator *spectrumDomain = new FunctionDomain1DSpectrumCreator;
spectrumDomain->setMatrixWorkspace(m_matrixWorkspace);
spectrumDomain->setWorkspaceIndex(i);

seqDomain->addCreator(IDomainCreator_sptr(spectrumDomain));
seqDomain->addCreator(IDomainCreator_sptr(spectrumDomain));
}
}

domain.reset(seqDomain);
Expand Down Expand Up @@ -102,22 +104,32 @@ Workspace_sptr SeqDomainSpectrumCreator::createOutputWorkspace(const std::string

MatrixWorkspace_sptr outputWs = boost::dynamic_pointer_cast<MatrixWorkspace>(WorkspaceFactory::Instance().create(m_matrixWorkspace));

// Assign y-values, taking into account masked detectors
for(size_t i = 0; i < seqDomain->getNDomains(); ++i) {
FunctionDomain_sptr localDomain;
FunctionValues_sptr localValues;

seqDomain->getDomainAndValues(i, localDomain, localValues);
function->function(*localDomain, *localValues);

boost::shared_ptr<FunctionDomain1DSpectrum> spectrumDomain = boost::dynamic_pointer_cast<FunctionDomain1DSpectrum>(localDomain);

if(spectrumDomain) {
size_t wsIndex = spectrumDomain->getWorkspaceIndex();

MantidVec& yValues = outputWs->dataY(wsIndex);
for(size_t j = 0; j < yValues.size(); ++j) {
yValues[j] = localValues->getCalculated(j);
}
}
}

// Assign x-values on all histograms
for(size_t i = 0; i < m_matrixWorkspace->getNumberHistograms(); ++i) {
const MantidVec& originalXValue = m_matrixWorkspace->readX(i);
MantidVec& xValues = outputWs->dataX(i);
assert(xValues.size() == originalXValue.size());
MantidVec& yValues = outputWs->dataY(i);

xValues.assign( originalXValue.begin(), originalXValue.end() );
for(size_t j = 0; j < yValues.size(); ++j) {
yValues[j] = localValues->getCalculated(j);
}
}

if(m_manager && !outputWorkspacePropertyName.empty()) {
Expand Down Expand Up @@ -172,6 +184,26 @@ void SeqDomainSpectrumCreator::setMatrixWorkspace(MatrixWorkspace_sptr matrixWor
m_matrixWorkspace = matrixWorkspace;
}

/// Determines whether a spectrum is masked, in case there is no instrument this always returns true.
bool SeqDomainSpectrumCreator::histogramIsUsable(size_t i) const
{
if(!m_matrixWorkspace) {
throw std::invalid_argument("No matrix workspace assigned.");
}

try {
Geometry::IDetector_const_sptr detector = m_matrixWorkspace->getDetector(i);

if(!detector) {
return true;
}

return !detector->isMasked();
} catch(Kernel::Exception::NotFoundError) {
return true;
}
}



} // namespace CurveFitting
Expand Down
104 changes: 104 additions & 0 deletions Code/Mantid/Framework/CurveFitting/test/SeqDomainSpectrumCreatorTest.h
Expand Up @@ -71,6 +71,26 @@ class SeqDomainSpectrumCreatorTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS(seqDomain->size(), 4 * 12);
}

void testHistogramIsUsable()
{
TestableSeqDomainSpectrumCreator creator(NULL, "");

TS_ASSERT_THROWS(creator.histogramIsUsable(0), std::invalid_argument);

// Workspace with 2 histograms, one of which is masked (No. 0)
std::set<int64_t> masked;
masked.insert(0);
creator.setMatrixWorkspace(WorkspaceCreationHelper::Create2DWorkspace123(2, 12, false, masked));

TS_ASSERT(!creator.histogramIsUsable(0));
TS_ASSERT(creator.histogramIsUsable(1));

// No instrument
creator.setMatrixWorkspace(WorkspaceCreationHelper::Create2DWorkspace123(2, 12));
TS_ASSERT(creator.histogramIsUsable(0));
TS_ASSERT(creator.histogramIsUsable(1));
}

void testCreateDomain()
{
TestableSeqDomainSpectrumCreator creator(NULL, "");
Expand All @@ -97,10 +117,45 @@ class SeqDomainSpectrumCreatorTest : public CxxTest::TestSuite
}
}

void testCreateDomainMaskedDetectors()
{
TestableSeqDomainSpectrumCreator creator(NULL, "");

// Workspace with 4 histograms, one of which is masked (No. 2)
std::set<int64_t> masked;
masked.insert(2);
creator.setMatrixWorkspace(WorkspaceCreationHelper::Create2DWorkspace123(4, 12, false, masked));

FunctionDomain_sptr domain;
FunctionValues_sptr values;

creator.createDomain(domain, values);

boost::shared_ptr<SeqDomain> seqDomain = boost::dynamic_pointer_cast<SeqDomain>(domain);

// One less than the created workspace
TS_ASSERT_EQUALS(seqDomain->getNDomains(), 3);
for(size_t i = 0; i < seqDomain->getNDomains(); ++i) {
FunctionDomain_sptr localDomain;
FunctionValues_sptr localValues;

seqDomain->getDomainAndValues(i, localDomain, localValues);

boost::shared_ptr<FunctionDomain1DSpectrum> localSpectrumDomain = boost::dynamic_pointer_cast<FunctionDomain1DSpectrum>(localDomain);
TS_ASSERT(localSpectrumDomain);

TS_ASSERT_EQUALS(localSpectrumDomain->size(), 12);

// Make sure we never find 2 (masking)
TS_ASSERT_DIFFERS(localSpectrumDomain->getWorkspaceIndex(), 2);
}
}

void testCreateOutputWorkspace()
{
double slope = 2.0;
// all x values are 1.0

MatrixWorkspace_sptr matrixWs = WorkspaceCreationHelper::Create2DWorkspace123(4, 12);

TestableSeqDomainSpectrumCreator creator(NULL, "");
Expand Down Expand Up @@ -135,6 +190,55 @@ class SeqDomainSpectrumCreatorTest : public CxxTest::TestSuite
}
}

void testCreateOutputWorkspaceMasked()
{
double slope = 2.0;
// all x values are 1.0
// Mask one histogram (No. 2)
std::set<int64_t> masked;
masked.insert(2);
MatrixWorkspace_sptr matrixWs = WorkspaceCreationHelper::Create2DWorkspace123(4, 12, false, masked);

TestableSeqDomainSpectrumCreator creator(NULL, "");
creator.setMatrixWorkspace(matrixWs);

FunctionDomain_sptr domain;
FunctionValues_sptr values;

creator.createDomain(domain, values);

IFunction_sptr testFunction(new SeqDomainCreatorTestFunction);
testFunction->initialize();
testFunction->setParameter("Slope", slope);

Workspace_sptr outputWs = creator.createOutputWorkspace("", testFunction, domain, values);

MatrixWorkspace_sptr outputWsMatrix = boost::dynamic_pointer_cast<MatrixWorkspace>(outputWs);
TS_ASSERT(outputWsMatrix);

// Still has to be the same number of histograms.
TS_ASSERT_EQUALS(outputWsMatrix->getNumberHistograms(), matrixWs->getNumberHistograms());

// Spectrum 0: 0 + 2 * 1 -> All y-values should be 2
// Spectrum 1: 1 + 2 * 1 -> All y-values should be 3...etc.
for(size_t i = 0; i < outputWsMatrix->getNumberHistograms(); ++i) {
const std::vector<double> &x = outputWsMatrix->readX(i);
const std::vector<double> &y = outputWsMatrix->readY(i);

for(size_t j = 0; j < x.size(); ++j) {
TS_ASSERT_EQUALS(x[j], 1.0);

// If detector is not masked, there should be values, otherwise 0.
if(!outputWsMatrix->getDetector(i)->isMasked()) {
TS_ASSERT_EQUALS(y[j], static_cast<double>(i) + slope * x[j]);
} else {
TS_ASSERT_EQUALS(y[j], 0.0);
}
}
}

}

void testFit()
{
double slope = 2.0;
Expand Down

0 comments on commit 9a553ab

Please sign in to comment.