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.pathExists(
"/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 start_time = entry.
getString(
"start_time");
171 std::string dataName =
"data/Detector_data";
177 for (
auto pixel_no = 0; pixel_no < static_cast<int>(D7_NUMBER_PIXELS); ++pixel_no) {
178 auto &spectrum =
workspace->mutableY(pixel_no);
179 auto &errors =
workspace->mutableE(pixel_no);
180 for (
auto channel_no = 0; channel_no < static_cast<int>(
m_numberOfChannels); ++channel_no) {
181 unsigned int counts = data(pixel_no, 0, channel_no);
182 spectrum[channel_no] = counts;
184 errors[channel_no] = 1.0;
186 errors[channel_no] = std::sqrt(counts);
193 for (
auto monitor_no =
static_cast<int>(D7_NUMBER_PIXELS);
194 monitor_no < static_cast<int>(D7_NUMBER_PIXELS + NUMBER_MONITORS); ++monitor_no) {
196 "monitor" +
std::to_string(monitor_no + 1 -
static_cast<int>(D7_NUMBER_PIXELS)) +
"/data");
198 auto &spectrum =
workspace->mutableY(monitor_no);
199 auto &errors =
workspace->mutableE(monitor_no);
200 for (
auto channel_no = 0; channel_no < static_cast<int>(
m_numberOfChannels); channel_no++) {
201 unsigned int counts = monitorData(0, 0, channel_no);
202 spectrum[channel_no] = counts;
204 errors[channel_no] = 1.0;
206 errors[channel_no] = std::sqrt(counts);
235 NXstatus nxStat = NXopen(
m_fileName.c_str(), NXACC_READ, &nxHandle);
237 if (nxStat != NX_ERROR) {
238 for (
auto workspaceId = 0; workspaceId < static_cast<int>(
m_outputWorkspaceGroup.size()); ++workspaceId) {
241 auto const entryName = std::string(
"entry" +
std::to_string(workspaceId));
260 const size_t nSpectra = D7_NUMBER_PIXELS + NUMBER_MONITORS;
264 acquisitionMode.
load();
268 timeOfFlightInfo.
load();
293 std::string polDirection = entry.
getString(
"D7/POL/actual_state");
294 std::string flipperState = entry.
getString(
"D7/POL/actual_stateB1B2");
295 workspace->setTitle(polDirection.substr(0, 1) +
"_" + flipperState);
304 const std::string &startTime) {
307 workspace->mutableRun().addProperty(
"start_time", startTime);
310 loadInst->setPropertyValue(
"Filename",
m_instName +
"_Definition.xml");
312 loadInst->setProperty(
"RewriteSpectraMap",
OptionalBool(
true));
325 const NXEntry &entry,
const int bankId) {
327 auto const nPixelsPerBank =
workspace->getInstrument()->getIntParameter(
"number_pixels_per_bank")[0];
328 std::vector<double>
twoTheta(
static_cast<int>(nPixelsPerBank));
332 twoThetaPixels.
load();
333 float *twoThetaDataStart = twoThetaPixels();
334 float *twoThetaDataEnd = twoThetaDataStart + nPixelsPerBank;
335 twoTheta.assign(twoThetaDataStart, twoThetaDataEnd);
339 loadIpf->setProperty(
"Workspace",
workspace);
345 m_wavelength = currentBank->getNumberParameter(
"wavelength")[0];
347 for (
auto pixel_no = 0; pixel_no < static_cast<int>(nPixelsPerBank); pixel_no++) {
348 twoTheta[pixel_no] = currentBank->getNumberParameter(
"twoTheta_pixel_" +
std::to_string(pixel_no + 1))[0];
362 std::vector<double> bankParameters;
367 auto slope = currentBank->getNumberParameter(
"gradient")[0];
368 bankParameters.push_back(slope);
369 auto offset = currentBank->getNumberParameter(
"offset")[0];
370 bankParameters.push_back(offset);
372 return bankParameters;
383 auto const nBanks = instrument->getIntParameter(
"number_banks")[0];
384 auto const nPixelsPerBank = instrument->getIntParameter(
"number_pixels_per_bank")[0];
386 auto &componentInfo =
workspace->mutableComponentInfo();
387 for (
auto bank_no = 0; bank_no < static_cast<int>(nBanks); ++bank_no) {
394 instrument->getComponentByName(std::string(
"bank" +
std::to_string(bank_no + 2)));
395 const auto componentIndex = componentInfo.indexOf(currentBank->getComponentID());
396 componentInfo.setRotation(componentIndex,
rotation);
399 std::vector<double> bankParameters{1, 0};
403 for (
auto pixel_no = 0; pixel_no < static_cast<int>(nPixelsPerBank); ++pixel_no) {
404 auto const pixelIndex = bank_no *
static_cast<int>(nPixelsPerBank) + pixel_no;
405 auto const pixel = componentInfo.componentID(pixelIndex);
407 double radius, theta, phi;
409 position.spherical(
radius, bankParameters[0] * twoThetaBank[0] - bankParameters[1] - twoThetaPixels[pixel_no],
411 componentInfo.setPosition(pixelIndex,
position);
425 std::vector<double> axes;
429 timeOfFlightInfo.
load();
430 auto channelWidth =
static_cast<double>(timeOfFlightInfo[0]);
432 auto tofDelay = timeOfFlightInfo[2];
433 for (
auto channel_no = 0; channel_no <= static_cast<int>(
m_numberOfChannels); channel_no++) {
435 axes.push_back(tofDelay + channel_no * channelWidth);
437 axes.push_back(channel_no);
441 double wavelength = 0;
446 wavelengthNexus.
load();
447 wavelength = wavelengthNexus[0];
449 axes.push_back(
static_cast<double>(wavelength * 0.99));
450 axes.push_back(
static_cast<double>(wavelength * 1.01));
471 changeSign->initialize();
472 changeSign->setProperty(
"InputWorkspace",
workspace);
473 changeSign->setProperty(
"OutputWorkspace",
"__unused_for_child");
474 changeSign->setProperty(
"Axis",
"Y");
475 changeSign->setProperty(
"Formula",
"-y");
476 changeSign->execute();
477 return changeSign->getProperty(
"OutputWorkspace");
487 transpose->initialize();
488 transpose->setProperty(
"InputWorkspace",
workspace);
489 transpose->setProperty(
"OutputWorkspace",
"__unused_for_child");
490 transpose->execute();
491 return transpose->getProperty(
"OutputWorkspace");
501 if (outputGroupSize < 2) {
504 std::vector<int> sortedWorkspaceIds(outputGroupSize);
505 std::map<const std::string, int> polarisationsOrder{{
"OFF", 0}, {
"ZPO", 1}, {
"XPO", 3},
506 {
"YPO", 5}, {
"XPO-YPO", 7}, {
"XPO+YPO", 9}};
507 for (
auto workspaceId = 0; workspaceId < outputGroupSize; workspaceId++) {
509 auto flipperState = ws->mutableRun().getLogData(
"POL.actual_stateB1B2")->value();
510 std::string polarisation = ws->mutableRun().getLogData(
"POL.actual_state")->value();
512 if (polarisationsOrder.count(polarisation) > 0) {
513 sortedId = polarisationsOrder[polarisation];
514 if (flipperState ==
"ON")
517 sortedWorkspaceIds[workspaceId] = sortedId;
519 for (
auto workspaceId : sortedWorkspaceIds) {
IPeaksWorkspace_sptr workspace
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
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.
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::vector< double > prepareAxes(const NeXus::NXEntry &)
Prepares values for bin edges depending of measurement type.
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.
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.
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.
void moveTwoTheta(const NeXus::NXEntry &, const API::MatrixWorkspace_sptr &)
Rotates each pixel to its corresponding 2theta read from the file.
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::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 loadInstrument(const API::MatrixWorkspace_sptr &, const std::string &)
Runs LoadInstrument as child to link the instrument to workspace.
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)
Defines a wrapper around a file whose internal structure can be accessed using the NeXus API.
OptionalBool : Tri-state bool.
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.
NXInt openNXInt(const std::string &name) const
Creates and opens an integer dataset.
void close()
Close this class.
std::vector< NXClassInfo > & groups() const
Returns a list of all classes (or groups) in this NXClass.
NXDataSetTyped< T > openNXDataSet(const std::string &name) const
Templated method for creating datasets.
NXFloat openNXFloat(const std::string &name) const
Creates and opens a float dataset.
std::string getString(const std::string &name) const
Returns a string.
Templated class implementation of NXDataSet.
void load(const int blocksize=1, int i=-1, int j=-1, int k=-1, int l=-1) override
Implementation of the virtual NXDataSet::load(...) method.
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(NXhandle nxfileID, API::Run &runDetails, const std::string &entryName="", bool useFullPath=false)
Add properties from a nexus file to the workspace run.
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...
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::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.