Mantid
Loading...
Searching...
No Matches
BeamProfileFactory.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2022 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation BeamProfileFactory,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7
14#include "MantidKernel/V3D.h"
15
16#include <algorithm>
17#include <cmath>
18
19namespace Mantid::Algorithms {
20std::unique_ptr<IBeamProfile> BeamProfileFactory::createBeamProfile(const Geometry::Instrument &instrument,
21 const API::Sample &sample) {
22 const auto frame = instrument.getReferenceFrame();
23 const auto source = instrument.getSource();
24
25 const std::string beamShapeParam = source->getParameterAsString("beam-shape");
26 if (beamShapeParam == "Slit") {
27 const auto beamWidthParam = source->getNumberParameter("beam-width");
28 const auto beamHeightParam = source->getNumberParameter("beam-height");
29 if (beamWidthParam.size() == 1 && beamHeightParam.size() == 1) {
30 return std::make_unique<RectangularBeamProfile>(*frame, source->getPos(), beamWidthParam[0], beamHeightParam[0]);
31 }
32 } else if (beamShapeParam == "Circle") {
33 const auto beamRadiusParam = source->getNumberParameter("beam-radius");
34 if (beamRadiusParam.size() == 1) {
35 return std::make_unique<CircularBeamProfile>(*frame, source->getPos(), beamRadiusParam[0]);
36 }
37 }
38 // revert to rectangular profile enclosing sample dimensions if no return by this point
39 if (!sample.getShape().hasValidShape() && !sample.hasEnvironment()) {
40 throw std::invalid_argument("Cannot determine beam profile without a sample shape and environment");
41 }
42 Kernel::V3D bboxMin;
43 Kernel::V3D bboxMax;
44 if (sample.getShape().hasValidShape()) {
45 bboxMin = sample.getShape().getBoundingBox().minPoint();
46 bboxMax = sample.getShape().getBoundingBox().maxPoint();
47 } else {
48 bboxMin = sample.getEnvironment().boundingBox().minPoint();
49 bboxMax = sample.getEnvironment().boundingBox().maxPoint();
50 }
51 // Beam profile is always centred on zero, so its half-extent must reach the furthest sample face
52 // from the origin on either side. Using 2*max(|min|, |max|) keeps the beam valid when the sample
53 // is offset and/or rotated such that its bbox lies entirely in a negative half-space.
54 const auto hor = frame->pointingHorizontal();
55 const auto up = frame->pointingUp();
56 const double beamWidth = 2 * std::max(std::abs(bboxMin[hor]), std::abs(bboxMax[hor]));
57 const double beamHeight = 2 * std::max(std::abs(bboxMin[up]), std::abs(bboxMax[up]));
58 return std::make_unique<RectangularBeamProfile>(*frame, source->getPos(), beamWidth, beamHeight);
59}
60} // namespace Mantid::Algorithms
This class stores information about the sample used in particular run.
Definition Sample.h:33
bool hasEnvironment() const
Definition Sample.cpp:129
const Geometry::IObject & getShape() const
Return the sample shape.
Definition Sample.cpp:102
const Geometry::SampleEnvironment & getEnvironment() const
Get a reference to the sample's environment.
Definition Sample.cpp:136
static std::unique_ptr< IBeamProfile > createBeamProfile(const Geometry::Instrument &instrument, const API::Sample &sample)
const Kernel::V3D & minPoint() const
Returns the min point of the box.
Definition BoundingBox.h:89
const Kernel::V3D & maxPoint() const
Returns the min point of the box.
Definition BoundingBox.h:91
virtual const BoundingBox & getBoundingBox() const =0
Return cached value of axis-aligned bounding box.
virtual bool hasValidShape() const =0
Base Instrument Class.
Definition Instrument.h:49
IComponent_const_sptr getSource() const
Gets a pointer to the source.
std::shared_ptr< const ReferenceFrame > getReferenceFrame() const
Get refernce Frame.
Geometry::BoundingBox boundingBox() const
Class for 3D vectors.
Definition V3D.h:34