Unverified Commit 16969e53 authored by Gigg, Martyn Anthony's avatar Gigg, Martyn Anthony Committed by GitHub
Browse files

Merge pull request #28562 from mantidproject/27626_combine_peak_mod_vector

parents 7f1afbc7 039b15e4
......@@ -7,6 +7,7 @@
#include "MantidCrystal/CombinePeaksWorkspaces.h"
#include "MantidAPI/Sample.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/EnabledWhenProperty.h"
......@@ -85,6 +86,63 @@ void CombinePeaksWorkspaces::exec() {
Progress progress(this, 0.0, 1.0, rhsPeaks.size());
// Combine modulation vectors
// Currently, the lattice can only support up to 3 modulation vectors. If any
// more than that are combined, a warning is shown and the LHS values are
// used.
try {
std::vector<Kernel::V3D> rhsModVectors;
std::vector<Kernel::V3D> lhsModVectors;
// Collect modulation vectors for both workspaces.
for (int i = 0; i < 3; ++i) { // Currently contains up to 3 vectors.
const auto modVecR =
RHSWorkspace->sample().getOrientedLattice().getModVec(i);
// Each vector contains 3 values, check that at least one is not 0.
if (!(modVecR[0] == 0 && modVecR[1] == 0 && modVecR[2] == 0)) {
rhsModVectors.push_back(modVecR);
}
const auto modVecL =
LHSWorkspace->sample().getOrientedLattice().getModVec(i);
if (!(modVecL[0] == 0 && modVecL[1] == 0 && modVecL[2] == 0)) {
lhsModVectors.push_back(modVecL);
}
}
// Add only unique mod vectors from the rhs list to the lhs list.
std::remove_copy_if(
rhsModVectors.begin(), rhsModVectors.end(),
back_inserter(lhsModVectors), [lhsModVectors](Kernel::V3D modVec) {
return lhsModVectors.end() !=
std::find(lhsModVectors.begin(), lhsModVectors.end(), modVec);
});
// Hard limit of 3 mod vectors until PeaksWorkspace is refactored.
if (lhsModVectors.size() > 3) {
g_log.warning("There are too many modulation vectors. Using vectors from "
"LHSWorkspace");
} else {
// This is horrible, but setting mod vectors has to be done by 3 separate
// methods.
for (size_t i = 0; i < lhsModVectors.size(); ++i) {
if (i == 0) {
output->mutableSample().getOrientedLattice().setModVec1(
lhsModVectors[i]);
} else if (i == 1) {
output->mutableSample().getOrientedLattice().setModVec2(
lhsModVectors[i]);
} else if (i == 2) {
output->mutableSample().getOrientedLattice().setModVec3(
lhsModVectors[i]);
}
}
}
} catch (std::runtime_error &e) {
g_log.error() << "Failed to combine modulation vectors with the following "
"error: "
<< e.what();
}
// If not checking for matching peaks, then it's easy...
if (!CombineMatchingPeaks) {
// Loop over the peaks in the second workspace, appending each one to the
......
......@@ -8,8 +8,11 @@
#include <cxxtest/TestSuite.h>
#include "MantidAPI/Sample.h"
#include "MantidCrystal/CombinePeaksWorkspaces.h"
#include "MantidCrystal/PredictFractionalPeaks.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
using Mantid::Crystal::CombinePeaksWorkspaces;
......@@ -189,4 +192,160 @@ public:
// Remove workspace from the data service.
AnalysisDataService::Instance().remove(outWSName);
}
void test_modulation_vectors_are_combined() {
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Crystal;
PeaksWorkspace_sptr peaksWs =
WorkspaceCreationHelper::createPeaksWorkspace(3, true);
Mantid::Crystal::PredictFractionalPeaks predictAlg;
predictAlg.initialize();
predictAlg.setProperty("Peaks", peaksWs);
predictAlg.setProperty("ModVector1", "0.5, 0, 0.5");
predictAlg.setProperty("FracPeaks", "frac_vec1");
predictAlg.setProperty("MaxOrder", 1);
predictAlg.execute();
predictAlg.initialize();
predictAlg.setProperty("Peaks", peaksWs);
predictAlg.setProperty("ModVector1", "-0.5, -0.5, -0.5");
predictAlg.setProperty("FracPeaks", "frac_vec2");
predictAlg.setProperty("MaxOrder", 1);
predictAlg.execute();
CombinePeaksWorkspaces alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LHSWorkspace", "frac_vec1"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("RHSWorkspace", "frac_vec2"));
TS_ASSERT_THROWS_NOTHING(
alg.setPropertyValue("OutputWorkspace", "frac_vec_1and2"));
TS_ASSERT_THROWS_NOTHING(alg.execute());
IPeaksWorkspace_const_sptr outWs;
TS_ASSERT_THROWS_NOTHING(
outWs = AnalysisDataService::Instance().retrieveWS<IPeaksWorkspace>(
"frac_vec_1and2"));
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[0], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[2], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[0],
-0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[1],
-0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[2],
-0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[0], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[2], 0);
}
void test_lhs_modulation_vectors_are_used_when_too_many() {
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Crystal;
PeaksWorkspace_sptr peaksWs =
WorkspaceCreationHelper::createPeaksWorkspace(3, true);
Mantid::Crystal::PredictFractionalPeaks predictAlg;
predictAlg.initialize();
predictAlg.setProperty("Peaks", peaksWs);
predictAlg.setProperty("ModVector1", "0.5, 0, 0.5");
predictAlg.setProperty("ModVector2", "0.5, 0, 0.5");
predictAlg.setProperty("ModVector3", "0.5, 0, 0.5");
predictAlg.setProperty("FracPeaks", "frac_vec1");
predictAlg.setProperty("MaxOrder", 1);
predictAlg.execute();
predictAlg.initialize();
predictAlg.setProperty("Peaks", peaksWs);
predictAlg.setProperty("ModVector1", "-0.5, -0.5, -0.5");
predictAlg.setProperty("FracPeaks", "frac_vec2");
predictAlg.setProperty("MaxOrder", 1);
predictAlg.execute();
CombinePeaksWorkspaces alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LHSWorkspace", "frac_vec1"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("RHSWorkspace", "frac_vec2"));
TS_ASSERT_THROWS_NOTHING(
alg.setPropertyValue("OutputWorkspace", "frac_vec_1and2"));
TS_ASSERT_THROWS_NOTHING(alg.execute());
IPeaksWorkspace_const_sptr outWs;
TS_ASSERT_THROWS_NOTHING(
outWs = AnalysisDataService::Instance().retrieveWS<IPeaksWorkspace>(
"frac_vec_1and2"));
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[0], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[2], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[0], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[2], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[0], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[2], 0.5);
}
void test_duplicate_workspaces_are_not_combined() {
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Crystal;
PeaksWorkspace_sptr peaksWs =
WorkspaceCreationHelper::createPeaksWorkspace(3, true);
Mantid::Crystal::PredictFractionalPeaks predictAlg;
predictAlg.initialize();
predictAlg.setProperty("Peaks", peaksWs);
predictAlg.setProperty("ModVector1", "0.5, 0, 0.5");
predictAlg.setProperty("ModVector2", "0.5, 0, 0.5");
predictAlg.setProperty("FracPeaks", "frac_vec1");
predictAlg.setProperty("MaxOrder", 1);
predictAlg.execute();
predictAlg.initialize();
predictAlg.setProperty("Peaks", peaksWs);
predictAlg.setProperty("ModVector1", "0.5, 0, 0.5");
predictAlg.setProperty("FracPeaks", "frac_vec2");
predictAlg.setProperty("MaxOrder", 1);
predictAlg.execute();
CombinePeaksWorkspaces alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize());
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LHSWorkspace", "frac_vec1"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("RHSWorkspace", "frac_vec2"));
TS_ASSERT_THROWS_NOTHING(
alg.setPropertyValue("OutputWorkspace", "frac_vec_1and2"));
TS_ASSERT_THROWS_NOTHING(alg.execute());
IPeaksWorkspace_const_sptr outWs;
TS_ASSERT_THROWS_NOTHING(
outWs = AnalysisDataService::Instance().retrieveWS<IPeaksWorkspace>(
"frac_vec_1and2"));
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[0], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(0)[2], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[0], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(1)[2], 0.5);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[0], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[1], 0);
TS_ASSERT_EQUALS(outWs->sample().getOrientedLattice().getModVec(2)[2], 0);
}
};
......@@ -30,6 +30,9 @@ Improvements
Single Crystal Diffraction
--------------------------
Improvements
^^^^^^^^^^^^
- :ref:`CombinePeaksWorkspaces <algm-CombinePeaksWorkspaces>` now combines the modulation vectors present in the two workspaces, provided the total number of vectors is less than 3.
- New instrument geometry for MaNDi instrument at SNS
Imaging
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment