Mantid
Loading...
Searching...
No Matches
LoadQKK.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
9#include "MantidAPI/Axis.h"
17#include "MantidIndexing/IndexInfo.h"
20
21#include <Poco/File.h>
22
23#include <fstream>
24
25using namespace Mantid::DataHandling;
26using namespace Mantid::API;
27using namespace Mantid::Kernel;
28
29namespace Mantid::DataHandling {
30
31// Register the algorithm into the AlgorithmFactory
33
34
40int LoadQKK::confidence(Kernel::NexusDescriptor &descriptor) const {
41 const auto &firstEntryName = descriptor.firstEntryNameType().first;
42 if (descriptor.pathExists("/" + firstEntryName + "/data/hmm_xy"))
43 return 80;
44 else
45 return 0;
46}
47
54 // Declare the Filename algorithm property. Mandatory. Sets the path to the
55 // file to load.
56 declareProperty(std::make_unique<API::FileProperty>("Filename", "", API::FileProperty::Load, ".nx.hdf"),
57 "The input filename of the stored data");
58 // Declare the OutputWorkspace property. This sets the name of the workspace
59 // to be filled with the data
60 // from the file.
61 declareProperty(std::make_unique<API::WorkspaceProperty<>>("OutputWorkspace", "", Kernel::Direction::Output));
62}
63
68 using namespace Mantid::API;
69 // Get the name of the file.
70 std::string filename = getPropertyValue("Filename");
71
72 // Open the root.
73 NeXus::NXRoot root(filename);
74 // Open the first NXentry found in the file.
75 NeXus::NXEntry entry = root.openFirstEntry();
76 // Open NXdata group with name "data"
77 NeXus::NXData data = entry.openNXData("data");
78 // Read in wavelength value
79 double wavelength = static_cast<double>(data.getFloat("wavelength"));
80 // open the data set with the counts. It is identified by the signal=1
81 // attribute
82 NeXus::NXInt hmm = data.openIntData();
83 // Read the data into memory
84 hmm.load();
85
86 // Get the wavelength spread
87 double wavelength_spread = static_cast<double>(entry.getFloat("instrument/velocity_selector/wavelength_spread"));
88 double wavelength0 = wavelength - wavelength_spread / 2;
89 double wavelength1 = wavelength + wavelength_spread / 2;
90
91 // hmm is a 3d array with axes: sample_x, y_pixel_offset, x_pixel_offset
92 size_t ny = hmm.dim1(); // second dimension
93 size_t nx = hmm.dim2(); // third dimension
94 size_t nHist = ny * nx; // number of spectra in the dataset
95 if (nHist == 0) {
96 throw std::runtime_error("Error in data dimensions: " + std::to_string(ny) + " X " + std::to_string(nx));
97 }
98
99 // Build instrument geometry
100
101 // Create a new instrument and set its name
102 std::string instrumentname = "QUOKKA";
103 Geometry::Instrument_sptr instrument(new Geometry::Instrument(instrumentname));
104
105 // Add dummy source and samplepos to instrument
106
107 // Create an instrument component wich will represent the sample position.
108 Geometry::Component *samplepos = new Geometry::Component("Sample", instrument.get());
109 instrument->add(samplepos);
110 instrument->markAsSamplePos(samplepos);
111 // Put the sample in the centre of the coordinate system
112 samplepos->setPos(0.0, 0.0, 0.0);
113
114 // Create a component to represent the source
115 Geometry::ObjComponent *source = new Geometry::ObjComponent("Source", instrument.get());
116 instrument->add(source);
117 instrument->markAsSource(source);
118
119 // Read in the L1 value and place the source at (0,0,-L1)
120 double l1 = static_cast<double>(entry.getFloat("instrument/parameters/L1"));
121 source->setPos(0.0, 0.0, -1.0 * l1);
122
123 // Create a component for the detector.
124
125 // We assumed that these are the dimensions of the detector, and height is in
126 // y direction and width is in x direction
127 double height = static_cast<double>(entry.getFloat("instrument/detector/active_height"));
128 double width = static_cast<double>(entry.getFloat("instrument/detector/active_width"));
129 // Convert them to metres
130 height /= 1000;
131 width /= 1000;
132
133 // We assumed that individual pixels have the same size and shape of a cuboid
134 // with dimensions:
135 double pixel_height = height / static_cast<double>(ny);
136 double pixel_width = width / static_cast<double>(nx);
137 // Create size strings for shape creation
138 std::string pixel_height_str = boost::lexical_cast<std::string>(pixel_height / 2);
139 std::string pixel_width_str = boost::lexical_cast<std::string>(pixel_width / 2);
140 // Set the depth of a pixel to a very small number
141 std::string pixel_depth_str = "0.00001";
142
143 // Create a RectangularDetector which represents a rectangular array of pixels
144 Geometry::RectangularDetector *bank = new Geometry::RectangularDetector("bank", instrument.get());
145 // Define shape of a pixel as an XML string. See
146 // http://www.mantidproject.org/HowToDefineGeometricShape for details
147 // on shapes in Mantid.
148 std::string detXML = "<cuboid id=\"pixel\">"
149 "<left-front-bottom-point x= \"" +
150 pixel_width_str + "\" y=\"-" + pixel_height_str +
151 "\" z=\"0\" />"
152 "<left-front-top-point x= \"" +
153 pixel_width_str + "\" y=\"-" + pixel_height_str + "\" z=\"" + pixel_depth_str +
154 "\" />"
155 "<left-back-bottom-point x=\"-" +
156 pixel_width_str + "\" y=\"-" + pixel_height_str +
157 "\" z=\"0\" />"
158 "<right-front-bottom-point x= \"" +
159 pixel_width_str + "\" y= \"" + pixel_height_str +
160 "\" z=\"0\" />"
161 "</cuboid>";
162 // Create a shape object which will be shared by all pixels.
163 auto shape = Geometry::ShapeFactory().createShape(detXML);
164 // Initialise the detector specifying the sizes.
165 bank->initialize(shape, int(nx), 0, pixel_width, int(ny), 0, pixel_height, 1, true, int(nx));
166 for (int i = 0; i < static_cast<int>(ny); ++i)
167 for (int j = 0; j < static_cast<int>(nx); ++j) {
168 instrument->markAsDetector(bank->getAtXY(j, i).get());
169 }
170 // Position the detector so the z axis goes through its centre
171 bank->setPos(-width / 2, -height / 2, 0);
172
173 // Create a workspace with nHist spectra and a single y bin.
174 auto outputWorkspace =
175 DataObjects::create<DataObjects::Workspace2D>(instrument, Indexing::IndexInfo(nHist), HistogramData::BinEdges(2));
176 // Set the units of the x axis as Wavelength
177 outputWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create("Wavelength");
178 // Set the units of the data as Counts
179 outputWorkspace->setYUnitLabel("Counts");
180
181 using namespace HistogramData;
182 const BinEdges binEdges = {wavelength0, wavelength1};
183 for (size_t index = 0; index < nHist; ++index) {
184 auto x = static_cast<int>(index % nx);
185 auto y = static_cast<int>(index / nx);
186 auto c = hmm(0, x, y);
187
188 Counts yValue = {static_cast<double>(c)};
189 outputWorkspace->setHistogram(index, binEdges, yValue);
190 }
191
192 outputWorkspace->setTitle(entry.getString("experiment/title"));
193 setProperty("OutputWorkspace", std::move(outputWorkspace));
194}
195
196} // namespace Mantid::DataHandling
double height
Definition: GetAllEi.cpp:155
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#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.
Definition: Algorithm.cpp:1913
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
@ Load
allowed here which will be passed to the algorithm
Definition: FileProperty.h:52
A property class for workspaces.
Loads a Quokka data file.
Definition: LoadQKK.h:26
void exec() override
Execution code.
Definition: LoadQKK.cpp:67
void init() override
Initialisation code.
Definition: LoadQKK.cpp:53
Component is a wrapper for a Component which can modify some of its parameters, e....
Definition: Component.h:41
void setPos(double, double, double) override
Set the IComponent position, x, y, z respective to parent (if present)
Definition: Component.cpp:204
virtual void setPos(double, double, double)=0
Set the IComponent position, x, y, z respective to parent (if present)
Base Instrument Class.
Definition: Instrument.h:47
Object Component class, this class brings together the physical attributes of the component to the po...
Definition: ObjComponent.h:33
RectangularDetector is a type of CompAssembly, an assembly of components.
std::shared_ptr< Detector > getAtXY(const int X, const int Y) const
Return a pointer to the component in the assembly at the (X,Y) pixel position.
void initialize(std::shared_ptr< IObject > shape, int xpixels, double xstart, double xstep, int ypixels, double ystart, double ystep, int idstart, bool idfillbyfirst_y, int idstepbyrow, int idstep=1)
Create all the detector pixels of this rectangular detector.
Class originally intended to be used with the DataHandling 'LoadInstrument' algorithm.
Definition: ShapeFactory.h:89
std::shared_ptr< CSGObject > createShape(Poco::XML::Element *pElem)
Creates a geometric object from a DOM-element-node pointing to an element whose child nodes contain t...
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Defines a wrapper around a file whose internal structure can be accessed using the NeXus API.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
float getFloat(const std::string &name) const
Returns a float.
std::string getString(const std::string &name) const
Returns a string.
Templated class implementation of NXDataSet.
Definition: NexusClasses.h:203
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.
Definition: NexusClasses.h:289
int dim2() const
Returns the number of elements along the third dimension.
int dim1() const
Returns the number of elements along the second dimension.
Implements NXdata Nexus class.
Definition: NexusClasses.h:795
NXInt openIntData()
Opens data of int type.
Definition: NexusClasses.h:828
Implements NXentry Nexus class.
Definition: NexusClasses.h:898
NXData openNXData(const std::string &name) const
Opens a NXData.
Definition: NexusClasses.h:912
Implements NXroot Nexus class.
Definition: NexusClasses.h:922
NXEntry openFirstEntry()
Open the first NXentry in the file.
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Output
An output workspace.
Definition: Property.h:54