Skip to content

Commit

Permalink
refs #4150 SmoothNeighbours updated.
Browse files Browse the repository at this point in the history
 Can now speicify that SmoothNeighbours ignores or includes masked detectors. Appears to work from instrument view. This is an intermediate step. Next thing to do will be to include union criteria for limiting searching by radius as well as by number of neighbours.
  • Loading branch information
OwenArnold committed Nov 25, 2011
1 parent 0209d42 commit 6f75115
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 18 deletions.
2 changes: 2 additions & 0 deletions Code/Mantid/Framework/API/src/MatrixWorkspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,8 @@ namespace Mantid
{
}
}
//If masking has occured, the NearestNeighbours map will be out of date must be rebuilt.
this->rebuildNearestNeighbours();
}

//----------------------------------------------------------------------------------------------------
Expand Down
16 changes: 14 additions & 2 deletions Code/Mantid/Framework/Algorithms/src/SmoothNeighbours.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ void SmoothNeighbours::init()
"Alternative to providing the radius. The default is 8.");
setPropertySettings("NumberOfNeighbours", new EnabledWhenProperty(this, "ProvideRadius", IS_NOT_DEFAULT));

declareProperty("IgnoreMaskedDetectors", true, "If true, do not consider masked detectors in the NN search.");
setPropertySettings("IgnoreMaskedDetectors", new EnabledWhenProperty(this, "ProvideRadius", IS_NOT_DEFAULT));

declareProperty("WeightedSum", true,
"Adjust the weight of neighboring pixels when summing them, based on their distance.");
setPropertySettings("WeightedSum", new EnabledWhenProperty(this, "ProvideRadius", IS_DEFAULT)); //Weighted sum needs the radius for the calculation.
Expand Down Expand Up @@ -269,6 +272,12 @@ void SmoothNeighbours::findNeighboursRectangular()
*/
void SmoothNeighbours::findNeighboursUbiqutious()
{
/*
This will cause the Workspace to rebuild the nearest neighbours map, so that we can pick-up any of the properties specified
for this algorithm in the constructor for the NearestNeighboursObject.
*/
inWS->rebuildNearestNeighbours();

m_prog->resetNumSteps(inWS->getNumberHistograms(), 0.2, 0.5);
this->progress(0.2, "Building Neighbour Map");

Expand All @@ -280,6 +289,8 @@ void SmoothNeighbours::findNeighboursUbiqutious()
//Get the use radius flag.
bool useRadius = getProperty("ProvideRadius");
int nNeighbours = getProperty("NumberOfNeighbours");
bool ignoreMaskedDetectors = getProperty("IgnoreMaskedDetectors");

IDetector_const_sptr det;
// Go through every input workspace pixel
for (size_t wi=0; wi < inWS->getNumberHistograms(); wi++)
Expand All @@ -289,6 +300,7 @@ void SmoothNeighbours::findNeighboursUbiqutious()
{
det = inWS->getDetector(wi);
if( det->isMonitor() ) continue; //skip monitor
if( det->isMasked() ) continue; //skip masked detectors
}
catch(Kernel::Exception::NotFoundError&)
{
Expand All @@ -299,11 +311,11 @@ void SmoothNeighbours::findNeighboursUbiqutious()
std::map<specid_t, double> neighbSpectra;
if(useRadius)
{
neighbSpectra = inWS->getNeighbours(inSpec, Radius);
neighbSpectra = inWS->getNeighbours(inSpec, Radius, ignoreMaskedDetectors);
}
else
{
neighbSpectra = inWS->getNeighboursExact(inSpec, nNeighbours);
neighbSpectra = inWS->getNeighboursExact(inSpec, nNeighbours, ignoreMaskedDetectors);
}
// Force the central pixel to always be there
// There seems to be a bug in nearestNeighbours, returns distance != 0.0 for the central pixel. So we force distance = 0
Expand Down
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/Algorithms/test/SmoothNeighboursTest.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SmoothNeighboursTEST_H_
#define SmoothNeighboursTEST_H_

#include "MantidGeometry/Instrument/INearestNeighboursFactory.h"
#include "MantidAlgorithms/SmoothNeighbours.h"
#include "MantidAlgorithms/CheckWorkspacesMatch.h"
#include <cxxtest/TestSuite.h>
Expand All @@ -24,6 +25,7 @@ using namespace Mantid::Algorithms;

class SmoothNeighboursTest : public CxxTest::TestSuite
{

public:


Expand Down Expand Up @@ -145,6 +147,7 @@ class SmoothNeighboursTest : public CxxTest::TestSuite
alg.setProperty("WeightedSum", false);
alg.setProperty("ProvideRadius", false);
alg.setProperty("NumberOfNeighbours", 8);
alg.setProperty("IgnoreMaskedDetectors", true);
TS_ASSERT_THROWS_NOTHING( alg.execute(); );
TS_ASSERT( alg.isExecuted() );

Expand Down
6 changes: 5 additions & 1 deletion Code/Mantid/Framework/DataHandling/src/MaskDetectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,11 @@ void MaskDetectors::exec()
//Also clear the MRU for event workspaces.
eventWS->clearMRU();
}

/*
This rebuild request call, gives the workspace the opportunity to rebuild the nearest neighbours map
and therfore pick up any detectors newly masked with this algorithm.
*/
WS->rebuildNearestNeighbours();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace Mantid
public:
/// Constructor with an instrument and a spectra map
NearestNeighbours(boost::shared_ptr<const Instrument> instrument,
const ISpectraDetectorMap & spectraMap, bool ignoreMasked=false);
const ISpectraDetectorMap & spectraMap, bool ignoreMasked=true);
/// Default (empty) destructor
virtual ~NearestNeighbours() {};

Expand All @@ -68,12 +68,24 @@ namespace Mantid
// Neighbouring spectra by
std::map<specid_t, double> neighbours(const specid_t spectrum, bool force, const int numberofneighbours=8) const;

protected:

/// Get the spectra associated with all in the instrument
std::map<specid_t, IDetector_const_sptr>
getSpectraDetectors(boost::shared_ptr<const Instrument> instrument,
const ISpectraDetectorMap & spectraMap);

/// A pointer the the instrument
boost::shared_ptr<const Instrument> m_instrument;
/// A reference to the spectra map
const ISpectraDetectorMap & m_spectraMap;

private:
/// typedef for Graph object used to hold the calculated information
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
boost::property<boost::vertex_name_t, int64_t>,
boost::property<boost::edge_name_t, double>
> Graph;
> Graph;
/// Vertex descriptor object for Graph
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
/// map object of int to Graph Vertex descriptor
Expand All @@ -84,16 +96,6 @@ namespace Mantid
void build(const int noNeighbours);
/// Query the graph for the default number of nearest neighbours to specified detector
std::map<specid_t, double> defaultNeighbours(const specid_t spectrum) const;

/// Get the spectra associated with all in the instrument
std::map<specid_t, IDetector_const_sptr>
getSpectraDetectors(boost::shared_ptr<const Instrument> instrument,
const ISpectraDetectorMap & spectraMap);

/// A pointer the the instrument
boost::shared_ptr<const Instrument> m_instrument;
/// A reference to the spectra map
const ISpectraDetectorMap & m_spectraMap;
/// The current number of nearest neighbours
int m_noNeighbours;
/// The largest value of the distance to a nearest neighbour
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ namespace Mantid
std::vector<int> detIDs = spectraMap.getDetectors(spectrumNo);
IDetector_const_sptr det = instrument->getDetectorG(detIDs);
//Always ignore monitors and ignore masked detectors if requested.
bool doSkipMasked = m_bIgnoreMaskedDetectors && det->isMasked();
if( !det->isMonitor() || !doSkipMasked )
bool heedMasking = !m_bIgnoreMaskedDetectors && det->isMasked();
if( !det->isMonitor() && !heedMasking )
{
spectra.insert(std::make_pair(spectrumNo, det));
}
Expand Down
52 changes: 51 additions & 1 deletion Code/Mantid/Framework/Geometry/test/NearestNeighboursTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ using Mantid::Kernel::V3D;
//=====================================================================================
class NearestNeighboursTest : public CxxTest::TestSuite
{

private:

/// Helper type giving access to protected methods. Makes testing of NN internals possible.
class ExposedNearestNeighbours : public Mantid::Geometry::NearestNeighbours
{
public:
ExposedNearestNeighbours(boost::shared_ptr<const Instrument> instrument,
const ISpectraDetectorMap & spectraMap, bool ignoreMasked=false) : NearestNeighbours(instrument, spectraMap, ignoreMasked){}

//Direct access to intermdiate spectra detectors
std::map<specid_t, IDetector_const_sptr> getSpectraDetectors()
{
return NearestNeighbours::getSpectraDetectors(m_instrument, m_spectraMap);
}
};

public:

void doTestWithNeighbourNumbers(int actualNeighboursNumber, int expectedNeighboursNumber)
Expand Down Expand Up @@ -149,6 +166,40 @@ class NearestNeighboursTest : public CxxTest::TestSuite

}

void testIgnoreAndApplyMasking()
{
Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(ComponentCreationHelper::createTestInstrumentCylindrical(2));
boost::scoped_ptr<ISpectraDetectorMap> spectramap(new OneToOneSpectraDetectorMap(1, 18));

// Default parameter map.
ParameterMap_sptr pmap(new ParameterMap());

//Mask the first 5 detectors
for(size_t i = 1; i < 3; i++)
{
if ( const Geometry::ComponentID det = instrument->getDetector(spectramap->getDetectors(i)[0])->getComponentID() )
{
pmap->addBool(det,"masked",true);
}
}

// Parameterized instrument
Instrument_sptr m_instrument(new Instrument(instrument, pmap));

IDetector_const_sptr det = m_instrument->getDetector(spectramap->getDetectors(1)[0]);

// Create the NearestNeighbours object directly. Ignore any masking.
ExposedNearestNeighbours ignoreMaskedNN(m_instrument, *spectramap, true);
// Create the NearestNeighbours object directly. Account for any masking.
ExposedNearestNeighbours accountForMaskedNN(m_instrument, *spectramap, false);

size_t sizeWithoutMasking = ignoreMaskedNN.getSpectraDetectors().size();
size_t sizeWithMasking = accountForMaskedNN.getSpectraDetectors().size();

TSM_ASSERT_EQUALS("Without masking should get 18 spectra back", 18, sizeWithoutMasking);
TSM_ASSERT("Must have less detectors available after applying masking", sizeWithoutMasking > sizeWithMasking);
}

};

//=====================================================================================
Expand Down Expand Up @@ -209,7 +260,6 @@ class NearestNeighboursTestPerformance : public CxxTest::TestSuite
nn.neighbours(1, true, 8.0);
}
}

};


Expand Down

0 comments on commit 6f75115

Please sign in to comment.