Unverified Commit a097e6b6 authored by Gagik Vardanyan's avatar Gagik Vardanyan Committed by GitHub
Browse files

Figaro refactor loader (#30825)

* cleanup of some hardcoded values in the loader

* cleanup loading chopper gap and source to sample

* added new figaro data from cycle 203 for tests

* cleaned up chopper settings, edelay, x-axis

* cleanup of some hardcoded values in the loader

* cleanup loading chopper gap and source to sample

* added new figaro data from cycle 203 for tests

* cleaned up chopper settings, edelay, x-axis

* revise the unit test to adjust for renamed entries

* fix retrieval of sample angle

* fixed one test tofFigaro

* fixed one more test

* removed unneeded warning

* removed comment out code

* make all the tests pass for the laoder

* remove figaro tests with old files

* formatting code

* rerun formatting

* rerun formatting
parent c46b084a
......@@ -28,7 +28,6 @@ public:
/// Algorithm's version for identification. @see Algorithm::version
int version() const override { return 1; }
const std::vector<std::string> seeAlso() const override { return {"LoadNexus"}; }
std::map<std::string, std::string> validateInputs() override;
/// Algorithm's category for search and find. @see Algorithm::category
const std::string category() const override { return "DataHandling\\Nexus;ILL\\Reflectometry"; }
/// Algorithm's summary. @see Algorithm::summary
......@@ -37,17 +36,16 @@ public:
"FIGARO).";
}
double doubleFromRun(const std::string &entryName) const;
double sampleDetectorDistance() const;
double sampleHorizontalOffset() const;
double sourceSampleDistance() const;
private:
/// ID tags for supported instruments.
enum class Supported { D17, FIGARO };
void init() override;
void exec() override;
double sampleDetectorDistance() const;
double sourceSampleDistance() const;
void sampleHorizontalOffset();
void sampleAngle(NeXus::NXEntry &entry);
void initWorkspace(const std::vector<std::vector<int>> &monitorsData);
void initNames(NeXus::NXEntry &entry);
void initPixelWidth();
......@@ -70,26 +68,26 @@ private:
double collimationAngle() const;
double detectorAngle() const;
double offsetAngle(const double peakCentre, const double detectorCentre, const double detectorDistance) const;
API::MatrixWorkspace_sptr m_localWorkspace;
Supported m_instrument{Supported::D17}; ///< Name of the instrument
size_t m_acqMode{1}; ///< Acquisition mode (1 TOF (default), 0 monochromatic)
Supported m_instrument{Supported::D17};
size_t m_acqMode{1}; ///(1: TOF (default), 0: monochromatic)
size_t m_numberOfChannels{0};
double m_tofDelay{0.0};
size_t m_numberOfHistograms{0};
double m_channelWidth{0.0};
std::string m_detectorAngleName;
std::string m_sampleAngleName;
std::string m_offsetFrom;
std::string m_chopper1Name;
std::string m_chopper2Name;
double m_tofDelay{0.0};
double m_channelWidth{0.0};
double m_detectorAngle{0.0};
double m_detectorDistance{0.0};
double m_pixelWidth{0.0};
double m_sampleZOffset{0.0};
double m_sourceDistance{0.0};
double m_sampleAngle{0.0};
Mantid::DataHandling::LoadHelper m_loader;
Mantid::Types::Core::DateAndTime m_startTime;
API::MatrixWorkspace_sptr m_localWorkspace;
};
} // namespace DataHandling
......
......@@ -29,10 +29,10 @@ class LoadILLReflectometryTest : public CxxTest::TestSuite {
private:
const std::string m_d17DirectBeamFile{"ILL/D17/317369.nxs"};
const std::string m_d17File{"ILL/D17/317370.nxs"};
const std::string m_d17Cycle203File{"ILL/D17/564343.nxs"};
const std::string m_figaroFile{"ILL/Figaro/598488.nxs"};
const std::string m_d17File_2018{"ILL/D17/000001.nxs"};
const std::string m_figaroFile_2018{"ILL/Figaro/000002.nxs"};
const std::string m_d17Cycle203File{"ILL/D17/564343.nxs"};
const std::string m_figaroDirectBeamFile{"ILL/Figaro/709922.nxs"};
const std::string m_figaroReflectedBeamFile{"ILL/Figaro/709886.nxs"};
// Name of the default output workspace
const std::string m_outWSName{"LoadILLReflectometryTest_OutputWS"};
......@@ -122,7 +122,7 @@ public:
void testExecD17() { loadSpecific(m_d17File, m_outWSName, emptyProperties()); }
void testExecFigaro() { loadSpecific(m_figaroFile, m_outWSName, emptyProperties()); }
void testExecFigaro() { loadSpecific(m_figaroDirectBeamFile, m_outWSName, emptyProperties()); }
void testTOFD17() {
MatrixWorkspace_sptr output;
......@@ -174,19 +174,19 @@ public:
MatrixWorkspace_sptr output;
auto prop = emptyProperties();
prop.emplace_back("XUnit", "TimeOfFlight");
getWorkspaceFor(output, m_figaroFile, m_outWSName, prop);
getWorkspaceFor(output, m_figaroDirectBeamFile, m_outWSName, prop);
TS_ASSERT_EQUALS(output->getAxis(0)->unit()->unitID(), "TOF")
const auto &run = output->run();
const auto channelWidth = run.getPropertyValueAsType<double>("PSD.time_of_flight_0");
const auto channelCount = static_cast<size_t>(run.getPropertyValueAsType<double>("PSD.time_of_flight_1"));
const auto tofDelay = run.getPropertyValueAsType<double>("PSD.time_of_flight_2") +
run.getPropertyValueAsType<double>("Theta.edelay_delay");
run.getPropertyValueAsType<double>("MainParameters.edelay_delay");
// Using choppers 1 and 4.
const auto chopper1Speed = run.getPropertyValueAsType<double>("CH1.rotation_speed");
const auto chopper1Speed = run.getPropertyValueAsType<double>("chopper1.rotation_speed");
const double chopper1Phase{0.}; // The value in NeXus is trash.
const auto chopper2Phase = run.getPropertyValueAsType<double>("CH4.phase");
const auto chopper2Phase = run.getPropertyValueAsType<double>("chopper2.phase");
const auto pOffset = run.getPropertyValueAsType<double>("CollAngle.poff");
const auto openOffset = run.getPropertyValueAsType<double>("CollAngle.openOffset");
const auto openOffset = run.getPropertyValueAsType<double>("CollAngle.open_offset");
const auto tof0 =
tofDelay - 60e6 * (pOffset - 45. + chopper2Phase - chopper1Phase + openOffset) / (2. * 360. * chopper1Speed);
TS_ASSERT_EQUALS(output->blocksize(), channelCount)
......@@ -200,11 +200,11 @@ public:
TS_ASSERT_EQUALS(run.getProperty("PSD.time_of_flight_0")->units(), "")
TS_ASSERT_EQUALS(run.getProperty("PSD.time_of_flight_1")->units(), "")
TS_ASSERT_EQUALS(run.getProperty("PSD.time_of_flight_2")->units(), "")
TS_ASSERT_EQUALS(run.getProperty("Theta.edelay_delay")->units(), "microsec")
TS_ASSERT_EQUALS(run.getProperty("CH1.rotation_speed")->units(), "rpm")
TS_ASSERT_EQUALS(run.getProperty("CH4.phase")->units(), "degree")
TS_ASSERT_EQUALS(run.getProperty("CollAngle.poff")->units(), "uu")
TS_ASSERT_EQUALS(run.getProperty("CollAngle.openOffset")->units(), "uu")
TS_ASSERT_EQUALS(run.getProperty("MainParameters.edelay_delay")->units(), "usec")
TS_ASSERT_EQUALS(run.getProperty("chopper1.rotation_speed")->units(), "rpm")
TS_ASSERT_EQUALS(run.getProperty("chopper2.phase")->units(), "deg")
TS_ASSERT_EQUALS(run.getProperty("CollAngle.poff")->units(), "deg")
TS_ASSERT_EQUALS(run.getProperty("CollAngle.open_offset")->units(), "deg")
}
void testSampleAndSourcePositionsD17() {
......@@ -236,11 +236,11 @@ public:
MatrixWorkspace_sptr output;
auto prop = emptyProperties();
prop.emplace_back("Xunit", "TimeOfFlight");
getWorkspaceFor(output, m_figaroFile, m_outWSName, prop);
getWorkspaceFor(output, m_figaroDirectBeamFile, m_outWSName, prop);
const auto &run = output->run();
const auto chopperCentre = run.getPropertyValueAsType<double>("ChopperSetting.chopperpair_sample_distance") * 1.e-3;
const auto incomingDeflectionAngle = run.getPropertyValueAsType<double>("CollAngle.actual_coll_angle");
const auto sampleZOffset = run.getPropertyValueAsType<double>("Theta.sampleHorizontalOffset") * 1.e-3;
const auto sampleZOffset = run.getPropertyValueAsType<double>("Theta.sample_horizontal_offset") * 1.e-3;
const auto sourceSample = chopperCentre + sampleZOffset / std::cos(incomingDeflectionAngle / 180. * M_PI);
const auto &spectrumInfo = output->spectrumInfo();
const auto l1 = spectrumInfo.l1();
......@@ -253,8 +253,8 @@ public:
TS_ASSERT_EQUALS(sourcePos.X(), 0.)
TS_ASSERT_EQUALS(sourcePos.Y(), 0.)
TS_ASSERT_EQUALS(sourcePos.Z(), -sourceSample)
TS_ASSERT_EQUALS(run.getProperty("CollAngle.actual_coll_angle")->units(), "uu")
TS_ASSERT_EQUALS(run.getProperty("Theta.sampleHorizontalOffset")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("CollAngle.actual_coll_angle")->units(), "deg")
TS_ASSERT_EQUALS(run.getProperty("Theta.sample_horizontal_offset")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("ChopperSetting.chopperpair_sample_distance")->units(), "mm")
}
......@@ -290,12 +290,12 @@ public:
auto prop = emptyProperties();
prop.emplace_back("Measurement", "ReflectedBeam");
prop.emplace_back("BraggAngle", "1.5");
getWorkspaceFor(output, m_figaroFile, m_outWSName, prop);
getWorkspaceFor(output, m_figaroReflectedBeamFile, m_outWSName, prop);
const auto &spectrumInfo = output->spectrumInfo();
const auto &run = output->run();
const double centre = run.getPropertyValueAsType<double>("reduction.line_position");
TS_ASSERT_DELTA(centre, 173.38, 0.001);
const double centreAngle = (spectrumInfo.twoTheta(173) + spectrumInfo.twoTheta(174)) / 2;
TS_ASSERT_DELTA(centre, 62.834, 0.001);
const double centreAngle = (spectrumInfo.twoTheta(62) + spectrumInfo.twoTheta(63)) / 2;
TS_ASSERT_DELTA(centreAngle * 180 / M_PI, 3., 0.1);
}
......@@ -303,12 +303,12 @@ public:
MatrixWorkspace_sptr output;
auto prop = emptyProperties();
prop.emplace_back("Measurement", "DirectBeam");
getWorkspaceFor(output, m_figaroFile, m_outWSName, prop);
getWorkspaceFor(output, m_figaroDirectBeamFile, m_outWSName, prop);
const auto &spectrumInfo = output->spectrumInfo();
const auto &run = output->run();
const double centre = run.getPropertyValueAsType<double>("reduction.line_position");
TS_ASSERT_DELTA(centre, 173.38, 0.001);
const double centreAngle = (spectrumInfo.twoTheta(173) + spectrumInfo.twoTheta(174)) / 2;
TS_ASSERT_DELTA(centre, 62.589, 0.001);
const double centreAngle = (spectrumInfo.twoTheta(62) + spectrumInfo.twoTheta(63)) / 2;
TS_ASSERT_DELTA(centreAngle * 180 / M_PI, 0., 0.1);
}
......@@ -321,7 +321,7 @@ public:
void testPropertiesFigaro() {
MatrixWorkspace_sptr output;
getWorkspaceFor(output, m_figaroFile, m_outWSName, emptyProperties());
getWorkspaceFor(output, m_figaroDirectBeamFile, m_outWSName, emptyProperties());
commonProperties(output, "FIGARO");
}
......@@ -334,16 +334,16 @@ public:
loader.setRethrows(true);
TS_ASSERT_THROWS_NOTHING(loader.initialize())
TS_ASSERT(loader.isInitialized())
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", this->m_figaroFile_2018))
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", this->m_figaroDirectBeamFile))
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("OutputWorkspace", this->m_outWSName))
TS_ASSERT_THROWS_NOTHING(loader.execute())
TS_ASSERT(loader.isExecuted())
const auto output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(this->m_outWSName);
const auto &run = output->run();
TS_ASSERT(output)
TS_ASSERT_EQUALS(run.getProperty("Distance.edelay_delay")->units(),
"microsec") // a time in the distance field!
TS_ASSERT_EQUALS(run.getProperty("Distance.inter-slit_distance")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("MainParameters.edelay_delay")->units(),
"usec") // a time in the distance field!
TS_ASSERT_EQUALS(run.getProperty("Distance.S2_S3")->units(), "mm")
}
void testSourceAndSampleLocationsFigaro() {
......@@ -353,16 +353,16 @@ public:
loader.setRethrows(true);
TS_ASSERT_THROWS_NOTHING(loader.initialize())
TS_ASSERT(loader.isInitialized())
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", this->m_figaroFile_2018))
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", this->m_figaroDirectBeamFile))
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("OutputWorkspace", this->m_outWSName))
TS_ASSERT_THROWS_NOTHING(loader.execute())
TS_ASSERT(loader.isExecuted())
const auto output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(this->m_outWSName);
TS_ASSERT(output)
const auto &run = output->run();
TS_ASSERT_EQUALS(run.getProperty("Distance.D1")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("Distance.D0")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("Distance.dist_chop_samp")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("Distance.sample_DH1")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("Distance.sample_DH2")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("Distance.Sample_CenterOfDetector_distance")->units(), "mm")
}
void testSourceAndSampleLocationsD17() {
......@@ -387,14 +387,14 @@ public:
loader.setRethrows(true);
TS_ASSERT_THROWS_NOTHING(loader.initialize())
TS_ASSERT(loader.isInitialized())
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", this->m_figaroFile_2018))
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename", this->m_figaroDirectBeamFile))
TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("OutputWorkspace", this->m_outWSName))
TS_ASSERT_THROWS_NOTHING(loader.execute())
TS_ASSERT(loader.isExecuted())
const auto output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(this->m_outWSName);
TS_ASSERT(output)
const auto v1 = loader.doubleFromRun("Theta.sampleHorizontalOffset");
const auto v2 = loader.doubleFromRun("Distance.sampleHorizontalOffset");
const auto v1 = loader.doubleFromRun("Theta.sample_horizontal_offset");
const auto v2 = loader.doubleFromRun("Distance.sample_changer_horizontal_offset");
TS_ASSERT_EQUALS(v1, v2)
// Unused variables -> if used in future they may simplify the loader
TS_ASSERT_EQUALS(loader.doubleFromRun("Theta.actual_directDan"), 0.)
......@@ -447,21 +447,21 @@ public:
void testSlitConfigurationFigaro() {
MatrixWorkspace_sptr output;
getWorkspaceFor(output, m_figaroFile, m_outWSName, emptyProperties());
getWorkspaceFor(output, m_figaroDirectBeamFile, m_outWSName, emptyProperties());
auto instrument = output->getInstrument();
auto slit1 = instrument->getComponentByName("slit2");
auto slit2 = instrument->getComponentByName("slit3");
const auto &run = output->run();
// The S3 position is missing in the NeXus file; use a hard-coded value.
const double collimationAngle = run.getPropertyValueAsType<double>("CollAngle.actual_coll_angle") / 180. * M_PI;
const double sampleOffset = output->run().getPropertyValueAsType<double>("Theta.sampleHorizontalOffset") * 1e-3;
const double slitZOffset = sampleOffset / std::cos(collimationAngle);
const double S3z = -0.368 - slitZOffset;
const double slitSeparation = run.getPropertyValueAsType<double>("Theta.inter-slit_distance") * 1e-3;
const double S2z = S3z - slitSeparation;
TS_ASSERT_EQUALS(slit1->getPos(), V3D(0.0, 0.0, S2z))
TS_ASSERT_EQUALS(slit2->getPos(), V3D(0.0, 0.0, S3z))
TS_ASSERT_EQUALS(run.getProperty("Theta.inter-slit_distance")->units(), "mm")
const double s2z = run.getPropertyValueAsType<double>("Distance.S2_Sample") * 1e-3;
const double s3z = run.getPropertyValueAsType<double>("Distance.S3_Sample") * 1e-3;
const double s23 = run.getPropertyValueAsType<double>("Distance.S2_S3") * 1e-3;
const double ds = s2z - s3z;
TS_ASSERT_DELTA(s2z, 2.412, 1e-3);
TS_ASSERT_DELTA(s3z, 0.247, 1e-3);
TS_ASSERT_DELTA(ds, s23, 1e-3);
TS_ASSERT_EQUALS(run.getProperty("Distance.S2_S3")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("Distance.S2_Sample")->units(), "mm")
TS_ASSERT_EQUALS(run.getProperty("Distance.S3_Sample")->units(), "mm")
}
};
......
......@@ -115,24 +115,6 @@ class ReflectometryILLPreprocessTest(unittest.TestCase):
two_theta_fg = (outWS.spectrumInfo().twoTheta(peakLeft) + outWS.spectrumInfo().twoTheta(peakRight))/2.
self.assertAlmostEqual(numpy.rad2deg(two_theta_fg), 3.097, delta=0.01)
def testDefaultRunFIGARO(self):
args = {
'Run': 'ILL/Figaro/000002.nxs',
'OutputWorkspace': 'outWS',
'rethrow': True,
'child': True
}
alg = create_algorithm('ReflectometryILLPreprocess', **args)
assertRaisesNothing(self, alg.execute)
outWS = alg.getProperty('OutputWorkspace').value
self.assertEqual(outWS.getAxis(0).getUnit().caption(), 'Wavelength')
fgCentre = outWS.run().getProperty(common.SampleLogs.LINE_POSITION).value
self.assertAlmostEqual(fgCentre, 127.801, delta=0.001)
peakLeft = math.floor(fgCentre)
peakRight = peakLeft + 1
two_theta_fg = (outWS.spectrumInfo().twoTheta(peakLeft) + outWS.spectrumInfo().twoTheta(peakRight)) / 2.
self.assertAlmostEqual(numpy.rad2deg(two_theta_fg), 0., delta=0.1)
def testTwoInputFiles(self):
outWSName = 'outWS'
args = {
......
......@@ -22,10 +22,6 @@ class ReflectometryILLSumForegroundTest(unittest.TestCase):
Measurement='ReflectedBeam',
ForegroundHalfWidth=5,
OutputWorkspace='rb')
ReflectometryILLPreprocess(Run='ILL/Figaro/000002.nxs',
Measurement='DirectBeam',
ForegroundHalfWidth=5,
OutputWorkspace='fig_db')
@classmethod
def tearDownClass(cls):
......@@ -59,13 +55,6 @@ class ReflectometryILLSumForegroundTest(unittest.TestCase):
self.checkOutput(mtd['rb_inq_frg'], 1045)
def testDirectBeamFigaro(self):
# the direct beam
ReflectometryILLSumForeground(InputWorkspace='fig_db',
OutputWorkspace='fig_db_frg')
self.checkOutput(mtd['fig_db_frg'], 971)
def checkOutput(self, ws, blocksize):
self.assertTrue(ws)
......
......@@ -43,5 +43,16 @@
<parameter name="sample_logs_fail_tolerances" type="string">
<value val="0, 0, 0" />
</parameter>
<parameter name="chopper_window_opening">
<!-- Chopper opening window [degrees]-->
<value val="45.0" valid-to="2020-07-31T23:59:59"/>
<value val="20.0" valid-from="2020-08-01T00:00:00"/>
</parameter>
<parameter name="chopper_gap_unit" type="string">
<!-- The unit of the chopper gap -->
<value val="cm" valid-to="2019-08-19T23:59:59"/>
<value val="m" valid-from="2019-08-20T00:00:00" valid-to="2020-07-31T23:59:59"/>
<value val="mm" valid-from="2020-08-01T00:00:00"/>
</parameter>
</component-link>
</parameter-file>
<?xml version="1.0" encoding="UTF-8" ?>
<parameter-file instrument="FIGARO" valid-from="2017-01-31 23:59:59">
<parameter-file instrument="FIGARO">
<component-link name="FIGARO">
<parameter name="deltaE-mode" type="string">
......@@ -24,7 +24,7 @@
<parameter name="sample_logs_fail_tolerances" type="string">
<value val="0, 0, 0, 0" />
</parameter>
<!-- ConjoinXRuns behavior when merging sample logs when using Stitch1D or Stitch1DMany. -->
<!-- ConjoinXRuns behavior when merging sample logs when using Stitch1D or Stitch1DMany. -->
<parameter name="conjoin_sample_logs_sum" type="string">
<value val="" />
</parameter>
......@@ -42,6 +42,18 @@
</parameter>
<parameter name="conjoin_sample_logs_fail_tolerances" type="string">
<value val="" />
</parameter>
</parameter>
<parameter name="chopper_window_opening">
<!-- Chopper opening window [degrees]-->
<value val="45.0"/>
</parameter>
<parameter name="DH1Z">
<!-- The sample to first height motor position along Z [m]-->
<value val="1.135" />
</parameter>
<parameter name="DH2Z">
<!-- The sample to second height motor position along Z [m]-->
<value val="2.077" />
</parameter>
</component-link>
</parameter-file>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment