9#include "MantidBeamline/DetectorInfo.h"
25double angleFromObserver(
const Kernel::V3D &
position,
const Kernel::V3D &observer,
const Kernel::V3D &axis) {
26 return (
position - observer).angle(axis);
29double signedAngleFromObserver(
const Kernel::V3D &
position,
const Kernel::V3D &observer,
const Kernel::V3D &axis,
30 const Kernel::V3D &instrumentUp) {
31 const auto observerDetVec =
position - observer;
32 double angle = observerDetVec.angle(axis);
34 const auto cross = axis.cross_prod(observerDetVec);
35 const auto normToSurface = axis.cross_prod(instrumentUp);
36 if (normToSurface.scalar_prod(cross) < 0) {
44double applyPhiOffset(
const double phi,
const double offset) {
return phi < 0 ? -(offset + phi) : offset - phi; }
54 std::shared_ptr<const Geometry::Instrument> instrument,
55 std::shared_ptr<
const std::vector<detid_t>> detectorIds,
56 std::shared_ptr<
const std::unordered_map<detid_t, size_t>> detIdToIndexMap,
57 std::shared_ptr<ParameterInfo> parameterInfo,
58 std::shared_ptr<ReferenceFrame const> referenceFrame)
59 : m_detectorInfo(
std::move(detectorInfo)), m_instrument(
std::move(instrument)),
60 m_detectorIDs(
std::move(detectorIds)), m_detIDToIndex(
std::move(detIdToIndexMap)),
61 m_parameterInfo(
std::move(parameterInfo)), m_referenceFrame(
std::move(referenceFrame)),
67 throw std::invalid_argument(
"DetectorInfo::DetectorInfo Workspace does not contain an instrument!");
70 throw std::invalid_argument(
"DetectorInfo::DetectorInfo: ID and ID->index map do not match");
79 : m_detectorInfo(
std::make_unique<Beamline::
DetectorInfo>(*other.m_detectorInfo)), m_instrument(other.m_instrument),
80 m_detectorIDs(other.m_detectorIDs), m_detIDToIndex(other.m_detIDToIndex), m_parameterInfo(other.m_parameterInfo),
87 throw std::runtime_error(
"DetectorInfo::operator=: Detector IDs in "
88 "assignment do not match. Assignment not "
161 throw std::logic_error(
"Two theta (scattering angle) is not defined for monitors.");
166 if (beamLine.nullVector()) {
171 return sampleDetVec.angle(beamLine);
177 throw std::logic_error(
"Two theta (scattering angle) is not defined for monitors.");
182 if (beamLine.nullVector()) {
187 return sampleDetVec.angle(beamLine);
193 throw std::logic_error(
"Two theta (scattering angle) is not defined for monitors.");
198 if (beamLine.nullVector()) {
205 double angle = sampleDetVec.angle(beamLine);
207 const auto cross = beamLine.cross_prod(sampleDetVec);
208 const auto normToSurface = beamLine.cross_prod(instrumentUpAxis);
209 if (normToSurface.scalar_prod(cross) < 0) {
218 throw std::logic_error(
"Two theta (scattering angle) is not defined for monitors.");
223 if (beamLine.nullVector()) {
230 double angle = sampleDetVec.angle(beamLine);
232 const auto cross = beamLine.cross_prod(sampleDetVec);
233 const auto normToSurface = beamLine.cross_prod(instrumentUpAxis);
234 if (normToSurface.scalar_prod(cross) < 0) {
242 throw std::logic_error(
"Azimuthal angle is not defined for monitors");
247 if (beamLine.nullVector()) {
256 const auto vertical = beamLineNormalized.cross_prod(origHorizontal);
258 throw std::runtime_error(
"Failed to create up axis orthogonal to the beam direction");
261 const auto horizontal = vertical.cross_prod(beamLineNormalized);
262 if (origHorizontal.scalar_prod(horizontal) <= 0.)
263 throw std::runtime_error(
"Failed to create horizontal axis orthogonal to the beam direction");
265 const double dotHorizontal = sampleDetVec.scalar_prod(horizontal);
266 const double dotVertical = sampleDetVec.scalar_prod(vertical);
268 return atan2(dotVertical, dotHorizontal);
273 throw std::logic_error(
"Azimuthal angle is not defined for monitors");
278 if (beamLine.nullVector()) {
287 const auto vertical = beamLineNormalized.cross_prod(origHorizontal);
289 throw std::runtime_error(
"Failed to create up axis orthogonal to the beam direction");
292 const auto horizontal = vertical.cross_prod(beamLineNormalized);
293 if (origHorizontal.scalar_prod(horizontal) <= 0.)
294 throw std::runtime_error(
"Failed to create horizontal axis orthogonal to the beam direction");
296 const double dotHorizontal = sampleDetVec.scalar_prod(horizontal);
297 const double dotVertical = sampleDetVec.scalar_prod(vertical);
299 return atan2(dotVertical, dotHorizontal);
324 return signedAngleFromObserver(
position(
index), observer, axis, instrumentUp);
330 return signedAngleFromObserver(
position(
index), observer, axis, instrumentUp);
361 return applyPhiOffset(
phi(
index), offset);
366 return applyPhiOffset(
phi(
index), offset);
370 std::vector<detid_t> &calibratedDets,
371 std::vector<detid_t> &uncalibratedDets)
const {
375 double difc = par->value<
double>();
376 calibratedDets.push_back(detectorId);
380 difa = par->value<
double>();
383 tzero = par->value<
double>();
388 uncalibratedDets.push_back(detectorId);
390 return {0.,
difc, 0.};
402 const double beamCoord = sampleDetVec[
m_referenceFrame->pointingAlongBeam()];
403 const double leftoverCoord = sampleDetVec[
m_referenceFrame->pointingHorizontal()];
404 const double lat = std::atan2(upCoord, std::hypot(leftoverCoord, beamCoord));
405 const double lon = std::atan2(leftoverCoord, beamCoord);
406 return std::pair<double, double>(lat, lon);
413 const double beamCoord = sampleDetVec[
m_referenceFrame->pointingAlongBeam()];
414 const double leftoverCoord = sampleDetVec[
m_referenceFrame->pointingHorizontal()];
415 const double lat = std::atan2(upCoord, std::hypot(leftoverCoord, beamCoord));
416 const double lon = std::atan2(leftoverCoord, beamCoord);
417 return std::pair<double, double>(lat, lon);
430 std::vector<Kernel::V3D> positions;
431 positions.reserve(
size());
432 for (
size_t i = 0; i <
size(); ++i) {
450 std::vector<Kernel::Quat> rotations;
451 rotations.reserve(
size());
452 for (
size_t i = 0; i <
size(); ++i) {
460 std::vector<Kernel::V3D> scaleFactors;
461 scaleFactors.reserve(
size());
462 for (
size_t i = 0; i <
size(); ++i) {
482 for (
size_t i = 0; i <
size(); ++i)
541 }
catch (
const std::out_of_range &) {
542 std::stringstream msg;
543 msg <<
"Failed to find detector with id=" << id;
544 throw std::out_of_range(msg.str());
563 return {intervals.begin(), intervals.end()};
608 const size_t n =
size();
612 const size_t detectorIDsMem =
sizeof(std::vector<detid_t>) +
n *
sizeof(
detid_t);
615 const size_t detIDToIndexMem =
616 sizeof(std::unordered_map<detid_t, size_t>) +
n * (
sizeof(
detid_t) +
sizeof(size_t) + 2 *
sizeof(
void *));
618 const size_t cacheMem =
m_lastDetector.capacity() *
sizeof(std::shared_ptr<const Geometry::IDetector>) +
622 const size_t paramInfoSize =
sizeof(std::shared_ptr<Geometry::ParameterInfo>);
624 const size_t refFrameSize =
sizeof(std::shared_ptr<Geometry::ReferenceFrame const>);
627 return sizeof(*this) + beamlineMem + detectorIDsMem + detIDToIndexMem + cacheMem + paramInfoSize + refFrameSize;
const std::vector< double > & rhs
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_THREAD_NUMBER
#define PARALLEL_GET_MAX_THREADS
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
void clearPositionDependentParameters(const size_t index)
double twoTheta(const size_t index) const
Returns 2 theta (scattering angle w.r.t. to beam direction).
std::shared_ptr< std::vector< detid_t > const > m_detectorIDs
size_t scanCount() const
Returns the scan count of the detector with given detector index.
void setPosition(const size_t index, const Kernel::V3D &position)
Set the absolute position of the detector with given index. Not thread safe.
double l2(const size_t index) const
Returns L2 (distance from sample to spectrum).
std::vector< Kernel::Quat > allRotations() const
Returns the absolute rotations of all detectors in a vector ordered by index.
const Geometry::IDetector & getDetector(const size_t index) const
std::shared_ptr< Geometry::ReferenceFrame const > m_referenceFrame
Kernel::V3D samplePosition() const
Returns the sample position.
std::pair< double, double > geographicalAngles(const size_t index) const
std::shared_ptr< std::unordered_map< detid_t, size_t > const > m_detIDToIndex
DetectorInfo(std::unique_ptr< Beamline::DetectorInfo > detectorInfo, std::shared_ptr< const Geometry::Instrument > instrument, std::shared_ptr< const std::vector< detid_t > > detectorIds, std::shared_ptr< const std::unordered_map< detid_t, size_t > > detIdToIndexMap, std::shared_ptr< ParameterInfo > parameterInfo, std::shared_ptr< ReferenceFrame const > referenceFrame)
Construct DetectorInfo based on an Instrument.
double phiOffset(const size_t index, const double offset) const
Returns phi() reflected about offset (radians): offset - phi for phi >= 0 and -(offset + phi) otherwi...
DetectorInfoIterator< DetectorInfo > end()
bool hasMaskedDetectors() const
Returns true if there are masked detectors.
Kernel::Quat rotation(const size_t index) const
Returns the rotation of the detector with given index.
bool isMasked(const size_t index) const
Returns true if the detector is masked.
void setMasked(const size_t index, bool masked)
Set the mask flag of the detector with given index. Not thread safe.
std::vector< Kernel::V3D > allPositions() const
Returns the absolute positions of all detectors in a vector ordered by index.
const std::vector< detid_t > & detectorIDs() const
Returns a sorted vector of all detector IDs.
Kernel::V3D position(const size_t index) const
Returns the position of the detector with given index.
size_t getMemorySize() const
Return memory used by the detector info, in bytes.
std::shared_ptr< Geometry::Instrument const > m_instrument
std::shared_ptr< Geometry::ParameterInfo > m_parameterInfo
void clearMaskFlags()
Sets all mask flags to false (unmasked).
bool isEquivalent(const DetectorInfo &other) const
Returns true if the content of this is equivalent to the content of other.
const DetectorInfoIterator< const DetectorInfo > cend() const
std::vector< std::shared_ptr< const Geometry::IDetector > > m_lastDetector
double signedTwoTheta(const size_t index) const
Returns signed 2 theta (signed scattering angle w.r.t. to beam direction).
double l1() const
Returns L1 (distance from source to sample).
void setRotation(const size_t index, const Kernel::Quat &rotation)
Set the absolute rotation of the detector with given index. Not thread safe.
std::vector< size_t > m_lastIndex
double phi(const size_t index) const
Returns the angle of the detector position about the lab-frame z axis, atan2(y, x),...
Kernel::V3D sourcePosition() const
Returns the source position.
std::tuple< double, double, double > diffractometerConstants(const size_t index, std::vector< detid_t > &calibratedDets, std::vector< detid_t > &uncalibratedDets) const
const Geometry::IDetector & detector(const size_t index) const
Return a const reference to the detector with given index.
const DetectorInfoIterator< const DetectorInfo > cbegin() const
std::vector< Kernel::V3D > allScaleFactors() const
Returns the scale factors of all detectors in a vector ordered by index.
size_t indexOf(const detid_t id) const
Returns the index of the detector with the given detector ID.
size_t size() const
Returns the size of the DetectorInfo, i.e., the number of detectors in the instrument.
DetectorInfoIterator< DetectorInfo > begin()
std::unique_ptr< Beamline::DetectorInfo > m_detectorInfo
Pointer to the actual DetectorInfo object (non-wrapping part).
bool isMonitor(const size_t index) const
Returns true if the detector is a monitor.
bool isScanning() const
Returns true if the beamline has scanning detectors.
double azimuthal(const size_t index) const
DetectorInfo & operator=(const DetectorInfo &rhs)
Assigns the contents of the non-wrapping part of rhs to this.
double difcUncalibrated(const size_t index) const
detid_t detid(const size_t index) const
Returns the detector ID for the given logical detector index.
const std::vector< std::pair< Types::Core::DateAndTime, Types::Core::DateAndTime > > scanIntervals() const
Returns the scan interval of the detector with given index.
std::shared_ptr< const Geometry::IDetector > getDetectorPtr(const size_t index) const
Helper used by SpectrumInfo.
Interface class for detector objects.
Exception for errors associated with the instrument definition.
DetectorInfoIterator< DetectorInfo > DetectorInfoIt
DetectorInfoIterator< const DetectorInfo > DetectorInfoConstIt
MANTID_KERNEL_DLL double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset)
Calculate and return conversion factor from tof to d-spacing.
Kernel::Quat toQuat(const Eigen::Quaterniond &quat)
Converts Eigen::Quaterniond to Kernel::Quat.
Eigen::Vector3d toVector3d(const Kernel::V3D &vec)
Converts Kernel::V3D to Eigen::Vector3d.
Kernel::V3D toV3D(const Eigen::Vector3d &vec)
This header provides conversion helpers between vector and rotation types in MantidKernel and equival...
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
Eigen::Quaterniond toQuaterniond(const Kernel::Quat &quat)
Converts Kernel::Quat to Eigen::Quaterniond.
int32_t detid_t
Typedef for a detector ID.