Skip to content

Commit

Permalink
refs #9184. Employ and test position correction multidetector
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenArnold committed Jun 3, 2014
1 parent d0d12dd commit 759476e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 63 deletions.
Expand Up @@ -52,7 +52,7 @@ namespace Mantid
virtual const std::string category() const;

/// Convert to an IvsQ workspace. Performs detector positional corrections based on the component name and the theta value.
Mantid::API::MatrixWorkspace_sptr toIvsQ(API::MatrixWorkspace_sptr toConvert, const bool correctPosition,
Mantid::API::MatrixWorkspace_sptr toIvsQ(API::MatrixWorkspace_sptr& toConvert, const bool correctPosition,
OptionalDouble& thetaInDeg, const bool isPointDetector);

private:
Expand All @@ -71,8 +71,7 @@ namespace Mantid
Mantid::Geometry::IComponent_const_sptr getDetectorComponent(Mantid::Geometry::Instrument_const_sptr inst, const bool isPointDetector);

/// Correct detector positions.
void correctPosition(API::MatrixWorkspace_sptr toCorrect, const double& thetaInDeg,
Geometry::IComponent_const_sptr sample, Geometry::IComponent_const_sptr detector, const bool isPointDetector);
API::MatrixWorkspace_sptr correctPosition(API::MatrixWorkspace_sptr& toCorrect, const double& thetaInDeg, const bool isPointDetector);

/// Sum spectra.
Mantid::API::MatrixWorkspace_sptr sumSpectraOverRange(API::MatrixWorkspace_sptr inWS, const int startIndex, const int endIndex);
Expand Down
76 changes: 17 additions & 59 deletions Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp
Expand Up @@ -93,9 +93,9 @@ namespace Mantid
for (auto it = specToWSIndexMap.begin(); it != specToWSIndexMap.end(); ++it, ++i)
{
keys[i] = static_cast<int>(it->first);
++i;
}
std::sort(keys.begin(), keys.end()); // Sort the keys, as the order is not guaranteed in the map.

return keys;
}
}
Expand Down Expand Up @@ -232,49 +232,12 @@ namespace Mantid
* Correct the position of the detectors based on the input theta value.
* @param toCorrect : Workspace to correct detector positions on.
* @param thetaInDeg : Theta in degrees to use in correction calculations.
* @param sample : Pointer to the sample
* @param detector : Pointer to a given detector
* @param isPointDetector : True if using point detector analysis
* @return Copy with positions corrected.
*/
void ReflectometryReductionOne::correctPosition(API::MatrixWorkspace_sptr toCorrect,
const double& thetaInDeg, IComponent_const_sptr sample, IComponent_const_sptr detector,
const bool isPointDetector)
MatrixWorkspace_sptr ReflectometryReductionOne::correctPosition(API::MatrixWorkspace_sptr& toCorrect,
const double& thetaInDeg, const bool isPointDetector)
{
/*
auto instrument = toCorrect->getInstrument();
const V3D detectorPosition = detector->getPos();
const V3D samplePosition = sample->getPos();
const V3D sampleToDetector = detectorPosition - samplePosition;
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 upOffset = sampleToDetectorAlongBeam * std::sin(2.0 * thetaInRad);
auto moveComponentAlg = this->createChildAlgorithm("MoveInstrumentComponent");
moveComponentAlg->initialize();
moveComponentAlg->setProperty("Workspace", toCorrect);
moveComponentAlg->setProperty("ComponentName", detector->getName());
moveComponentAlg->setProperty("RelativePosition", false);
// Movements
moveComponentAlg->setProperty(referenceFrame->pointingAlongBeamAxis(), beamOffset);
moveComponentAlg->setProperty(referenceFrame->pointingHorizontalAxis(), acrossOffset);
moveComponentAlg->setProperty(referenceFrame->pointingUpAxis(), upOffset);
// Execute the movement.
moveComponentAlg->execute();
*/

g_log.debug("Correcting position using theta.");

auto correctPosAlg = this->createChildAlgorithm("SpecularReflectionPositionCorrect");
Expand All @@ -283,31 +246,32 @@ namespace Mantid

const std::string analysisMode = this->getProperty("AnalysisMode");
correctPosAlg->setProperty("AnalysisMode", analysisMode);
auto instrument = toCorrect->getInstrument();
IComponent_const_sptr sample = this->getSurfaceSampleComponent(instrument);
const std::string sampleComponentName = this->getProperty("SampleComponentName");
correctPosAlg->setProperty("SampleComponentName", sample->getName());
correctPosAlg->setProperty("TwoThetaIn", thetaInDeg * 2);

if (isPointDetector)
{
IComponent_const_sptr detector = this->getDetectorComponent(instrument, isPointDetector);
correctPosAlg->setProperty("DetectorComponentName", detector->getName());
}
else
{
auto specNumbers = getSpectrumNumbers(toCorrect);
g_log.notice("In Order?");
std::stringstream buffer;
for(size_t t = 0; t < specNumbers.size();++t)
correctPosAlg->setProperty("SpectrumNumbersOfDetectors", specNumbers);
for(size_t t = 0; t < specNumbers.size(); ++t)
{
buffer << specNumbers[t] << std::endl;
std::stringstream buffer;
buffer << "Writing out: " << specNumbers[t];
g_log.notice(buffer.str());
}
g_log.notice(buffer.str());

correctPosAlg->setProperty("SpectrumNumbersOfDetectors", specNumbers);
}
correctPosAlg->execute();
MatrixWorkspace_sptr outWS = correctPosAlg->getProperty("OutputWorkspace");
toCorrect = outWS;
MatrixWorkspace_sptr corrected = correctPosAlg->getProperty("OutputWorkspace");

return corrected;
}

/**
Expand All @@ -320,7 +284,7 @@ namespace Mantid
* @return
*/
Mantid::API::MatrixWorkspace_sptr ReflectometryReductionOne::toIvsQ(
API::MatrixWorkspace_sptr toConvert, const bool bCorrectPosition, OptionalDouble& thetaInDeg,
API::MatrixWorkspace_sptr& toConvert, const bool bCorrectPosition, OptionalDouble& thetaInDeg,
const bool isPointDetector)
{
/*
Expand Down Expand Up @@ -354,15 +318,9 @@ namespace Mantid
thetaInDeg = twoTheta / 2;

}
else if (bCorrectPosition) // This probably ought to be an automatic decision. How about making a guess about sample position holder and detector names. But also allowing the two component names (sample and detector) to be passed in.
else if (bCorrectPosition)
{
g_log.debug("Correcting detector position");

auto instrument = toConvert->getInstrument();
IComponent_const_sptr detector = this->getDetectorComponent(instrument, isPointDetector);
IComponent_const_sptr sample = this->getSurfaceSampleComponent(instrument);

correctPosition(toConvert, thetaInDeg.get(), sample, detector, isPointDetector);
toConvert = correctPosition(toConvert, thetaInDeg.get(), isPointDetector);
}

// Always convert units.
Expand Down
Expand Up @@ -288,7 +288,6 @@ def test_multidetector_run(self):
alg.set_InputWorkspace(real_run[0])
alg.set_AnalysisMode("MultiDetectorAnalysis")
alg.set_CorrectDetectorPositions(False)
alg.set_DetectorComponentName('lineardetector')
alg.set_ProcessingInstructions("3, 10") # Fictional values
alg.set_RegionOfDirectBeam("20, 30") # Fictional values
alg.set_ThetaIn(0.1) # Fictional values
Expand All @@ -301,3 +300,20 @@ def test_multidetector_run(self):
self.assertTrue(isinstance(out_ws_q, mantid.api.MatrixWorkspace), "Should be a matrix workspace")
self.assertEqual("MomentumTransfer", out_ws_q.getAxis(0).getUnit().unitID())

def test_correct_positions_multi_detector(self):
alg = self.construct_standard_algorithm()
real_run = Load('POLREF00004699.nxs')
alg.set_InputWorkspace(real_run[0])
alg.set_AnalysisMode("MultiDetectorAnalysis")
alg.set_CorrectDetectorPositions(True)
alg.set_ProcessingInstructions("73")
alg.set_RegionOfDirectBeam("28,29")
alg.set_ThetaIn(0.49/2)
out_ws_q, out_ws_lam, theta = alg.execute()

pos = out_ws_lam.getInstrument().getComponentByName('lineardetector').getPos()
self.assertAlmostEqual(-0.05714, pos.Z(), 3, "Vertical correction is wrong. Recorded as: " + str(pos.Z()))




0 comments on commit 759476e

Please sign in to comment.