forked from npshub/mantid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PeakShapeEllipsoid.cpp
122 lines (98 loc) · 5.3 KB
/
PeakShapeEllipsoid.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidDataObjects/PeakShapeEllipsoid.h"
#include "MantidKernel/cow_ptr.h"
#include <json/json.h>
#include <utility>
namespace Mantid {
namespace DataObjects {
PeakShapeEllipsoid::PeakShapeEllipsoid(const std::vector<Kernel::V3D> &directions, const std::vector<double> &abcRadii,
const std::vector<double> &abcRadiiBackgroundInner,
const std::vector<double> &abcRadiiBackgroundOuter,
Kernel::SpecialCoordinateSystem frame, std::string algorithmName,
int algorithmVersion, const Kernel::V3D &translation)
: PeakShapeBase(frame, std::move(algorithmName), algorithmVersion), m_directions(directions), m_abc_radii(abcRadii),
m_abc_radiiBackgroundInner(abcRadiiBackgroundInner), m_abc_radiiBackgroundOuter(abcRadiiBackgroundOuter),
m_translation(translation) {
if (directions.size() != 3) {
throw std::invalid_argument("directions must be of size 3");
}
if (abcRadii.size() != 3) {
throw std::invalid_argument("radii must be of size 3");
}
if (abcRadiiBackgroundInner.size() != 3) {
throw std::invalid_argument("radii inner must be of size 3");
}
if (abcRadiiBackgroundOuter.size() != 3) {
throw std::invalid_argument("radii outer must be of size 3");
}
}
bool PeakShapeEllipsoid::operator==(const PeakShapeEllipsoid &other) const {
return PeakShapeBase::operator==(other) && other.directions() == this->directions() &&
other.abcRadii() == this->abcRadii() && other.abcRadiiBackgroundInner() == this->abcRadiiBackgroundInner() &&
other.abcRadiiBackgroundOuter() == this->abcRadiiBackgroundOuter() &&
other.translation() == this->translation();
}
const std::vector<double> &PeakShapeEllipsoid::abcRadii() const { return m_abc_radii; }
const std::vector<double> &PeakShapeEllipsoid::abcRadiiBackgroundInner() const { return m_abc_radiiBackgroundInner; }
const std::vector<double> &PeakShapeEllipsoid::abcRadiiBackgroundOuter() const { return m_abc_radiiBackgroundOuter; }
const std::vector<Kernel::V3D> &PeakShapeEllipsoid::directions() const { return m_directions; }
const Kernel::V3D &PeakShapeEllipsoid::translation() const { return m_translation; }
std::vector<Kernel::V3D>
PeakShapeEllipsoid::getDirectionInSpecificFrame(Kernel::Matrix<double> &invertedGoniometerMatrix) const {
if ((invertedGoniometerMatrix.numCols() != m_directions.size()) ||
(invertedGoniometerMatrix.numRows() != m_directions.size())) {
throw std::invalid_argument("The inverted goniometer matrix is not "
"compatible with the direction vector");
}
std::vector<Kernel::V3D> directionsInFrame;
directionsInFrame.reserve(m_directions.size());
std::transform(m_directions.cbegin(), m_directions.cend(), std::back_inserter(directionsInFrame),
[&invertedGoniometerMatrix](const auto &direction) { return invertedGoniometerMatrix * direction; });
return directionsInFrame;
}
std::string PeakShapeEllipsoid::toJSON() const {
Json::Value root;
PeakShapeBase::buildCommon(root);
root["radius0"] = Json::Value(m_abc_radii[0]);
root["radius1"] = Json::Value(m_abc_radii[1]);
root["radius2"] = Json::Value(m_abc_radii[2]);
root["background_inner_radius0"] = Json::Value(m_abc_radiiBackgroundInner[0]);
root["background_inner_radius1"] = Json::Value(m_abc_radiiBackgroundInner[1]);
root["background_inner_radius2"] = Json::Value(m_abc_radiiBackgroundInner[2]);
root["background_outer_radius0"] = Json::Value(m_abc_radiiBackgroundOuter[0]);
root["background_outer_radius1"] = Json::Value(m_abc_radiiBackgroundOuter[1]);
root["background_outer_radius2"] = Json::Value(m_abc_radiiBackgroundOuter[2]);
root["direction0"] = m_directions[0].toString();
root["direction1"] = m_directions[1].toString();
root["direction2"] = m_directions[2].toString();
root["translation0"] = Json::Value(m_translation[0]);
root["translation1"] = Json::Value(m_translation[1]);
root["translation2"] = Json::Value(m_translation[2]);
Json::StyledWriter writer;
return writer.write(root);
}
PeakShapeEllipsoid *PeakShapeEllipsoid::clone() const { return new PeakShapeEllipsoid(*this); }
std::string PeakShapeEllipsoid::shapeName() const { return PeakShapeEllipsoid::ellipsoidShapeName(); }
boost::optional<double> PeakShapeEllipsoid::radius(RadiusType type) const {
std::vector<double>::const_iterator it;
switch (type) {
case (RadiusType::Radius):
it = std::max_element(m_abc_radii.cbegin(), m_abc_radii.cend());
break;
case (RadiusType::OuterRadius):
it = std::max_element(m_abc_radiiBackgroundOuter.cbegin(), m_abc_radiiBackgroundOuter.cend());
break;
case (RadiusType::InnerRadius):
it = std::max_element(m_abc_radiiBackgroundInner.cbegin(), m_abc_radiiBackgroundInner.cend());
break;
}
return boost::optional<double>{*it};
}
const std::string PeakShapeEllipsoid::ellipsoidShapeName() { return "ellipsoid"; }
} // namespace DataObjects
} // namespace Mantid