Skip to content

Commit

Permalink
Initial version of CopyDetectorMapping algorithm
Browse files Browse the repository at this point in the history
Refs #11125
  • Loading branch information
DanNixon committed Feb 19, 2015
1 parent 2e32c70 commit 98a23b7
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 5 deletions.
Expand Up @@ -53,7 +53,8 @@ class MANTID_API_DLL SpectrumDetectorMapping {
typedef boost::unordered_map<specid_t, std::set<detid_t>> sdmap;

public:
explicit SpectrumDetectorMapping(const MatrixWorkspace *const workspace);
explicit SpectrumDetectorMapping(const MatrixWorkspace *const workspace,
bool useSpecNoIndex = true);
SpectrumDetectorMapping(
const std::vector<specid_t> &spectrumNumbers,
const std::vector<detid_t> &detectorIDs,
Expand All @@ -67,7 +68,10 @@ class MANTID_API_DLL SpectrumDetectorMapping {
std::set<specid_t> getSpectrumNumbers() const;
const std::set<detid_t> &
getDetectorIDsForSpectrumNo(const specid_t spectrumNo) const;
const std::set<detid_t> &
getDetectorIDsForSpectrumIndex(const size_t index) const;
const sdmap &getMapping() const;
bool indexIsSpecNumber() const;

private:
void fillMapFromArray(const specid_t *const spectrumNumbers,
Expand All @@ -77,6 +81,7 @@ class MANTID_API_DLL SpectrumDetectorMapping {
const std::vector<detid_t> &detectorIDs,
const std::vector<detid_t> &ignoreDetIDs);

bool m_indexIsSpecNo;
/// The mapping of a spectrum number to zero or more detector IDs
sdmap m_mapping;
};
Expand Down
8 changes: 6 additions & 2 deletions Code/Mantid/Framework/API/src/MatrixWorkspace.cpp
Expand Up @@ -152,8 +152,12 @@ void MatrixWorkspace::updateSpectraUsing(const SpectrumDetectorMapping &map) {
for (size_t j = 0; j < getNumberHistograms(); ++j) {
auto spec = getSpectrum(j);
try {
spec->setDetectorIDs(
map.getDetectorIDsForSpectrumNo(spec->getSpectrumNo()));
if(map.indexIsSpecNumber())
spec->setDetectorIDs(
map.getDetectorIDsForSpectrumNo(spec->getSpectrumNo()));
else
spec->setDetectorIDs(
map.getDetectorIDsForSpectrumIndex(j));
} catch (std::out_of_range &e) {
// Get here if the spectrum number is not in the map.
spec->clearDetectorIDs();
Expand Down
25 changes: 23 additions & 2 deletions Code/Mantid/Framework/API/src/SpectrumDetectorMapping.cpp
Expand Up @@ -8,15 +8,23 @@ namespace API {
* @throws std::invalid_argument if a null workspace pointer is passed in
*/
SpectrumDetectorMapping::SpectrumDetectorMapping(
const MatrixWorkspace *const workspace) {
const MatrixWorkspace *const workspace,
bool useSpecNoIndex): m_indexIsSpecNo(useSpecNoIndex) {
if (!workspace) {
throw std::invalid_argument(
"SpectrumDetectorMapping: Null workspace pointer passed");
}

for (size_t i = 0; i < workspace->getNumberHistograms(); ++i) {
auto spectrum = workspace->getSpectrum(i);
m_mapping[spectrum->getSpectrumNo()] = spectrum->getDetectorIDs();

int index;
if(m_indexIsSpecNo)
index = spectrum->getSpectrumNo();
else
index = static_cast<int>(i);

m_mapping[index] = spectrum->getDetectorIDs();
}
}

Expand Down Expand Up @@ -93,13 +101,26 @@ std::set<specid_t> SpectrumDetectorMapping::getSpectrumNumbers() const {

const std::set<detid_t> &SpectrumDetectorMapping::getDetectorIDsForSpectrumNo(
const specid_t spectrumNo) const {
if(!m_indexIsSpecNo)
throw std::runtime_error("Indicies are in spectrum index, not number.");
return m_mapping.at(spectrumNo);
}

const std::set<detid_t> &SpectrumDetectorMapping::getDetectorIDsForSpectrumIndex(
const size_t spectrumIndex) const {
if(m_indexIsSpecNo)
throw std::runtime_error("Indicies are in spectrum number, not index.");
return m_mapping.at(static_cast<int>(spectrumIndex));
}

const SpectrumDetectorMapping::sdmap &
SpectrumDetectorMapping::getMapping() const {
return m_mapping;
}

bool SpectrumDetectorMapping::indexIsSpecNumber() const {
return m_indexIsSpecNo;
}

} // namespace API
} // namespace Mantid
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/Algorithms/CMakeLists.txt
Expand Up @@ -52,6 +52,7 @@ set ( SRC_FILES
src/ConvertToMatrixWorkspace.cpp
src/ConvertToPointData.cpp
src/ConvertUnits.cpp
src/CopyDetectorMapping.cpp
src/CopyInstrumentParameters.cpp
src/CopyLogs.cpp
src/CopySample.cpp
Expand Down Expand Up @@ -306,6 +307,7 @@ set ( INC_FILES
inc/MantidAlgorithms/ConvertToMatrixWorkspace.h
inc/MantidAlgorithms/ConvertToPointData.h
inc/MantidAlgorithms/ConvertUnits.h
inc/MantidAlgorithms/CopyDetectorMapping.h
inc/MantidAlgorithms/CopyInstrumentParameters.h
inc/MantidAlgorithms/CopyLogs.h
inc/MantidAlgorithms/CopySample.h
Expand Down Expand Up @@ -571,6 +573,7 @@ set ( TEST_FILES
ConvertToMatrixWorkspaceTest.h
ConvertToPointDataTest.h
ConvertUnitsTest.h
CopyDetectorMappingTest.h
CopyInstrumentParametersTest.h
CopyLogsTest.h
CopySampleTest.h
Expand Down
@@ -0,0 +1,69 @@
#ifndef MANTID_ALGORITHMS_COPYDETECTORMAPPING_H_
#define MANTID_ALGORITHMS_COPYDETECTORMAPPING_H_

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/Algorithm.h"

namespace Mantid {
namespace Algorithms {

/**
Algorithm to copy spectra-detector mapping from one matrix workspace
to another.
@author Dan Nixon
Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
National Laboratory & European Spallation Source
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport CopyDetectorMapping : public API::Algorithm {
public:
/// (Empty) Constructor
CopyDetectorMapping() : API::Algorithm() {}
/// Virtual destructor
virtual ~CopyDetectorMapping() {}
/// Algorithm's name
virtual const std::string name() const { return "CopyDetectorMapping"; }
/// Summary of algorithms purpose
virtual const std::string summary() const {
return "";
}

/// Algorithm's version
virtual int version() const { return (1); }
/// Algorithm's category for identification
virtual const std::string category() const {
return "DataHandling";
}

private:
/// Initialisation code
void init();
/// Execution code
void exec();
};

} // namespace Algorithms
} // namespace Mantid

#endif /*MANTID_ALGORITHMS_COPYDETECTORMAPPING_H_*/
40 changes: 40 additions & 0 deletions Code/Mantid/Framework/Algorithms/src/CopyDetectorMapping.cpp
@@ -0,0 +1,40 @@
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAlgorithms/CopyDetectorMapping.h"
#include "MantidAPI/SpectrumDetectorMapping.h"

namespace Mantid {
namespace Algorithms {

DECLARE_ALGORITHM(CopyDetectorMapping)

using namespace Kernel;
using namespace API;

void CopyDetectorMapping::init() {
declareProperty(
new WorkspaceProperty<>("WorkspaceToMatch", "", Direction::Input));

declareProperty(
new WorkspaceProperty<>("WorkspaceToRemap", "", Direction::InOut));

declareProperty(
new PropertyWithValue<bool>("IndexBySpectrumNumber", false, Direction::Input),
"Will use mapping indexed by spectrum number rather than the default of"
"spectrum index (typically not recommended).");
}

void CopyDetectorMapping::exec() {
MatrixWorkspace_const_sptr wsToMatch = getProperty("WorkspaceToMatch");
MatrixWorkspace_sptr wsToRemap = getProperty("WorkspaceToRemap");
bool indexBySpecNumber = getProperty("IndexBySpectrumNumber");

SpectrumDetectorMapping detMap(wsToMatch.get(), indexBySpecNumber);
wsToRemap->updateSpectraUsing(detMap);

setProperty("WorkspaceToRemap", wsToRemap);
}

} // namespace Algorithms
} // namespace Mantid
63 changes: 63 additions & 0 deletions Code/Mantid/Framework/Algorithms/test/CopyDetectorMappingTest.h
@@ -0,0 +1,63 @@
#ifndef COPYDETECTORMAPPINGTEST_H_
#define COPYDETECTORMAPPINGTEST_H_

#include <cxxtest/TestSuite.h>
#include "MantidAlgorithms/CopyDetectorMapping.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"

using Mantid::MantidVec;

class CopyDetectorMappingTest : public CxxTest::TestSuite
{
public:
void testInit()
{
TS_ASSERT_THROWS_NOTHING( copyMapping.initialize() )
TS_ASSERT( copyMapping.isInitialized() )
}

void testAdd()
{
using namespace Mantid;
using namespace Mantid::API;
using namespace Mantid::Kernel;

auto toMatch = WorkspaceCreationHelper::Create2DWorkspace(10, 10);

// Set the detector map for a spectra in the to match workspace
std::set<detid_t> detIDs;
detIDs.insert(5);
detIDs.insert(9);
detIDs.insert(6);
detIDs.insert(2);
toMatch->getSpectrum(0)->setDetectorIDs(detIDs);

// Add workspaces to ADS
AnalysisDataService::Instance().add("to_match", toMatch);
AnalysisDataService::Instance().add("to_remap", WorkspaceCreationHelper::Create2DWorkspace(10, 10));

// Run algorithm
TS_ASSERT_THROWS_NOTHING( copyMapping.setPropertyValue("WorkspaceToMatch", "to_match") );
TS_ASSERT_THROWS_NOTHING( copyMapping.setPropertyValue("WorkspaceToRemap", "to_remap") );

TS_ASSERT_THROWS_NOTHING( copyMapping.execute() );
TS_ASSERT( copyMapping.isExecuted() );

// Check the detector map in the to remap workspace matches that of the to match workspace
MatrixWorkspace_const_sptr result;
TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast<MatrixWorkspace>
(AnalysisDataService::Instance().retrieve("to_remap")) );
std::set<detid_t> resultDetIDs = result->getSpectrum(0)->getDetectorIDs();
TS_ASSERT( detIDs == resultDetIDs );

// Clean up workspace
AnalysisDataService::Instance().remove("to_match");
AnalysisDataService::Instance().remove("to_remap");
}

private:
Mantid::Algorithms::CopyDetectorMapping copyMapping;

};

#endif /*COPYDETECTORMAPPINGTEST_H_*/

0 comments on commit 98a23b7

Please sign in to comment.