Skip to content

Commit 96141d9

Browse files
Update PaalmanPingsAbsorptionCorrection (#39210)
* Update BeamProfileFactory * Make requested changes * Swapped integration volume and sample object when doing Rasterize::calculate() * Update PaalmanPings * cppCheck and release notes * fix whole sample illuminated by beam * fix cppcheck * address review comments * fix cppcheck * correct Raster::Calculate call * fix cppcheck * add comment for V3D comparison * remove unused variable --------- Co-authored-by: Daniel Caballero <dlcaballero16@gmail.com>
1 parent 0774ff8 commit 96141d9

File tree

8 files changed

+200
-95
lines changed

8 files changed

+200
-95
lines changed

Framework/Algorithms/inc/MantidAlgorithms/PaalmanPingsAbsorptionCorrection.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "MantidAPI/MatrixWorkspace_fwd.h"
1111
#include "MantidAlgorithms/DllConfig.h"
1212
#include "MantidGeometry/Objects/IObject.h"
13+
#include "MantidGeometry/Rasterize.h"
1314
#include "MantidKernel/Material.h"
1415
#include "MantidKernel/V3D.h"
1516

@@ -73,6 +74,7 @@ class MANTID_ALGORITHMS_DLL PaalmanPingsAbsorptionCorrection final : public API:
7374
void defineProperties();
7475
void retrieveProperties();
7576
void initialiseCachedDistances();
77+
Geometry::Raster rasterize(const Geometry::IObject *object);
7678

7779
API::MatrixWorkspace_sptr m_inputWS; ///< A pointer to the input workspace
7880
const Geometry::IObject *m_sampleObject; ///< Local cache of sample object.

Framework/Algorithms/src/PaalmanPingsAbsorptionCorrection.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "MantidAPI/SpectrumInfo.h"
1313
#include "MantidAPI/WorkspaceGroup.h"
1414
#include "MantidAPI/WorkspaceUnitValidator.h"
15+
#include "MantidAlgorithms/BeamProfileFactory.h"
1516
#include "MantidDataObjects/WorkspaceCreation.h"
1617
#include "MantidGeometry/IDetector.h"
1718
#include "MantidGeometry/Instrument.h"
@@ -35,6 +36,8 @@ using namespace Geometry;
3536
using HistogramData::interpolateLinearInplace;
3637
using namespace Kernel;
3738
using namespace Mantid::DataObjects;
39+
using Mantid::Algorithms::BeamProfileFactory;
40+
using Mantid::Geometry::Raster;
3841

3942
namespace {
4043
// the maximum number of elements to combine at once in the pairwise summation
@@ -278,37 +281,46 @@ void PaalmanPingsAbsorptionCorrection::exec() {
278281
setProperty("OutputWorkspace", outWS);
279282
}
280283

281-
/// Calculate the distances for L1 (for both self-absorption and
282-
/// absorption by other object) and element size for each element in
283-
/// the sample and container
284-
void PaalmanPingsAbsorptionCorrection::initialiseCachedDistances() {
285-
// First, check if a 'gauge volume' has been defined. If not, it's the same as
286-
// the sample.
287-
auto integrationVolume = std::shared_ptr<const IObject>(m_sampleObject->clone());
284+
Raster PaalmanPingsAbsorptionCorrection::rasterize(const IObject *object) {
285+
IObject_const_sptr integrationVolume;
288286
if (m_inputWS->run().hasProperty("GaugeVolume")) {
289287
integrationVolume = constructGaugeVolume();
288+
} else {
289+
try {
290+
auto beamProfile = BeamProfileFactory::createBeamProfile(*m_inputWS->getInstrument(), Mantid::API::Sample());
291+
integrationVolume = beamProfile->getIntersectionWithSample(*object);
292+
} catch (const std::invalid_argument &) {
293+
// If createBeamProfile fails, the beam parameters are not defined
294+
// If getIntersectionWithSample fails, the beam misses the object
295+
// In either case we will just fall back to using the whole sample below.
296+
}
297+
if (integrationVolume == nullptr) {
298+
// If the beam profile is not defined, use the sample object
299+
integrationVolume = std::shared_ptr<const IObject>(object->clone());
300+
}
290301
}
291302

292-
auto raster = Geometry::Rasterize::calculate(m_beamDirection, *integrationVolume, *m_sampleObject, m_cubeSideSample);
303+
return Geometry::Rasterize::calculate(m_beamDirection, *integrationVolume, *object, m_cubeSideSample);
304+
}
305+
306+
/// Calculate the distances for L1 (for both self-absorption and
307+
/// absorption by other object) and element size for each element in
308+
/// the sample and container
309+
void PaalmanPingsAbsorptionCorrection::initialiseCachedDistances() {
310+
auto raster = rasterize(m_sampleObject);
293311
m_sampleVolume = raster.totalvolume;
294312
if (raster.l1.size() == 0)
295-
throw std::runtime_error("Failed to rasterize shape");
313+
throw std::runtime_error("Failed to rasterize sample shape");
296314
// move over the information
297315
m_numSampleVolumeElements = raster.l1.size();
298316
m_sampleL1s = std::move(raster.l1);
299317
m_sampleElementPositions = std::move(raster.position);
300318
m_sampleElementVolumes = std::move(raster.volume);
301-
302319
// now for the container
303-
integrationVolume = std::shared_ptr<const IObject>(m_containerObject->clone());
304-
if (m_inputWS->run().hasProperty("GaugeVolume")) {
305-
integrationVolume = constructGaugeVolume();
306-
}
307-
308-
raster = Geometry::Rasterize::calculate(m_beamDirection, *integrationVolume, *m_containerObject, m_cubeSideContainer);
320+
raster = rasterize(m_containerObject);
309321
m_containerVolume = raster.totalvolume;
310322
if (raster.l1.size() == 0)
311-
throw std::runtime_error("Failed to rasterize shape");
323+
throw std::runtime_error("Failed to rasterize container shape");
312324
// move over the information
313325
m_numContainerVolumeElements = raster.l1.size();
314326
m_containerL1s = std::move(raster.l1);

Framework/Algorithms/src/SampleCorrections/IBeamProfile.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,17 @@ Geometry::IObject_sptr IBeamProfile::getIntersectionWithSample(const Geometry::I
8080

8181
try {
8282
intersectionBox = defineActiveRegion(sampleBB);
83-
} catch (...) {
83+
} catch (const std::invalid_argument &) {
84+
// Exception means the beam missed the object and cannot create an intersection BoundingBox
8485
return nullptr;
8586
}
8687

88+
// If the intersection volume is the same as the sample volume use the sample volume instead of creating a new shape
89+
// V3D operator== comparison is done with a 1.0e-6 tolerance
90+
if ((sampleBB.minPoint() == intersectionBox.minPoint()) && (sampleBB.maxPoint() == intersectionBox.maxPoint())) {
91+
return std::shared_ptr<Geometry::IObject>(sample.clone());
92+
}
93+
8794
double yExtent = intersectionBox.yMax() - intersectionBox.yMin();
8895
double xExtent = intersectionBox.xMax() - intersectionBox.xMin();
8996
double zExtent = intersectionBox.zMax() - intersectionBox.zMin();

Framework/Algorithms/test/IBeamProfileTest.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,6 @@ class IBeamProfileTest : public CxxTest::TestSuite {
183183
const auto beamProfile = BeamProfileFactory::createBeamProfile(*experiment->getInstrument(), experiment->sample());
184184
const auto intersectionVolume = beamProfile->getIntersectionWithSample(*sample);
185185

186-
checkIntersectionVolume(intersectionVolume, 5., 20, 5.);
186+
checkIntersectionVolume(intersectionVolume, 5., 20., 5.);
187187
}
188188
};

0 commit comments

Comments
 (0)