Mantid
Loading...
Searching...
No Matches
PeakAlgorithmHelpers.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
12#include "MantidKernel/V3D.h"
13
20
21namespace Mantid::Crystal {
22
26double qConventionFactor(const std::string &convention) {
27 if (convention == "Crystallography") {
28 return -1.0;
29 }
30 return 1.0;
31}
32
36double qConventionFactor() { return qConventionFactor(ConfigService::Instance().getString("Q.convention")); }
37
44 auto mustBeLengthThree = std::make_shared<ArrayLengthValidator<double>>(3);
45 alg->declareProperty(
46 std::make_unique<ArrayProperty<double>>(ModulationProperties::ModVector1, "0.0,0.0,0.0", mustBeLengthThree),
47 "Modulation Vector 1: dh, dk, dl");
48 alg->declareProperty(
49 std::make_unique<ArrayProperty<double>>(ModulationProperties::ModVector2, "0.0,0.0,0.0", mustBeLengthThree),
50 "Modulation Vector 2: dh, dk, dl");
51 alg->declareProperty(
52 std::make_unique<ArrayProperty<double>>(ModulationProperties::ModVector3, "0.0,0.0,0.0", mustBeLengthThree),
53 "Modulation Vector 3: dh, dk, dl");
54 auto mustBePositiveOrZero = std::make_shared<BoundedValidator<int>>();
55 mustBePositiveOrZero->setLower(0);
56 alg->declareProperty(ModulationProperties::MaxOrder, 0, mustBePositiveOrZero,
57 "Maximum order to apply Modulation Vectors. Default = 0", Direction::Input);
59 "Include combinations of modulation vectors in satellite search", Direction::Input);
60}
61
74 const bool saveOnLattice{true};
75 return {std::move(offsets), maxOrder, crossTerms, saveOnLattice};
76}
77
86std::vector<Kernel::V3D> validModulationVectors(const std::vector<double> &modVector1,
87 const std::vector<double> &modVector2,
88 const std::vector<double> &modVector3) {
89 std::vector<V3D> modVectors;
90 auto addIfNonZero = [&modVectors](const auto &modVec) {
91 if (std::fabs(modVec[0]) > 0 || std::fabs(modVec[1]) > 0 || std::fabs(modVec[2]) > 0)
92 modVectors.emplace_back(V3D(modVec[0], modVec[1], modVec[2]));
93 };
94 addIfNonZero(modVector1);
95 addIfNonZero(modVector2);
96 addIfNonZero(modVector3);
97 return modVectors;
98}
99
107std::vector<Kernel::V3D> addModulationVectors(const std::vector<double> &modVector1,
108 const std::vector<double> &modVector2,
109 const std::vector<double> &modVector3) {
110 std::vector<V3D> modVectors;
111 auto addVec = [&modVectors](const auto &modVec) { modVectors.emplace_back(V3D(modVec[0], modVec[1], modVec[2])); };
112 addVec(modVector1);
113 addVec(modVector2);
114 addVec(modVector3);
115 return modVectors;
116}
117
128std::vector<MNPOffset> generateOffsetVectors(const std::vector<Kernel::V3D> &modVectors, const int maxOrder,
129 const bool crossTerms) {
130 assert(modVectors.size() <= 3);
131
132 std::vector<MNPOffset> offsets;
133 if (crossTerms && modVectors.size() > 1) {
134 const auto &modVector0{modVectors[0]}, modVector1{modVectors[1]};
135 if (modVectors.size() == 2) {
136 // Calculate m*mod_vec1 + n*mod_vec2 for combinations of
137 // m, n in
138 // [-maxOrder,maxOrder]
139 offsets.reserve(2 * maxOrder);
140 for (auto m = -maxOrder; m <= maxOrder; ++m) {
141 for (auto n = -maxOrder; n <= maxOrder; ++n) {
142 if (m == 0 && n == 0)
143 continue;
144 offsets.emplace_back(std::make_tuple(m, n, 0, modVector0 * m + modVector1 * n));
145 }
146 }
147 } else {
148 // Calculate m*mod_vec1 + n*mod_vec2 + p*mod_vec3 for
149 // combinations of m, n, p in [-maxOrder,maxOrder]
150 const auto &modVector2{modVectors[2]};
151 offsets.reserve(3 * maxOrder);
152 for (auto m = -maxOrder; m <= maxOrder; ++m) {
153 for (auto n = -maxOrder; n <= maxOrder; ++n) {
154 for (auto p = -maxOrder; p <= maxOrder; ++p) {
155 if (m == 0 && n == 0 && p == 0)
156 continue;
157 offsets.emplace_back(m, n, p, modVector0 * m + modVector1 * n + modVector2 * p);
158 }
159 }
160 }
161 }
162 } else {
163 // No cross terms: Compute coeff*mod_vec_i for each
164 // modulation vector separately for coeff in [-maxOrder,
165 // maxOrder]
166 for (auto i = 0u; i < modVectors.size(); ++i) {
167 const auto &modVector = modVectors[i];
168 for (int order = -maxOrder; order <= maxOrder; ++order) {
169 if (order == 0)
170 continue;
171 V3D offset{modVector * order};
172 switch (i) {
173 case 0:
174 offsets.emplace_back(order, 0, 0, offset);
175 break;
176 case 1:
177 offsets.emplace_back(0, order, 0, offset);
178 break;
179 case 2:
180 offsets.emplace_back(0, 0, order, offset);
181 break;
182 }
183 }
184 }
185 }
186
187 return offsets;
188}
189
200std::vector<MNPOffset> generateOffsetVectors(const std::vector<double> &hOffsets, const std::vector<double> &kOffsets,
201 const std::vector<double> &lOffsets) {
202 std::vector<MNPOffset> offsets;
203 for (double hOffset : hOffsets) {
204 for (double kOffset : kOffsets) {
205 std::transform(lOffsets.begin(), lOffsets.end(), std::back_inserter(offsets),
206 [&hOffset, &kOffset](double lOffset) {
207 // it's not quite clear how to interpret them as mnp
208 // indices so set to 0, 0, 0
209 return std::make_tuple(0, 0, 0, V3D(hOffset, kOffset, lOffset));
210 });
211 }
212 }
213 return offsets;
214}
215
216} // namespace Mantid::Crystal
const std::vector< V3D > modVectors
Definition: IndexPeaks.cpp:56
const bool crossTerms
Definition: IndexPeaks.cpp:57
const int maxOrder
Definition: IndexPeaks.cpp:55
IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:45
ArrayLenghtValidator : Validate length of an array property.
Support for a property that holds an array of values.
Definition: ArrayProperty.h:28
BoundedValidator is a validator that requires the values to be between upper or lower bounds,...
virtual void declareProperty(std::unique_ptr< Property > p, const std::string &doc="")=0
Function to declare properties (i.e. store them)
virtual TypedValue getProperty(const std::string &name) const =0
Get the value of a property.
Manage the lifetime of a class intended to be a singleton.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class for 3D vectors.
Definition: V3D.h:34
std::vector< Kernel::V3D > addModulationVectors(const std::vector< double > &modVector1, const std::vector< double > &modVector2, const std::vector< double > &modVector3)
Create a list of valid modulation vectors from the input.
std::vector< MNPOffset > generateOffsetVectors(const std::vector< Kernel::V3D > &modVectors, const int maxOrder, const bool crossTerms)
Calculate a list of HKL offsets from the given modulation vectors.
double qConventionFactor()
convenience overload to pull the convention from the config service
std::vector< Kernel::V3D > validModulationVectors(const std::vector< double > &modVector1, const std::vector< double > &modVector2, const std::vector< double > &modVector3)
Create a list of valid modulation vectors from the input.
Tie together the names of the properties for the modulation vectors.
static ModulationProperties create(const API::IAlgorithm &alg)
Create a ModulationProperties object from an algorithm.
static void appendTo(API::IAlgorithm *alg)
Append the common set of properties that relate to modulation vectors to the given algorithm.
Describes the direction (within an algorithm) of a Property.
Definition: Property.h:50
@ Input
An input workspace.
Definition: Property.h:53