31#include "MantidNexus/NexusFile.h"
36using namespace Geometry;
37using namespace Kernel;
39using Types::Core::DateAndTime;
43constexpr size_t D7_NUMBER_PIXELS = 132;
45constexpr size_t NUMBER_MONITORS = 2;
47constexpr size_t TOF_MODE_ON = 1;
57 if (descriptor.isEntry(
"/entry0/D7")) {
75 return "Loads ILL D7 instrument polarized diffraction nexus files.";
88 "File path of the data file to load");
90 "The output workspace.");
91 const std::vector<std::string> positionCalibrationOptions{
"None",
"Nexus",
"YIGFile"};
92 declareProperty(
"PositionCalibration",
"None", std::make_shared<StringListValidator>(positionCalibrationOptions),
93 "Select the type of pixel position calibration. If None, the pixel "
94 "positions are read from IDF file. If Nexus, the positions are read from "
95 "Nexus file. If YIGFile, then the calibration twotheta data is loaded "
96 "from a user-defined calibration file.");
99 "File path of the YIG calibration data file to load.");
101 std::make_unique<Kernel::EnabledWhenProperty>(
"PositionCalibration",
IS_EQUAL_TO,
"YIGFile"));
103 declareProperty(
"TransposeMonochromatic",
false,
"Transpose the 2D workspace with monochromatic data",
105 const std::vector<std::string> TOFUnitOptions{
"UncalibratedTime",
"TimeChannels"};
106 declareProperty(
"TOFUnits", TOFUnitOptions[0], std::make_shared<StringListValidator>(TOFUnitOptions),
107 "The choice of X-axis units for Time-Of-Flight data.");
111 std::map<std::string, std::string> issues;
113 issues[
"PositionCalibration"] =
"YIG-based position calibration of detectors requested but "
114 "the file was not provided.";
129 progress.report(
"Loading the detector polarization analysis data");
132 progress.report(
"Loading the metadata");
135 progress.report(
"Sorting polarisations");
138 setProperty(
"OutputWorkspace", outputWorkspaceGroup);
151 for (
auto entryNumber = 0; entryNumber < static_cast<int>((dataRoot.
groups().size())); entryNumber++) {
155 std::string startTime = entry.
getString(
"start_time");
162 workspace->mutableRun().addProperty(
"start_time", startTime);
171 const std::vector<double> axis =
prepareAxes(entry);
180 for (
auto monitor_no =
static_cast<int>(D7_NUMBER_PIXELS);
181 monitor_no < static_cast<int>(D7_NUMBER_PIXELS + NUMBER_MONITORS); ++monitor_no) {
183 entry,
"monitor" +
std::to_string(monitor_no + 1 -
static_cast<int>(D7_NUMBER_PIXELS)));
214 for (
auto workspaceId = 0; workspaceId < static_cast<int>(
m_outputWorkspaceGroup.size()); ++workspaceId) {
217 auto const entryName = std::string(
"entry" +
std::to_string(workspaceId));
224 g_log.
debug() <<
"Failed to open nexus file \"" <<
m_fileName <<
"\" in read mode: " << e.what() <<
"\n";
237 const size_t nSpectra = D7_NUMBER_PIXELS + NUMBER_MONITORS;
241 acquisitionMode.
load();
245 timeOfFlightInfo.
load();
257 auto lblUnit = std::dynamic_pointer_cast<Kernel::Units::Label>(UnitFactory::Instance().
create(
"Label"));
261 workspace->getAxis(0)->unit() = UnitFactory::Instance().create(
"TOF");
264 workspace->getAxis(0)->unit() = UnitFactory::Instance().create(
"Wavelength");
270 std::string polDirection = entry.
getString(
"D7/POL/actual_state");
271 std::string flipperState = entry.
getString(
"D7/POL/actual_stateB1B2");
272 workspace->setTitle(polDirection.substr(0, 1) +
"_" + flipperState);
285 const NXEntry &entry,
const int bankId) {
287 auto const nPixelsPerBank =
workspace->getInstrument()->getIntParameter(
"number_pixels_per_bank")[0];
288 std::vector<double>
twoTheta(
static_cast<int>(nPixelsPerBank));
292 twoThetaPixels.
load();
293 float *twoThetaDataStart = twoThetaPixels();
294 float *twoThetaDataEnd = twoThetaDataStart + nPixelsPerBank;
295 twoTheta.assign(twoThetaDataStart, twoThetaDataEnd);
299 loadIpf->setProperty(
"Workspace",
workspace);
305 m_wavelength = currentBank->getNumberParameter(
"wavelength")[0];
307 for (
auto pixel_no = 0; pixel_no < static_cast<int>(nPixelsPerBank); pixel_no++) {
308 twoTheta[pixel_no] = currentBank->getNumberParameter(
"twoTheta_pixel_" +
std::to_string(pixel_no + 1))[0];
322 std::vector<double> bankParameters;
327 auto slope = currentBank->getNumberParameter(
"gradient")[0];
328 bankParameters.push_back(slope);
329 auto offset = currentBank->getNumberParameter(
"offset")[0];
330 bankParameters.push_back(offset);
332 return bankParameters;
343 auto const nBanks = instrument->getIntParameter(
"number_banks")[0];
344 auto const nPixelsPerBank = instrument->getIntParameter(
"number_pixels_per_bank")[0];
346 auto &componentInfo =
workspace->mutableComponentInfo();
347 for (
auto bank_no = 0; bank_no < static_cast<int>(nBanks); ++bank_no) {
354 instrument->getComponentByName(std::string(
"bank" +
std::to_string(bank_no + 2)));
355 const auto componentIndex = componentInfo.indexOf(currentBank->getComponentID());
356 componentInfo.setRotation(componentIndex,
rotation);
359 std::vector<double> bankParameters{1, 0};
363 for (
auto pixel_no = 0; pixel_no < static_cast<int>(nPixelsPerBank); ++pixel_no) {
364 auto const pixelIndex = bank_no *
static_cast<int>(nPixelsPerBank) + pixel_no;
365 auto const pixel = componentInfo.componentID(pixelIndex);
367 double radius, theta, phi;
369 position.spherical(radius, bankParameters[0] * twoThetaBank[0] - bankParameters[1] - twoThetaPixels[pixel_no],
371 componentInfo.setPosition(pixelIndex,
position);
385 std::vector<double> axes;
389 timeOfFlightInfo.
load();
390 auto channelWidth =
static_cast<double>(timeOfFlightInfo[0]);
392 auto tofDelay = timeOfFlightInfo[2];
393 for (
auto channel_no = 0; channel_no <= static_cast<int>(
m_numberOfChannels); channel_no++) {
395 axes.push_back(tofDelay + channel_no * channelWidth);
397 axes.push_back(channel_no);
401 double wavelength = 0;
406 wavelengthNexus.
load();
407 wavelength = wavelengthNexus[0];
409 axes.push_back(
static_cast<double>(wavelength * 0.99));
410 axes.push_back(
static_cast<double>(wavelength * 1.01));
431 changeSign->initialize();
432 changeSign->setProperty(
"InputWorkspace",
workspace);
433 changeSign->setProperty(
"OutputWorkspace",
"__unused_for_child");
434 changeSign->setProperty(
"Axis",
"Y");
435 changeSign->setProperty(
"Formula",
"-y");
436 changeSign->execute();
437 return changeSign->getProperty(
"OutputWorkspace");
447 transpose->initialize();
448 transpose->setProperty(
"InputWorkspace",
workspace);
449 transpose->setProperty(
"OutputWorkspace",
"__unused_for_child");
450 transpose->execute();
451 return transpose->getProperty(
"OutputWorkspace");
461 if (outputGroupSize < 2) {
464 std::vector<int> sortedWorkspaceIds(outputGroupSize);
465 std::map<const std::string, int> polarisationsOrder{{
"OFF", 0}, {
"ZPO", 1}, {
"XPO", 3},
466 {
"YPO", 5}, {
"XPO-YPO", 7}, {
"XPO+YPO", 9}};
467 for (
auto workspaceId = 0; workspaceId < outputGroupSize; workspaceId++) {
469 auto flipperState = ws->mutableRun().getLogData(
"POL.actual_stateB1B2")->value();
470 std::string polarisation = ws->mutableRun().getLogData(
"POL.actual_state")->value();
472 if (polarisationsOrder.count(polarisation) > 0) {
473 sortedId = polarisationsOrder[polarisation];
474 if (flipperState ==
"ON")
477 sortedWorkspaceIds[workspaceId] = sortedId;
479 for (
auto workspaceId : sortedWorkspaceIds) {
IPeaksWorkspace_sptr workspace
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
#define DECLARE_NEXUS_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro wh...
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
@ Load
allowed here which will be passed to the algorithm
Defines an interface to an algorithm that loads a file so that it can take part in the automatic sele...
Helper class for reporting progress from algorithms.
A property class for workspaces.
LoadILLPolarizedDiffraction : Loads ILL polarized diffraction nexus files from instrument D7.
API::WorkspaceGroup_sptr sortPolarisations()
Ensures that the order of flipper state values is 'ON' and then 'OFF' for each polarisation orientati...
API::MatrixWorkspace_sptr transposeMonochromatic(const API::MatrixWorkspace_sptr &)
Transposes given 2D workspace with monochromatic data.
void moveTwoTheta(const Nexus::NXEntry &, const API::MatrixWorkspace_sptr &)
Rotates each pixel to its corresponding 2theta read from the file.
API::MatrixWorkspace_sptr initStaticWorkspace(const Nexus::NXEntry &)
Initializes the output workspace based on the resolved instrument.
void init() override
Initialize the algorithm's properties.
const std::string name() const override
Algorithms name for identification.
std::vector< double > prepareAxes(const Nexus::NXEntry &)
Prepares values for bin edges depending of measurement type.
void loadData()
Loads the polarized detector data, sets up workspaces and labels according to the measurement type an...
std::string m_instName
instrument name to load the IDF
LoadILLPolarizedDiffraction()
Constructor.
std::vector< double > loadBankParameters(const API::MatrixWorkspace_sptr &, const int)
Loads offsets and slopes for each detector bank from the workspace entry.
std::string m_fileName
file name to load
void loadMetaData()
Dumps the metadata from the file for each entry separately.
std::vector< API::MatrixWorkspace_sptr > m_outputWorkspaceGroup
vector with output workspaces
size_t m_numberOfChannels
std::vector< double > loadTwoThetaDetectors(const API::MatrixWorkspace_sptr &, const Nexus::NXEntry &, const int)
Loads 2theta for each detector pixel from either the nexus file or the Instrument Parameter File.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
const std::string category() const override
Algorithm's category for identification.
int version() const override
Algorithm's version for identification.
API::MatrixWorkspace_sptr convertSpectrumAxis(API::MatrixWorkspace_sptr)
Converts the spectrum axis to scattering angle.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
void exec() override
Executes the algorithm.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void debug(const std::string &msg)
Logs at debug level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
static const UnitLabel EmptyLabel
Empty label.
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
Class that provides for a standard Nexus exception.
std::string getString(const std::string &name) const
Returns a string.
NXFloat openNXFloat(const std::string &name) const
Creates and opens a float dataset.
std::vector< NXClassInfo > & groups() const
Returns a list of all classes (or groups) in this NXClass.
void close()
Close this class.
NXInt openNXInt(const std::string &name) const
Creates and opens an integer dataset.
Templated class implementation of NXDataSet.
void load()
Read all of the datablock in.
Implements NXentry Nexus class.
Implements NXroot Nexus class.
NXEntry openEntry(const std::string &name)
Opens an entry – a topmost Nexus class.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
void addNexusFieldsToWsRun(Nexus::File &filehandle, API::Run &runDetails, const std::string &entryName="", bool useFullAddress=false)
Add properties from a nexus file to the workspace run.
Nexus::NXInt getIntDataset(const Nexus::NXEntry &, const std::string &)
Fetches NXInt data from the requested group name in the entry provided.
void fillStaticWorkspace(const API::MatrixWorkspace_sptr &, const Mantid::Nexus::NXInt &, const std::vector< double > &xAxis, int64_t initialSpectrum=0, bool pointData=false, const std::vector< detid_t > &detectorIDs=std::vector< int >(), const std::set< detid_t > &acceptedID=std::set< int >(), const std::tuple< short, short, short > &axisOrder=std::tuple< short, short, short >(0, 1, 2))
Fills workspace with histogram data from provided data structure.
std::string dateTimeInIsoFormat(const std::string &)
Parses the date as formatted at the ILL: 29-Jun-12 11:27:26 and converts it to the ISO format used in...
void loadEmptyInstrument(const API::MatrixWorkspace_sptr &ws, const std::string &instrumentName, const std::string &instrumentAddress="")
Loads empty instrument of chosen name into a provided workspace.
void replaceZeroErrors(const API::MatrixWorkspace_sptr &, double)
Replaces errors of bins with zero counts with provided value.
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.