Newer
Older
#include "MantidKernel/System.h"
#include "MantidKernel/ListValidator.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidDataObjects/CoordTransformDistance.h"
#include "MantidDataObjects/MDEventFactory.h"
#include "MantidMDAlgorithms/IntegratePeaksMD.h"
#include "MantidMDAlgorithms/CentroidPeaksMD2.h"
using Mantid::DataObjects::PeaksWorkspace;
namespace Mantid {
namespace MDAlgorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CentroidPeaksMD2)
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
using namespace Mantid::DataObjects;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//----------------------------------------------------------------------------------------------
/** Constructor
*/
CentroidPeaksMD2::CentroidPeaksMD2() {}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
CentroidPeaksMD2::~CentroidPeaksMD2() {}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CentroidPeaksMD2::init() {
declareProperty(new WorkspaceProperty<IMDEventWorkspace>("InputWorkspace", "",
Direction::Input),
"An input MDEventWorkspace.");
std::vector<std::string> propOptions;
propOptions.push_back("Q (lab frame)");
propOptions.push_back("Q (sample frame)");
propOptions.push_back("HKL");
declareProperty(
new PropertyWithValue<double>("PeakRadius", 1.0, Direction::Input),
"Fixed radius around each peak position in which to calculate the "
"centroid.");
declareProperty(new WorkspaceProperty<PeaksWorkspace>("PeaksWorkspace", "",
Direction::Input),
"A PeaksWorkspace containing the peaks to centroid.");
declareProperty(
new WorkspaceProperty<PeaksWorkspace>("OutputWorkspace", "",
Direction::Output),
"The output PeaksWorkspace will be a copy of the input PeaksWorkspace "
"with the peaks' positions modified by the new found centroids.");
}
//----------------------------------------------------------------------------------------------
/** Integrate the peaks of the workspace using parameters saved in the algorithm
* class
* @param ws :: MDEventWorkspace to integrate
*/
template <typename MDE, size_t nd>
void CentroidPeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) {
if (nd != 3)
throw std::invalid_argument("For now, we expect the input MDEventWorkspace "
"to have 3 dimensions only.");
/// Peak workspace to centroid
Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS =
getProperty("PeaksWorkspace");
/// Output peaks workspace, create if needed
Mantid::DataObjects::PeaksWorkspace_sptr peakWS =
getProperty("OutputWorkspace");
if (peakWS != inPeakWS)
peakWS.reset(inPeakWS->clone().release());
int CoordinatesToUse = ws->getSpecialCoordinateSystem();
/// Radius to use around peaks
double PeakRadius = getProperty("PeakRadius");
// cppcheck-suppress syntaxError
for (int i = 0; i < int(peakWS->getNumberPeaks()); ++i) {
double detectorDistance = p.getL2();
// Get the peak center as a position in the dimensions of the workspace
V3D pos;
if (CoordinatesToUse == 1) //"Q (lab frame)"
pos = p.getQLabFrame();
else if (CoordinatesToUse == 2) //"Q (sample frame)"
pos = p.getQSampleFrame();
else if (CoordinatesToUse == 3) //"HKL"
pos = p.getHKL();
// Build the sphere transformation
bool dimensionsUsed[nd];
coord_t center[nd];
for (size_t d = 0; d < nd; ++d) {
dimensionsUsed[d] = true; // Use all dimensions
center[d] = static_cast<coord_t>(pos[d]);
}
CoordTransformDistance sphere(nd, center, dimensionsUsed);
// Initialize the centroid to 0.0
signal_t signal = 0;
coord_t centroid[nd];
ws->getBox()->centroidSphere(
sphere, static_cast<coord_t>(PeakRadius * PeakRadius), centroid,
signal);
if (signal != 0.0) {
for (size_t d = 0; d < nd; d++)
centroid[d] /= static_cast<coord_t>(signal);
V3D vecCentroid(centroid[0], centroid[1], centroid[2]);
// Save it back in the peak object, in the dimension specified.
try {
if (CoordinatesToUse == 1) //"Q (lab frame)"
{
p.setQLabFrame(vecCentroid, detectorDistance);
p.findDetector();
} else if (CoordinatesToUse == 2) //"Q (sample frame)"
{
p.setQSampleFrame(vecCentroid, detectorDistance);
p.findDetector();
} else if (CoordinatesToUse == 3) //"HKL"
{
p.setHKL(vecCentroid);
}
} catch (std::exception &e) {
g_log.warning() << "Error setting Q or HKL" << std::endl;
g_log.warning() << e.what() << std::endl;
}
g_log.information() << "Peak " << i << " at " << pos << ": signal "
<< signal << ", centroid " << vecCentroid << " in "
<< CoordinatesToUse << std::endl;
} else {
g_log.information() << "Peak " << i << " at " << pos
<< " had no signal, and could not be centroided."
<< std::endl;
}
}
// Save the output
setProperty("OutputWorkspace", peakWS);
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void CentroidPeaksMD2::exec() {
inWS = getProperty("InputWorkspace");
CALL_MDEVENT_FUNCTION3(this->integrate, inWS);
}
} // namespace DataObjects