Skip to content
Snippets Groups Projects
CentroidPeaksMD2Test.h 7.71 KiB
Newer Older
Lynch, Vickie's avatar
Lynch, Vickie committed
#ifndef MANTID_MDEVENTS_MDCENTROIDPEAKS2TEST_H_
#define MANTID_MDEVENTS_MDCENTROIDPEAKS2TEST_H_

#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidDataObjects/MDEventFactory.h"
Lynch, Vickie's avatar
Lynch, Vickie committed
#include "MantidGeometry/MDGeometry/MDHistoDimension.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
#include "MantidMDAlgorithms/CentroidPeaksMD2.h"
#include "MantidMDAlgorithms/CreateMDWorkspace.h"
#include "MantidMDAlgorithms/FakeMDEventData.h"
Lynch, Vickie's avatar
Lynch, Vickie committed
#include <boost/math/distributions/normal.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
Lynch, Vickie's avatar
Lynch, Vickie committed
#include <cxxtest/TestSuite.h>

using Mantid::API::AnalysisDataService;
using Mantid::Geometry::MDHistoDimension;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
using namespace Mantid::MDAlgorithms;
using Mantid::Kernel::V3D;

class CentroidPeaksMD2Test : public CxxTest::TestSuite {
Lynch, Vickie's avatar
Lynch, Vickie committed
public:
  void test_Init() {
Lynch, Vickie's avatar
Lynch, Vickie committed
    CentroidPeaksMD2 alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize())
    TS_ASSERT(alg.isInitialized())
Lynch, Vickie's avatar
Lynch, Vickie committed
  }

  //-------------------------------------------------------------------------------
  /** Create the (blank) MDEW */
  static void createMDEW() {
Lynch, Vickie's avatar
Lynch, Vickie committed
    // ---- Start with empty MDEW ----
    TS_ASSERT_THROWS_NOTHING(algC.initialize())
    TS_ASSERT(algC.isInitialized())
    TS_ASSERT_THROWS_NOTHING(algC.setProperty("Dimensions", "3"));
    TS_ASSERT_THROWS_NOTHING(
        algC.setProperty("Extents", "-10,10,-10,10,-10,10"));
    TS_ASSERT_THROWS_NOTHING(algC.setProperty("Names", "h,k,l"));
    TS_ASSERT_THROWS_NOTHING(algC.setProperty("Units", "-,-,-"));
    TS_ASSERT_THROWS_NOTHING(algC.setProperty("SplitInto", "5"));
    TS_ASSERT_THROWS_NOTHING(algC.setProperty("MaxRecursionDepth", "2"));
    TS_ASSERT_THROWS_NOTHING(
        algC.setPropertyValue("OutputWorkspace", "CentroidPeaksMD2Test_MDEWS"));
    TS_ASSERT_THROWS_NOTHING(algC.execute());
    TS_ASSERT(algC.isExecuted());
Lynch, Vickie's avatar
Lynch, Vickie committed
  }

  //-------------------------------------------------------------------------------
  /** Add a fake "peak"*/
  static void addPeak(size_t num, double x, double y, double z, double radius) {
Lynch, Vickie's avatar
Lynch, Vickie committed
    std::ostringstream mess;
    mess << num << ", " << x << ", " << y << ", " << z << ", " << radius;
    TS_ASSERT_THROWS_NOTHING(algF.initialize())
    TS_ASSERT(algF.isInitialized())
    TS_ASSERT_THROWS_NOTHING(
        algF.setPropertyValue("InputWorkspace", "CentroidPeaksMD2Test_MDEWS"));
    TS_ASSERT_THROWS_NOTHING(
        algF.setProperty("PeakParams", mess.str().c_str()));
    TS_ASSERT_THROWS_NOTHING(algF.setProperty("RandomSeed", "1234"));
    TS_ASSERT_THROWS_NOTHING(algF.execute());
    TS_ASSERT(algF.isExecuted());
Lynch, Vickie's avatar
Lynch, Vickie committed
  }

  //-------------------------------------------------------------------------------
  /** Run the CentroidPeaksMD2 with the given peak radius param */
  void doRun(V3D startPos, double PeakRadius, V3D expectedResult,
             std::string message,
             std::string OutputWorkspace = "CentroidPeaksMD2Test_Peaks") {
Lynch, Vickie's avatar
Lynch, Vickie committed
    // Make a fake instrument - doesn't matter, we won't use it really
    Instrument_sptr inst =
        ComponentCreationHelper::createTestInstrumentCylindrical(5);
Lynch, Vickie's avatar
Lynch, Vickie committed

    // --- Make a fake PeaksWorkspace in the given coordinate space ---
    PeaksWorkspace_sptr peakWS(new PeaksWorkspace());

    Peak pIn(inst, 1, 1.0, startPos);
Lynch, Vickie's avatar
Lynch, Vickie committed
    if (CoordinatesToUse == "Q (lab frame)")
      pIn.setQLabFrame(startPos, 1 /*sample to detector distance*/);
Lynch, Vickie's avatar
Lynch, Vickie committed
    else if (CoordinatesToUse == "Q (sample frame)")
      pIn.setQSampleFrame(startPos, 1 /*sample to detector distance*/);
Lynch, Vickie's avatar
Lynch, Vickie committed
    else if (CoordinatesToUse == "HKL")
      pIn.setHKL(startPos);
    peakWS->addPeak(pIn);
    TS_ASSERT_EQUALS(peakWS->getPeak(0).getIntensity(), 0.0);
    AnalysisDataService::Instance().addOrReplace("CentroidPeaksMD2Test_Peaks",
                                                 peakWS);
Lynch, Vickie's avatar
Lynch, Vickie committed

    CentroidPeaksMD2 alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize())
    TS_ASSERT(alg.isInitialized())
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("InputWorkspace", "CentroidPeaksMD2Test_MDEWS"));
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("PeaksWorkspace", "CentroidPeaksMD2Test_Peaks"));
    TS_ASSERT_THROWS_NOTHING(
        alg.setPropertyValue("OutputWorkspace", OutputWorkspace));
    TS_ASSERT_THROWS_NOTHING(alg.setProperty("PeakRadius", PeakRadius));
    TS_ASSERT_THROWS_NOTHING(alg.execute());
    TS_ASSERT(alg.isExecuted());
Lynch, Vickie's avatar
Lynch, Vickie committed

    peakWS = boost::dynamic_pointer_cast<PeaksWorkspace>(
        AnalysisDataService::Instance().retrieve(OutputWorkspace));
    TS_ASSERT(peakWS);
    if (!peakWS)
      return;
Lynch, Vickie's avatar
Lynch, Vickie committed

    // Compare the result to the expectation
    V3D result;
    IPeak &p = peakWS->getPeak(0);
Lynch, Vickie's avatar
Lynch, Vickie committed
    if (CoordinatesToUse == "Q (lab frame)")
      result = p.getQLabFrame();
    else if (CoordinatesToUse == "Q (sample frame)") {
Lynch, Vickie's avatar
Lynch, Vickie committed
      std::cerr << p.getGoniometerMatrix() << std::endl;
      result = p.getQSampleFrame();
    } else if (CoordinatesToUse == "HKL")
Lynch, Vickie's avatar
Lynch, Vickie committed
      result = p.getHKL();

    for (size_t i = 0; i < 3; i++)
      TSM_ASSERT_DELTA(message, result[i], expectedResult[i], 0.05);
Lynch, Vickie's avatar
Lynch, Vickie committed

    AnalysisDataService::Instance().remove("CentroidPeaksMD2Test_Peaks");
  }

  //-------------------------------------------------------------------------------
  /** Full test using faked-out peak data */
  void do_test_exec() {
Lynch, Vickie's avatar
Lynch, Vickie committed
    // --- Fake workspace with 3 peaks ------
    createMDEW();
    addPeak(1000, 0, 0., 0., 1.0);
    addPeak(1000, 2., 3., 4., 0.5);
    addPeak(1000, 6., 6., 6., 2.0);
    MDEventWorkspace3Lean::sptr mdews =
        AnalysisDataService::Instance().retrieveWS<MDEventWorkspace3Lean>(
            "CentroidPeaksMD2Test_MDEWS");
    TS_ASSERT_EQUALS(mdews->getNPoints(), 3000);
    TS_ASSERT_DELTA(mdews->getBox()->getSignal(), 3000.0, 1e-2);
    if (CoordinatesToUse == "HKL") {
      mdews->setCoordinateSystem(Mantid::Kernel::HKL);
      doRun(V3D(0., 0., 0.), 1.0, V3D(0., 0., 0.),
            "Start at the center, get the center");

      doRun(V3D(0.2, 0.2, 0.2), 1.8, V3D(0., 0., 0.), "Somewhat off center");
    } else if (CoordinatesToUse == "Q (lab frame)") {
      mdews->setCoordinateSystem(Mantid::Kernel::QLab);
    } else if (CoordinatesToUse == "Q (sample frame)") {
      mdews->setCoordinateSystem(Mantid::Kernel::QSample);
    doRun(V3D(2., 3., 4.), 1.0, V3D(2., 3., 4.),
          "Start at the center, get the center");
    doRun(V3D(1.5, 2.5, 3.5), 3.0, V3D(2., 3., 4.), "Pretty far off");
    doRun(V3D(1.0, 1.5, 2.0), 4.0, V3D(1.0, 1.5, 2.0),
          "Include two peaks, get the centroid of the two");
    doRun(V3D(8.0, 0.0, 1.0), 1.0, V3D(8.0, 0.0, 1.0),
          "Include no events, get no change");
    doRun(V3D(6., 6., 6.), 0.1, V3D(6., 6., 6.), "Small radius still works");
Lynch, Vickie's avatar
Lynch, Vickie committed

    AnalysisDataService::Instance().remove("CentroidPeaksMD2Test_MDEWS");
  }

  void test_exec_HKL() {
Lynch, Vickie's avatar
Lynch, Vickie committed
    CoordinatesToUse = "HKL";
    do_test_exec();
  }

  void test_exec_QSampleFrame() {
Lynch, Vickie's avatar
Lynch, Vickie committed
    CoordinatesToUse = "Q (sample frame)";
    do_test_exec();
  }

  void test_exec_QLabFrame() {
Lynch, Vickie's avatar
Lynch, Vickie committed
    CoordinatesToUse = "Q (lab frame)";
    do_test_exec();
  }

  void test_exec_HKL_NotInPlace() {
Lynch, Vickie's avatar
Lynch, Vickie committed
    CoordinatesToUse = "HKL";
    createMDEW();
    addPeak(1000, 0, 0., 0., 1.0);
    doRun(V3D(0., 0., 0.), 1.0, V3D(0., 0., 0.),
          "Start at the center, get the center",
          "CentroidPeaksMD2Test_MDEWS_outputCopy");
Lynch, Vickie's avatar
Lynch, Vickie committed
  }

private:
  std::string CoordinatesToUse;
};

#endif /* MANTID_MDEVENTS_MDCENTROIDPEAKS2TEST_H_ */