Skip to content

Commit

Permalink
refs #9389. Vertical correction working for single detector.
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenArnold committed Apr 30, 2014
1 parent 5082076 commit 48acf64
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 13 deletions.
Expand Up @@ -12,6 +12,7 @@
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/CompositeValidator.h"
#include "MantidKernel/EnabledWhenProperty.h"
#include "MantidKernel/ListValidator.h"
#include "MantidKernel/MandatoryValidator.h"
#include "MantidGeometry/Instrument/DetectorGroup.h"
Expand Down Expand Up @@ -119,6 +120,11 @@ namespace Mantid

declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace", "", Direction::Output),
"An output workspace.");

setPropertySettings("SampleComponentName",
new Kernel::EnabledWhenProperty("SpectrumNumbersOfGroupedDetectors", IS_NOT_DEFAULT));
setPropertySettings("SpectrumNumbersOfGroupedDetectors",
new Kernel::EnabledWhenProperty("SampleComponentName", IS_NOT_DEFAULT));
}

//----------------------------------------------------------------------------------------------
Expand All @@ -128,6 +134,7 @@ namespace Mantid
{

MatrixWorkspace_sptr inWS = this->getProperty("InputWorkspace");
const std::string analysisMode = this->getProperty("AnalysisMode");
auto cloneWS = this->createChildAlgorithm("CloneWorkspace");
cloneWS->initialize();
cloneWS->setProperty("InputWorkspace", inWS);
Expand Down Expand Up @@ -244,26 +251,23 @@ namespace Mantid

auto referenceFrame = instrument->getReferenceFrame();

const double sampleToDetectorAlongBeam = sampleToDetector.scalar_prod(
referenceFrame->vecPointingAlongBeam());

const double thetaInRad = thetaInDeg * (M_PI / 180.0);

double acrossOffset = 0;

double beamOffset = detectorPosition.scalar_prod(referenceFrame->vecPointingAlongBeam());
double beamOffset = sampleToDetector.scalar_prod(referenceFrame->vecPointingAlongBeam()); // We just recalculate beam offset.

double upOffset = sampleToDetectorAlongBeam * std::sin(2.0 * thetaInRad);
double upOffset = beamOffset * std::tan(thetaInRad); // We only correct vertical position

auto moveComponentAlg = this->createChildAlgorithm("MoveInstrumentComponent");
moveComponentAlg->initialize();
moveComponentAlg->setProperty("Workspace", toCorrect);
moveComponentAlg->setProperty("ComponentName", detector->getName());
moveComponentAlg->setProperty("ComponentName", detector->getName()); // TODO. May need to move whole bank or linear detector etc.
moveComponentAlg->setProperty("RelativePosition", false);
// Movements
moveComponentAlg->setProperty(referenceFrame->pointingAlongBeamAxis(), beamOffset);
moveComponentAlg->setProperty(referenceFrame->pointingAlongBeamAxis(), detectorPosition.scalar_prod(referenceFrame->vecPointingAlongBeam()));
moveComponentAlg->setProperty(referenceFrame->pointingHorizontalAxis(), acrossOffset);
moveComponentAlg->setProperty(referenceFrame->pointingUpAxis(), upOffset);
moveComponentAlg->setProperty(referenceFrame->pointingUpAxis(), samplePosition.scalar_prod(referenceFrame->vecPointingUp()) + upOffset);
// Execute the movement.
moveComponentAlg->execute();

Expand Down
Expand Up @@ -5,9 +5,23 @@

#include "MantidAlgorithms/SpecularReflectionPositionCorrect.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/V3D.h"
#include "MantidGeometry/Instrument/ReferenceFrame.h"
#include <cmath>
#include <boost/tuple/tuple.hpp>

using Mantid::Algorithms::SpecularReflectionPositionCorrect;
using namespace Mantid::API;
using namespace Mantid::Kernel;
using namespace Mantid::Geometry;

namespace
{
typedef boost::tuple<double, double> VerticalHorizontalOffsetType;
}

class SpecularReflectionPositionCorrectTest: public CxxTest::TestSuite
{
Expand All @@ -23,6 +37,11 @@ class SpecularReflectionPositionCorrectTest: public CxxTest::TestSuite
delete suite;
}

SpecularReflectionPositionCorrectTest()
{
FrameworkManager::Instance();
}

void test_init()
{
SpecularReflectionPositionCorrect alg;
Expand Down Expand Up @@ -78,11 +97,12 @@ class SpecularReflectionPositionCorrectTest: public CxxTest::TestSuite
SpecularReflectionPositionCorrect alg;
alg.setRethrows(true);
alg.initialize();
alg.setProperty("InputWorkspace", WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument(1, 1, 1));
alg.setProperty("InputWorkspace",
WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument(1, 1, 1));
alg.setPropertyValue("OutputWorkspace", "test_out");
alg.setProperty("ThetaIn", 10.0);
std::vector<int> invalid(1, 1e7);
alg.setProperty("SpectrumNumbersOfGroupedDetectors", invalid);// Well outside range
std::vector<int> invalid(1, 1e7); // Well outside range
alg.setProperty("SpectrumNumbersOfGroupedDetectors", invalid); // Well outside range
TS_ASSERT_THROWS(alg.execute(), std::invalid_argument&);
}

Expand All @@ -91,15 +111,111 @@ class SpecularReflectionPositionCorrectTest: public CxxTest::TestSuite
SpecularReflectionPositionCorrect alg;
alg.setRethrows(true);
alg.initialize();
alg.setProperty("InputWorkspace", WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument(1, 1, 1));
alg.setProperty("InputWorkspace",
WorkspaceCreationHelper::create2DWorkspaceWithRectangularInstrument(1, 1, 1));
alg.setPropertyValue("OutputWorkspace", "test_out");
alg.setProperty("ThetaIn", 10.0);
std::vector<int> invalid(1, 1e7);
alg.setProperty("DetectorComponentName", "junk_value");// Well outside range
alg.setProperty("DetectorComponentName", "junk_value"); // Well outside range
TS_ASSERT_THROWS(alg.execute(), std::invalid_argument&);
}

VerticalHorizontalOffsetType determine_vertical_and_horizontal_offsets(MatrixWorkspace_sptr ws)
{
auto instrument = ws->getInstrument();
const V3D pointDetector = instrument->getComponentByName("point-detector")->getPos();
const V3D surfaceHolder = instrument->getComponentByName("some-surface-holder")->getPos();
const auto referenceFrame = instrument->getReferenceFrame();
const V3D sampleToDetector = pointDetector - surfaceHolder;

const double sampleToDetectorVerticalOffset = sampleToDetector.scalar_prod(
referenceFrame->vecPointingUp());
const double sampleToDetectorHorizontalOffset = sampleToDetector.scalar_prod(
referenceFrame->vecPointingAlongBeam());

return VerticalHorizontalOffsetType(sampleToDetectorVerticalOffset, sampleToDetectorHorizontalOffset);
}

void test_correct_point_detector_to_current_position()
{
auto loadAlg = AlgorithmManager::Instance().create("Load");
loadAlg->initialize();
loadAlg->setChild(true);
loadAlg->setProperty("Filename", "INTER00013460.nxs");
loadAlg->setPropertyValue("OutputWorkspace", "demo");
loadAlg->execute();
Workspace_sptr temp = loadAlg->getProperty("OutputWorkspace");
MatrixWorkspace_sptr toConvert = boost::dynamic_pointer_cast<MatrixWorkspace>(temp);

VerticalHorizontalOffsetType offsetTuple = determine_vertical_and_horizontal_offsets(toConvert); // Offsets before correction
const double sampleToDetectorVerticalOffset = offsetTuple.get<0>();
const double sampleToDetectorBeamOffset = offsetTuple.get<1>();

// Based on the current positions, calculate the current incident theta.
const double currentThetaInRad = std::atan(
sampleToDetectorVerticalOffset / sampleToDetectorBeamOffset);
const double currentThetaInDeg = currentThetaInRad * (180.0 / M_PI);

SpecularReflectionPositionCorrect alg;
alg.setRethrows(true);
alg.setChild(true);
alg.initialize();
alg.setProperty("InputWorkspace", toConvert);
alg.setPropertyValue("OutputWorkspace", "test_out");
alg.setProperty("ThetaIn", currentThetaInDeg);
alg.execute();
MatrixWorkspace_sptr corrected = alg.getProperty("OutputWorkspace");

VerticalHorizontalOffsetType offsetTupleCorrected = determine_vertical_and_horizontal_offsets(
corrected); // Positions after correction
const double sampleToDetectorVerticalOffsetCorrected = offsetTupleCorrected.get<0>();
const double sampleToDetectorBeamOffsetCorrected = offsetTupleCorrected.get<1>();

// Positions should be identical to original. No correction
TSM_ASSERT_DELTA("Vertical position should be unchanged", sampleToDetectorVerticalOffsetCorrected,
sampleToDetectorVerticalOffset, 1e-6);
TSM_ASSERT_DELTA("Beam position should be unchanged", sampleToDetectorBeamOffsetCorrected,
sampleToDetectorBeamOffset, 1e-6);
}

void test_correct_point_detector_position()
{
auto loadAlg = AlgorithmManager::Instance().create("Load");
loadAlg->initialize();
loadAlg->setChild(true);
loadAlg->setProperty("Filename", "INTER00013460.nxs");
loadAlg->setPropertyValue("OutputWorkspace", "demo");
loadAlg->execute();
Workspace_sptr temp = loadAlg->getProperty("OutputWorkspace");
MatrixWorkspace_sptr toConvert = boost::dynamic_pointer_cast<MatrixWorkspace>(temp);

const double thetaInDegrees = 10.0; //Desired theta in degrees.
const double thetaInRad = thetaInDegrees * (M_PI/180);
VerticalHorizontalOffsetType offsetTuple = determine_vertical_and_horizontal_offsets(toConvert); // Offsets before correction
const double sampleToDetectorBeamOffsetExpected = offsetTuple.get<1>();
const double sampleToDetectorVerticalOffsetExpected = std::tan(thetaInRad) * sampleToDetectorBeamOffsetExpected;

SpecularReflectionPositionCorrect alg;
alg.setRethrows(true);
alg.setChild(true);
alg.initialize();
alg.setProperty("InputWorkspace", toConvert);
alg.setPropertyValue("OutputWorkspace", "test_out");
alg.setProperty("ThetaIn", thetaInDegrees);
alg.execute();
MatrixWorkspace_sptr corrected = alg.getProperty("OutputWorkspace");

VerticalHorizontalOffsetType offsetTupleCorrected = determine_vertical_and_horizontal_offsets(
corrected); // Positions after correction
const double sampleToDetectorVerticalOffsetCorrected = offsetTupleCorrected.get<0>();
const double sampleToDetectorBeamOffsetCorrected = offsetTupleCorrected.get<1>();

// Positions should be identical to original. No correction
TSM_ASSERT_DELTA("Vertical position should be unchanged", sampleToDetectorVerticalOffsetCorrected,
sampleToDetectorVerticalOffsetExpected, 1e-6);
TSM_ASSERT_DELTA("Beam position should be unchanged", sampleToDetectorBeamOffsetCorrected,
sampleToDetectorBeamOffsetExpected, 1e-6);
}

};

Expand Down

0 comments on commit 48acf64

Please sign in to comment.