28namespace SolidAngleMethods {
37using namespace Kernel;
39using namespace Geometry;
40using namespace SolidAngleMethods;
42namespace SolidAngleHelpers {
57 auto inPlane = sampleDetVec;
59 return sampleDetVec.cosAngle(inPlane);
84 const double pixelArea)
87 if (method.find(
"Vertical") != std::string::npos) {
89 }
else if (method.find(
"Horizontal") != std::string::npos) {
117 const double scaledPixelArea =
m_pixelArea * scaleFactor[0] * scaleFactor[1];
118 return scaledPixelArea * cosTheta / (
l2 *
l2);
128 const double scaledPixelArea =
m_pixelArea * scaleFactor[0] * scaleFactor[1];
129 return scaledPixelArea * cosAlpha / (
l2 *
l2);
141 const double scaledPixelArea =
m_pixelArea * scaleFactor[0] * scaleFactor[1];
142 return scaledPixelArea * cosAlpha * cosAlpha * cosAlpha / (
l2 *
l2 * cosTheta * cosTheta);
151 std::make_shared<InstrumentValidator>()),
152 "This workspace is used to identify the instrument to use "
154 "spectra to create a solid angle for. If the Max and Min "
155 "spectra values are\n"
156 "not provided one solid angle will be created for each "
157 "spectra in the input\n"
160 "The name of the workspace to be created as the output of "
161 "the algorithm. A workspace of this name will be created "
162 "and stored in the Analysis Data Service.");
164 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
165 mustBePositive->setLower(0);
167 "The index number of the first spectrum for which to find "
171 "The index of the last spectrum whose solid angle is to be "
172 "found (default: the\n"
173 "last spectrum in the workspace)");
178 "Select the method to calculate the Solid Angle.");
186 int m_MinSpec =
getProperty(
"StartWorkspaceIndex");
189 const auto numberOfSpectra =
static_cast<int>(inputWS->getNumberHistograms());
192 if (m_MinSpec > numberOfSpectra) {
193 g_log.
warning(
"StartWorkspaceIndex out of range! Set to 0.");
197 m_MaxSpec = numberOfSpectra - 1;
198 if (m_MaxSpec > numberOfSpectra - 1 || m_MaxSpec < m_MinSpec) {
199 g_log.
warning(
"EndWorkspaceIndex out of range! Set to max detector number");
200 m_MaxSpec = numberOfSpectra - 1;
205 outputWS->setDistribution(
true);
206 outputWS->setYUnit(
"");
207 outputWS->setYUnitLabel(
"Steradian");
210 const auto &spectrumInfo = inputWS->spectrumInfo();
211 const auto &detectorInfo = inputWS->detectorInfo();
212 const auto &componentInfo = inputWS->componentInfo();
216 double pixelArea = 0.;
219 using namespace SolidAngleHelpers;
221 const auto instrument = inputWS->getInstrument();
222 if (instrument->hasParameter(
"x-pixel-size") && instrument->hasParameter(
"y-pixel-size")) {
223 const double pixelSizeX = instrument->getNumberParameter(
"x-pixel-size")[0] * MM_TO_METERS;
224 const double pixelSizeY = instrument->getNumberParameter(
"y-pixel-size")[0] * MM_TO_METERS;
225 pixelArea = pixelSizeX * pixelSizeY;
228 throw std::runtime_error(
"Missing necessary instrument parameters for non generic shape: "
229 "x-pixel-size and y-pixel-size [in mm].");
233 std::unique_ptr<SolidAngleCalculator> solidAngleCalculator;
235 solidAngleCalculator = std::make_unique<GenericShape>(componentInfo, detectorInfo, method, pixelArea);
237 solidAngleCalculator = std::make_unique<Rectangle>(componentInfo, detectorInfo, method, pixelArea);
239 solidAngleCalculator = std::make_unique<Tube>(componentInfo, detectorInfo, method, pixelArea);
241 solidAngleCalculator = std::make_unique<Wing>(componentInfo, detectorInfo, method, pixelArea);
244 std::atomic<size_t> failCount{0};
245 Progress prog(
this, 0.0, 1.0, numberOfSpectra);
248 for (
int j = m_MinSpec; j <= m_MaxSpec; ++j) {
251 if (spectrumInfo.hasDetectors(j)) {
252 double solidAngle = 0.0;
253 for (
const auto detID : inputWS->getSpectrum(j).getDetectorIDs()) {
254 const auto index = detectorInfo.indexOf(detID);
255 if (!detectorInfo.isMasked(
index) && !detectorInfo.isMonitor(
index)) {
256 solidAngle += solidAngleCalculator->solidAngle(
index);
259 outputWS->mutableY(j)[0] = solidAngle;
267 g_log.
warning() <<
"min max total" << m_MinSpec <<
" " << m_MaxSpec <<
" " << numberOfSpectra;
269 auto &outputSpectrumInfo = outputWS->mutableSpectrumInfo();
271 for (
int j = 0; j < m_MinSpec; ++j) {
274 outputSpectrumInfo.setMasked(j,
true);
279 for (
int j = m_MaxSpec + 1; j < numberOfSpectra; ++j) {
282 outputSpectrumInfo.setMasked(j,
true);
286 if (failCount != 0) {
288 <<
" spectra. The solid angle will be set to zero for "
289 "those detectors.\n";
298 outputWS.
mutableX(wsIndex)[0] = inputWS.
x(wsIndex).front();
299 outputWS.
mutableX(wsIndex)[1] = inputWS.
x(wsIndex).back();
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
Base MatrixWorkspace Abstract Class.
HistogramData::HistogramX & mutableX(const size_t index) &
const HistogramData::HistogramX & x(const size_t index) const
HistogramData::HistogramE & mutableE(const size_t index) &
HistogramData::HistogramY & mutableY(const size_t index) &
Helper class for reporting progress from algorithms.
A property class for workspaces.
void initSpectrum(const API::MatrixWorkspace &input, API::MatrixWorkspace &output, const size_t j)
SolidAngle::initSpectrum Sets the default value for the spectra for which solid angle is not calculat...
void exec() override
Executes the algorithm.
void init() override
Initialisation method.
ComponentInfo : Provides a component centric view on to the instrument.
Kernel::V3D scaleFactor(const size_t componentIndex) const
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
double l2(const size_t index) const
Returns L2 (distance from sample to spectrum).
Kernel::V3D position(const size_t index) const
Returns the position of the detector with given index.
const Geometry::IDetector & detector(const size_t index) const
Return a const reference to the detector with given index.
virtual double solidAngle(const Kernel::V3D &observer) const =0
Finds the approximate solid angle covered by the component when viewed from the point given.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
void setX(const double xx) noexcept
Set is x position.
double cosAngle(const V3D &) const
cos(Angle) between this and another vector
void setY(const double yy) noexcept
Set is y position.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
constexpr double MM_TO_METERS
static const std::string HORIZONTAL_WING
static const std::string VERTICAL_TUBE
static const std::string GENERIC_SHAPE
static const std::string HORIZONTAL_TUBE
static const std::string RECTANGLE
static const std::string VERTICAL_WING
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Returns the angle between the sample-to-pixel vector and its projection on the X-Z (vertical tube) or...
virtual ~AlphaAngleCalculator()=default
AlphaAngleCalculator(const DetectorInfo &detectorInfo)
virtual void project(V3D &v) const =0
double getAlpha(size_t index) const
const DetectorInfo & m_detectorInfo
void project(V3D &v) const override
void project(V3D &v) const override
double solidAngle(size_t index) const override
double solidAngle(size_t index) const override
Creates the solid angle calculator based on the selected method.
virtual ~SolidAngleCalculator()=default
const DetectorInfo & m_detectorInfo
std::unique_ptr< const AlphaAngleCalculator > m_alphaAngleCalculator
const ComponentInfo & m_componentInfo
virtual double solidAngle(size_t index) const =0
SolidAngleCalculator(const ComponentInfo &componentInfo, const DetectorInfo &detectorInfo, const std::string &method, const double pixelArea)
double solidAngle(size_t index) const override
double solidAngle(size_t index) const override
@ Input
An input workspace.
@ Output
An output workspace.