48 Criteria2(prop2Crit), value1(
std::move(prop1Value)), value2(
std::move(prop2Value))
51 Prop1 = std::make_unique<Kernel::EnabledWhenProperty>(propName1, Criteria1, value1);
52 Prop2 = std::make_unique<Kernel::EnabledWhenProperty>(propName2, Criteria2, value2);
63 return Prop1->isEnabled(algo) && Prop2->isEnabled(algo);
70 std::unique_ptr<Kernel::EnabledWhenProperty>
Prop1, Prop2;
75 "Workspace of Peaks with UB loaded");
77 "List of run Numbers for which the goniometer settings will "
81 "Output Workspace of Peaks with optimized sample Orientations");
85 "Workspace of Results");
88 "If true sample offsets will be adjusted to give better "
89 "fits, otherwise they will be fixed as zero(def=true)");
91 declareProperty(
"OptimizeGoniometerTilt",
false,
"Set true if main error is due to a tilted Goniometer(def=false)");
98 declareProperty(
"MaxAngularChange", 5.0,
"Max offset in degrees from current settings(def=5)");
101 "Use only peaks whose fractional "
102 "hkl values are below this "
103 "tolerance(def=0.15)");
106 "If less than 0 all peaks are used, "
107 "otherwise only peaks whose h,k, "
108 "and l values are below the level "
110 declareProperty(
"MaxSamplePositionChangeMeters", .0005,
"Maximum Change in Sample position in meters(def=.0005)");
127 "The name of the TableWorkspace in which to store the final "
128 "covariance matrix");
143 if (peaks != outPeaks) {
144 outPeaks = peaks->clone();
147 std::vector<int> NOoptimizeRuns =
getProperty(
"KeepGoniometerFixedfor");
149 const DblMatrix X = peaks->sample().getOrientedLattice().getUB();
157 std::vector<int> RunNumList;
158 std::vector<V3D> ChiPhiOmega;
162 double HKLintOffsetMax =
getProperty(
"MaxIndexingError");
164 for (
int i = 0; i < peaks->getNumberPeaks(); i++) {
165 IPeak &peak = peaks->getPeak(i);
167 auto it = RunNumList.begin();
168 for (; it != RunNumList.end() && *it != runNum; ++it) {
174 if (use && HKLMax > 0)
175 for (
int k = 0; k < 3; k++) {
176 if (
fabs(hkl[k]) > HKLMax)
180 if (it == RunNumList.end() && use)
182 RunNumList.emplace_back(runNum);
186 ChiPhiOmega.emplace_back(phichiOmega[1], phichiOmega[2], phichiOmega[0]);
192 xRef.emplace_back(
static_cast<double>(i));
193 xRef.emplace_back(
static_cast<double>(i));
194 xRef.emplace_back(
static_cast<double>(i));
198 g_log.
notice() <<
"Number initially indexed = " << nPeaksUsed <<
" at tolerance = " << HKLintOffsetMax <<
'\n';
200 if (nPeaksUsed < 1) {
201 g_log.
error() <<
"Error in UB too large. 0 peaks indexed at " << HKLintOffsetMax <<
'\n';
202 throw std::invalid_argument(
"Error in UB too large. 0 peaks indexed ");
205 int N = 3 * nPeaksUsed;
206 auto mwkspc = createWorkspace<Workspace2D>(1, N, N);
207 mwkspc->setPoints(0, xRef);
208 mwkspc->setCounts(0, N, 0.0);
209 mwkspc->setCountStandardDeviations(0, N, 1.0);
211 std::string FuncArg =
"name=PeakHKLErrors,PeakWorkspaceName=" +
getPropertyValue(
"PeaksWorkspace") +
"";
213 std::string OptRunNums;
217 std::vector<std::string> ChRunNumList;
218 std::string predChar;
219 for (
auto runNum : RunNumList) {
220 auto it1 = NOoptimizeRuns.begin();
221 for (; it1 != NOoptimizeRuns.end() && *it1 != runNum; ++it1) {
224 if (it1 == NOoptimizeRuns.end()) {
226 OptRunNums += predChar + runNumStr;
228 ChRunNumList.emplace_back(runNumStr);
234 NOoptimizeRuns = RunNumList;
236 std::string message =
"No Goniometer Angles ";
238 message +=
"relative to the tilted Goniometer ";
239 message +=
"will be 'changed'";
242 if (!OptRunNums.empty() && !omitRuns)
243 FuncArg +=
",OptRuns=" + OptRunNums;
247 std::ostringstream oss(std::ostringstream::out);
249 std::ostringstream oss1(std::ostringstream::out);
253 double DegreeTol =
getProperty(
"MaxAngularChange");
254 std::string startConstraint;
256 for (
size_t i = 0; i < RunNumList.size(); i++) {
257 int runNum = RunNumList[i];
260 for (; k < NOoptimizeRuns.size(); k++) {
261 if (NOoptimizeRuns[k] == runNum)
264 if (k >= NOoptimizeRuns.size()) {
265 V3D chiphiomega = ChiPhiOmega[i];
266 oss <<
",chi" << runNum <<
"=" << chiphiomega[0] <<
",phi" << runNum <<
"=" << chiphiomega[1] <<
",omega"
267 << runNum <<
"=" << chiphiomega[2];
269 oss1 << startConstraint << chiphiomega[0] - DegreeTol <<
"<chi" << runNum <<
"<" << chiphiomega[0] + DegreeTol;
270 oss1 <<
"," << chiphiomega[1] - DegreeTol <<
"<phi" << runNum <<
"<" << chiphiomega[1] + DegreeTol;
272 oss1 <<
"," << chiphiomega[2] - DegreeTol <<
"<omega" << runNum <<
"<" << chiphiomega[2] + DegreeTol;
273 startConstraint =
",";
279 V3D sampPos =
V3D(0., 0., 0.);
281 oss <<
",SampleXOffset=" << sampPos.
X() <<
",SampleYOffset=" << sampPos.
Y() <<
",SampleZOffset=" << sampPos.
Z();
282 oss <<
",GonRotx=0.0,GonRoty=0.0,GonRotz=0.0";
284 double maxSampshift =
getProperty(
"MaxSamplePositionChangeMeters");
285 oss1 << startConstraint << sampPos.
X() - maxSampshift <<
"<SampleXOffset<" << sampPos.
X() + maxSampshift <<
","
286 << sampPos.
Y() - maxSampshift <<
"<SampleYOffset<" << sampPos.
Y() + maxSampshift <<
","
287 << sampPos.
Z() - maxSampshift <<
"<SampleZOffset<" << sampPos.
Z() + maxSampshift;
289 oss1 <<
"," << -DegreeTol <<
"<GonRotx<" << DegreeTol <<
"," << -DegreeTol <<
"<GonRoty<" << DegreeTol <<
","
290 << -DegreeTol <<
"<GonRotz<" << DegreeTol;
292 FuncArg += oss.str();
293 std::string Constr = oss1.str();
295 g_log.
debug() <<
"Function argument=" << FuncArg <<
'\n';
296 g_log.
debug() <<
"Constraint argument=" << Constr <<
'\n';
302 fit_alg->setProperty(
"Function", FuncArg);
304 fit_alg->setProperty(
"MaxIterations", 60);
306 fit_alg->setProperty(
"Constraints", Constr);
308 fit_alg->setProperty(
"InputWorkspace", mwkspc);
310 fit_alg->setProperty(
"CreateOutput",
true);
315 std::ostringstream oss3(std::ostringstream::out);
318 oss3 <<
"SampleXOffset=" << sampPos.
X() <<
",SampleYOffset=" << sampPos.
Y() <<
",SampleZOffset=" << sampPos.
Z();
322 if (!(
bool)
getProperty(
"OptimizeGoniometerTilt")) {
326 Ties +=
"GonRotx=0.0,GonRoty=0.0,GonRotz=0.0";
330 fit_alg->setProperty(
"Ties", Ties);
332 fit_alg->setProperty(
"Output",
"out");
334 fit_alg->executeAsChildAlg();
338 double chisq = fit_alg->getProperty(
"OutputChi2overDoF");
339 g_log.
notice() <<
"Fit finished. Status=" << (std::string)fit_alg->getProperty(
"OutputStatus") <<
'\n';
346 g_log.
debug() <<
"Chi2overDof=" << chisq <<
" # Peaks used=" << nPeaksUsed <<
"# fitting parameters =" << nParams
347 <<
" dof=" << (nPeaksUsed - nParams) <<
'\n';
351 double sigma = sqrt(chisq);
353 std::string OutputStatus = fit_alg->getProperty(
"OutputStatus");
354 g_log.
notice() <<
"Output Status=" << OutputStatus <<
'\n';
358 setProperty(
"OutputNormalisedCovarianceMatrixOptX",
361 if (chisq < 0 || chisq != chisq)
365 std::map<std::string, double> Results;
366 for (
int prm = 0; prm < static_cast<int>(RRes->rowCount()); ++prm) {
367 std::string namee = RRes->getRef<std::string>(
"Name", prm);
369 std::string start = namee.substr(0, 3);
370 if (start !=
"chi" && start !=
"phi" && start !=
"ome" && start !=
"Sam" && start !=
"Gon")
373 double value = RRes->getRef<
double>(
"Value", prm);
374 Results[namee] =
value;
377 double v =
sigma * RRes->getRef<
double>(
"Error", prm);
378 RRes->getRef<
double>(
"Error", prm) = v;
386 V3D newSampPos(Results[
"SampleXOffset"], Results[
"SampleYOffset"], Results[
"SampleZOffset"]);
388 auto &componentInfo = outPeaks->mutableComponentInfo();
396 std::map<int, Matrix<double>> MapRunNum2GonMat;
397 std::string OptRun2 =
"/" + OptRunNums +
"/";
400 UBinv = outPeaks->sample().getOrientedLattice().getUB();
403 for (
int i = 0; i < outPeaks->getNumberPeaks(); ++i) {
404 auto &peak = outPeaks->getPeak(i);
405 peak.setSamplePos(peak.getSamplePos() + newSampPos);
406 int RunNum = peak.getRunNumber();
409 if (RunNum == prevRunNum || MapRunNum2GonMat.find(RunNum) != MapRunNum2GonMat.end())
410 GonMatrix = MapRunNum2GonMat[RunNum];
411 else if (OptRun2.find(
"/" + RunNumStr +
"/") < OptRun2.size() - 2) {
413 double chi = Results[
"chi" + RunNumStr];
414 double phi = Results[
"phi" + RunNumStr];
415 double omega = Results[
"omega" + RunNumStr];
424 GonMatrix = GonTilt * uniGonio.
getR();
425 MapRunNum2GonMat[RunNum] = GonMatrix;
427 GonMatrix = GonTilt * peak.getGoniometerMatrix();
428 MapRunNum2GonMat[RunNum] = GonMatrix;
431 peak.setGoniometerMatrix(GonMatrix);
432 V3D hkl = UBinv * peak.getQSampleFrame();
439 if (MapRunNum2GonMat.size() == 1)
441 Matrix<double> GonMatrix = MapRunNum2GonMat[outPeaks->getPeak(0).getRunNumber()];
443 outPeaks->mutableRun().setGoniometer(Gon,
false);
448 g_log.
notice() <<
"Number indexed after optimization= " << nIndexed <<
" at tolerance = " << HKLintOffsetMax <<
'\n';
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
A property class for workspaces.
void exec() override
Execute algorithm.
void init() override
Virtual method - must be overridden by concrete algorithm.
bool isEnabled(const IPropertyManager *algo) const override
Is the property to be shown as "enabled" in the GUI.
std::unique_ptr< Kernel::EnabledWhenProperty > Prop1
ePropertyCriterion Criteria1
~OrEnabledWhenProperties() override=default
OrEnabledWhenProperties(std::string prop1Name, ePropertyCriterion prop1Crit, std::string prop1Value, std::string prop2Name, ePropertyCriterion prop2Crit, std::string prop2Value)
static Kernel::Matrix< double > RotationMatrixAboutRegAxis(double theta, char axis)
Returns the matrix corresponding to a rotation of theta(degrees) around axis.
Class to represent a particular goniometer setting, which is described by the rotation matrix.
void setRotationAngle(const std::string &name, double value)
Set rotation angle for an axis using motor name.
std::vector< double > getEulerAngles(const std::string &convention="YZX")
Return Euler angles acording to a convention.
void makeUniversalGoniometer()
Make a default universal goniometer with phi,chi,omega angles according to SNS convention.
const Kernel::DblMatrix & getR() const
Return global rotation matrix.
Structure describing a single-crystal peak.
virtual Mantid::Kernel::Matrix< double > getGoniometerMatrix() const =0
virtual int getRunNumber() const =0
virtual Mantid::Kernel::V3D getQSampleFrame() const =0
This class contains static utility methods for indexing peaks and finding the UB matrix.
static bool ValidIndex(const Kernel::V3D &hkl, double tolerance)
Check is hkl is within tolerance of integer (h,k,l) non-zero values.
Support for a property that holds an array of values.
Interface to PropertyManager.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
Interface for modifiers to Property's that specify if they should be enabled or visible in a GUI.
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
T Invert()
LU inversion routine.
constexpr double X() const noexcept
Get x.
constexpr double Y() const noexcept
Get y.
constexpr double Z() const noexcept
Get z.
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
MANTID_CRYSTAL_DLL void adjustUpSampleAndSourcePositions(double const L0, const Kernel::V3D &newSampPos, Geometry::ComponentInfo &componentInfo)
Updates the ComponentInfo for the workspace containing newInstrument to reflect the position of the s...
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
ePropertyCriterion
Enum for use in EnabledWhenProperty.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.