Newer
Older
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
123
124
125
126
127
128
129
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/ReferenceFrame.h"
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidNexusGeometry/InstrumentBuilder.h"
#include "MantidNexusGeometry/NexusShapeFactory.h"
#include "MantidGeometry/Instrument/ObjCompAssembly.h"
#include "MantidGeometry/Instrument/CompAssembly.h"
#include "MantidKernel/make_unique.h"
#include "MantidKernel/EigenConversionHelpers.h"
#include <boost/make_shared.hpp>
namespace Mantid {
namespace NexusGeometry {
/// Constructor
InstrumentBuilder::InstrumentBuilder(const std::string &instrumentName)
: m_instrument(
Mantid::Kernel::make_unique<Geometry::Instrument>(instrumentName)) {
// Default view
std::string defaultViewAxis = "z";
Geometry::PointingAlong pointingUp(Geometry::Y), alongBeam(Geometry::Z),
thetaSign(Geometry::X);
Geometry::Handedness handedness(Geometry::Right);
std::string origin;
m_instrument->setDefaultViewAxis(defaultViewAxis);
// Reference frame definitely does not need to be shared, and the copy
// operations in instrument make a new one anyway, but at present i'm not
// chaning the instruemnt API, particularly since getReferenceFrame on
// instrument returns the shared pointer
m_instrument->setReferenceFrame(boost::make_shared<Geometry::ReferenceFrame>(
pointingUp, alongBeam, thetaSign, handedness, origin));
m_instrument->setPos(0, 0, 0);
m_instrument->setRot(Kernel::Quat());
}
/// Adds component to instrument
Geometry::IComponent *
InstrumentBuilder::addComponent(const std::string &compName,
const Eigen::Vector3d &position) {
Geometry::IComponent *component(new Geometry::ObjCompAssembly(compName));
component->setPos(position(0), position(1), position(2));
m_instrument->add(component);
return component;
}
void InstrumentBuilder::addDetectorToLastBank(
const std::string &detName, int detId,
const Eigen::Vector3d &relativeOffset,
boost::shared_ptr<const Geometry::IObject> &shape) {
if (!m_lastBank)
throw std::runtime_error("No bank to add the detector to");
auto *detector = new Geometry::Detector(
detName, detId,
const_cast<Geometry::IComponent *>(m_lastBank->getBaseComponent()));
detector->setPos(relativeOffset[0], relativeOffset[1], relativeOffset[2]);
// No rotation set for detector pixels of a bank. This is not possible in the
// Nexus Geometry specification.
detector->setShape(shape);
m_lastBank->add(detector);
m_instrument->markAsDetectorIncomplete(detector);
}
/// Adds detector to instrument
void InstrumentBuilder::addDetectorToInstrument(
const std::string &detName, int detId, const Eigen::Vector3d &position,
boost::shared_ptr<const Geometry::IObject> &shape) {
auto *detector(new Geometry::Detector(
detName, detId,
const_cast<Geometry::IComponent *>(m_instrument->getBaseComponent())));
detector->setPos(position(0), position(1), position(2));
detector->setShape(shape);
m_instrument->add(detector);
m_instrument->markAsDetectorIncomplete(detector);
}
void InstrumentBuilder::addMonitor(
const std::string &detName, int detId, const Eigen::Vector3d &position,
boost::shared_ptr<const Geometry::IObject> &shape) {
auto *detector(new Geometry::Detector(
detName, detId,
const_cast<Geometry::IComponent *>(m_instrument->getBaseComponent())));
detector->setPos(position(0), position(1), position(2));
detector->setShape(shape);
m_instrument->add(detector);
m_instrument->markAsMonitor(detector);
}
/// Sorts detectors
void InstrumentBuilder::sortDetectors() const {
m_instrument->markAsDetectorFinalize();
}
/// Add sample
void InstrumentBuilder::addSample(const std::string &sampleName,
const Eigen::Vector3d &position) {
auto *sample(this->addComponent(sampleName, position));
m_instrument->markAsSamplePos(sample);
}
/// Add source
void InstrumentBuilder::addSource(const std::string &sourceName,
const Eigen::Vector3d &position) {
auto *source(this->addComponent(sourceName, position));
m_instrument->markAsSource(source);
}
void InstrumentBuilder::addBank(const std::string &localName,
const Eigen::Vector3d &position,
const Eigen::Quaterniond &rotation) {
auto *assembly =
new Geometry::CompAssembly(m_instrument->getBaseComponent(), nullptr);
assembly->setName(localName);
assembly->setPos(position[0], position[1], position[2]);
assembly->setRot(Kernel::toQuat(rotation));
m_lastBank = assembly;
m_instrument->add(assembly);
}
std::unique_ptr<const Geometry::Instrument>
InstrumentBuilder::createInstrument() const {
sortDetectors();
return std::unique_ptr<const Geometry::Instrument>(m_instrument->clone());
}
}
}