Mantid
Loading...
Searching...
No Matches
MDEventsTestHelper.h
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 +
7/*********************************************************************************
8 * PLEASE READ THIS!!!!!!!
9 *
10 * This header MAY NOT be included in any test from a package below the level
11 *of
12 * DataObjects (e.g. Kernel, Geometry, API).
13 *********************************************************************************/
14#pragma once
15
24#include "MantidKernel/Utils.h"
25
26namespace {
27template <typename MDE, size_t nd>
28std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> createOutputWorkspace(size_t splitInto) {
29 std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> out(
31 Mantid::API::BoxController_sptr bc = out->getBoxController();
32 bc->setSplitThreshold(100);
33 bc->setSplitInto(splitInto);
34 return out;
35}
36
37template <typename MDE, size_t nd>
38void addMDDimensions(std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> out, Mantid::coord_t min,
39 Mantid::coord_t max, const std::string &axisNameFormat, const std::string &axisIdFormat) {
40
41 // Create MDFrame of General Frame type
43
44 // Create dimensions
45 for (size_t d = 0; d < nd; d++) {
46 char name[200];
47 sprintf(name, axisNameFormat.c_str(), d);
48 char id[200];
49 sprintf(id, axisIdFormat.c_str(), d);
50
52 new Mantid::Geometry::MDHistoDimension(std::string(name), std::string(id), frame, min, max, 10));
53 out->addDimension(dim);
54 }
55 out->initialize();
56}
57
58template <typename MDE, size_t nd>
59void addMDDimensionsWithFrames(std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> out, Mantid::coord_t min,
61 const std::string &axisNameFormat, const std::string &axisIdFormat) {
62 for (size_t d = 0; d < nd; d++) {
63 char name[200];
64 sprintf(name, axisNameFormat.c_str(), d);
65 char id[200];
66 sprintf(id, axisIdFormat.c_str(), d);
67
68 // Use the same frame for all dimensions
69 auto dim =
70 std::make_shared<Mantid::Geometry::MDHistoDimension>(std::string(name), std::string(id), frame, min, max, 10);
71 out->addDimension(dim);
72 }
73 out->initialize();
74}
75
76template <typename MDE, size_t nd>
77void addMDDimensionsWithIndividualFrames(std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> out,
79 const std::vector<Mantid::Geometry::MDFrame_sptr> &frame,
80 const std::string &axisNameFormat, const std::string &axisIdFormat) {
81 for (size_t d = 0; d < nd; d++) {
82 char name[200];
83 sprintf(name, axisNameFormat.c_str(), d);
84 char id[200];
85 sprintf(id, axisIdFormat.c_str(), d);
86
87 // Use the same frame for all dimensions
88 auto dim = std::make_shared<Mantid::Geometry::MDHistoDimension>(std::string(name), std::string(id), *frame[d], min,
89 max, 10);
90 out->addDimension(dim);
91 }
92 out->initialize();
93}
94
95template <typename MDE, size_t nd>
96void addData(std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>> out, size_t splitInto, Mantid::coord_t min,
97 Mantid::coord_t max, size_t numEventsPerBox) {
98 if (numEventsPerBox > 0) {
99 out->splitBox();
100 size_t index[nd];
102 size_t index_max[nd];
103 Mantid::Kernel::Utils::NestedForLoop::SetUp(nd, index_max, splitInto);
104 bool allDone = false;
105 while (!allDone) {
106 for (size_t i = 0; i < numEventsPerBox; i++) {
107 // Put an event in the middle of each box
108 Mantid::coord_t centers[nd];
109 for (size_t d = 0; d < nd; d++)
110 centers[d] = min + (static_cast<Mantid::coord_t>(index[d]) + 0.5f) * (max - min) /
111 static_cast<Mantid::coord_t>(splitInto);
112 out->addEvent(MDE(1.0, 1.0, centers));
113 }
114
116 }
117 out->refreshCache();
118 }
120 out->addExperimentInfo(ei);
121}
122} // namespace
123
124namespace Mantid {
125namespace DataObjects {
126
132namespace MDEventsTestHelper {
133
141 int numBins = 160);
142
149MDEventWorkspace3Lean::sptr makeFakeMDEventWorkspace(const std::string &wsName, long numEvents = 10000,
151
153MDHistoWorkspace_sptr makeFakeMDHistoWorkspace(double signal, size_t numDims, size_t numBins = 10, coord_t max = 10.0,
154 double errorSquared = 1.0, const std::string &name = "",
155 double numEvents = 1.0);
156
158makeFakeMDHistoWorkspaceWithMDFrame(double signal, size_t numDims, const Mantid::Geometry::MDFrame &frame,
159 size_t numBins = 10, coord_t max = 10.0, double errorSquared = 1.0,
160 const std::string &name = "", double numEvents = 1.0);
161
164 double errorSquared, size_t *numBins,
165 coord_t *min, coord_t *max,
166 const std::string &name = "");
169makeFakeMDHistoWorkspaceGeneral(size_t numDims, double signal, double errorSquared, size_t *numBins, coord_t *min,
170 coord_t *max, std::vector<std::string> names, const std::string &name = "");
171
172//-------------------------------------------------------------------------------------
187template <typename MDE, size_t nd>
188std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>>
189makeAnyMDEW(size_t splitInto, coord_t min, coord_t max, size_t numEventsPerBox = 0, const std::string &wsName = "",
190 const std::string &axisNameFormat = "Axis%d", const std::string &axisIdFormat = "Axis%d") {
191 // Create bare workspace
192 auto out = createOutputWorkspace<MDE, nd>(splitInto);
193
194 // Add standard dimensions
195 addMDDimensions<MDE, nd>(out, min, max, axisNameFormat, axisIdFormat);
196
197 // Add data
198 addData<MDE, nd>(out, splitInto, min, max, numEventsPerBox);
199
200 // Add to ADS on option
201 if (!wsName.empty())
202 Mantid::API::AnalysisDataService::Instance().addOrReplace(wsName, out);
203
204 return out;
205}
206
223template <typename MDE, size_t nd>
224std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>>
226 std::vector<Mantid::Geometry::MDFrame_sptr> frames, size_t numEventsPerBox = 0,
227 const std::string &wsName = "", std::string axisNameFormat = "Axis%d",
228 std::string axisIdFormat = "Axis%d") {
229 // Create bare workspace
230 auto out = createOutputWorkspace<MDE, nd>(splitInto);
231
232 // Add standard dimensions
233 addMDDimensionsWithIndividualFrames<MDE, nd>(out, min, max, frames, axisNameFormat, axisIdFormat);
234
235 // Add data
236 addData<MDE, nd>(out, splitInto, min, max, numEventsPerBox);
237
238 // Add to ADS on option
239 if (!wsName.empty())
240 Mantid::API::AnalysisDataService::Instance().addOrReplace(wsName, out);
241
242 return out;
243}
244
262template <typename MDE, size_t nd>
263std::shared_ptr<Mantid::DataObjects::MDEventWorkspace<MDE, nd>>
264makeAnyMDEWWithFrames(size_t splitInto, coord_t min, coord_t max, const Mantid::Geometry::MDFrame &frame,
265 size_t numEventsPerBox = 0, const std::string &wsName = "",
266 const std::string &axisNameFormat = "Axis%d", const std::string &axisIdFormat = "Axis%d") {
267 // Create bare workspace
268 auto out = createOutputWorkspace<MDE, nd>(splitInto);
269
270 // Add standard dimensions
271 addMDDimensionsWithFrames<MDE, nd>(out, min, max, frame, axisNameFormat, axisIdFormat);
272
273 // Add data
274 addData<MDE, nd>(out, splitInto, min, max, numEventsPerBox);
275
276 // Add to ADS on option
277 if (!wsName.empty())
278 Mantid::API::AnalysisDataService::Instance().addOrReplace(wsName, out);
279
280 return out;
281}
282
284template <size_t nd>
285std::shared_ptr<MDEventWorkspace<MDLeanEvent<nd>, nd>> makeMDEW(size_t splitInto, coord_t min, coord_t max,
286 size_t numEventsPerBox = 0) {
287 return makeAnyMDEW<MDLeanEvent<nd>, nd>(splitInto, min, max, numEventsPerBox);
288}
289
291template <size_t nd>
292std::shared_ptr<MDEventWorkspace<MDLeanEvent<nd>, nd>> makeMDEWWithFrames(size_t splitInto, coord_t min, coord_t max,
293 const Mantid::Geometry::MDFrame &frame,
294 size_t numEventsPerBox = 0) {
295 return makeAnyMDEWWithFrames<MDLeanEvent<nd>, nd>(splitInto, min, max, frame, numEventsPerBox);
296}
297
299template <size_t nd>
300std::shared_ptr<MDEventWorkspace<MDLeanEvent<nd>, nd>>
302 const std::vector<Mantid::Geometry::MDFrame_sptr> &frame, size_t numEventsPerBox = 0) {
303 return makeAnyMDEWWithIndividualFrames<MDLeanEvent<nd>, nd>(splitInto, min, max, frame, numEventsPerBox);
304}
305
308template <size_t nd>
309std::shared_ptr<MDEventWorkspace<MDEvent<nd>, nd>> makeMDEWFull(size_t splitInto, coord_t min, coord_t max,
310 size_t numEventsPerBox = 0) {
311 return makeAnyMDEW<MDEvent<nd>, nd>(splitInto, min, max, numEventsPerBox);
312}
313
314//=====================================================================================
315//=============================== MDGRIDBOX HELPER METHODS
316//============================
317//=====================================================================================
318
320MDBox<MDLeanEvent<1>, 1> *makeMDBox1(size_t splitInto = 10, API::BoxController *splitter = nullptr);
321
324
327std::vector<MDLeanEvent<1>> makeMDEvents1(size_t num);
328
329//-------------------------------------------------------------------------------------
339template <size_t nd>
340static MDGridBox<MDLeanEvent<nd>, nd> *makeMDGridBox(size_t split0 = 10, size_t split1 = 10, coord_t dimensionMin = 0.0,
341 coord_t dimensionMax = 10.0) {
342 // Split at 5 events
343 auto splitter = new Mantid::API::BoxController(nd);
344 splitter->setSplitThreshold(5);
345 // Splits into 10x10x.. boxes
346 splitter->setSplitInto(split0);
347 splitter->setSplitInto(0, split0);
348 if (nd > 1)
349 splitter->setSplitInto(1, split1);
350 // Set the size to 10.0 in all directions
351 auto box = std::make_unique<MDBox<MDLeanEvent<nd>, nd>>(splitter);
352 for (size_t d = 0; d < nd; d++)
353 // carefull! function with the side effects!
354 box->setExtents(d, dimensionMin, dimensionMax);
355 // calc volume necessary
356 box->calcVolume();
357
358 // Split
359 auto out = new MDGridBox<MDLeanEvent<nd>, nd>(box.get());
360 return out;
361}
362
363//-------------------------------------------------------------------------------------
373template <size_t nd>
374static void feedMDBox(MDBoxBase<MDLeanEvent<nd>, nd> *box, size_t repeat = 1, size_t numPerSide = 10,
375 coord_t start = 0.5, coord_t step = 1.0) {
376 size_t counters[nd];
378 size_t index_max[nd];
379 Mantid::Kernel::Utils::NestedForLoop::SetUp(nd, index_max, numPerSide);
380 // Recursive for loop
381 bool allDone = false;
382 while (!allDone) {
383 // Generate the position from the counter
384 coord_t centers[nd];
385 for (size_t d = 0; d < nd; d++)
386 centers[d] = static_cast<coord_t>(counters[d]) * step + start;
387
388 // Add that event 'repeat' times
389 for (size_t i = 0; i < repeat; ++i)
390 box->addEvent(MDLeanEvent<nd>(1.0, 1.0, centers));
391
392 // Increment the nested for loop
393 allDone = Mantid::Kernel::Utils::NestedForLoop::Increment(nd, counters, index_max);
394 }
395 box->refreshCache(nullptr);
396}
397
398//-------------------------------------------------------------------------------------
405template <size_t nd>
406static void recurseSplit(MDGridBox<MDLeanEvent<nd>, nd> *box, size_t atRecurseLevel, size_t recurseLimit) {
407 using boxVector = std::vector<MDBoxBase<MDLeanEvent<nd>, nd> *>;
408 if (atRecurseLevel >= recurseLimit)
409 return;
410
411 // Split all the contents
412 boxVector boxes;
413 boxes = box->getBoxes();
414 for (size_t i = 0; i < boxes.size(); i++)
415 box->splitContents(i);
416
417 // Retrieve the contained MDGridBoxes
418 boxes = box->getBoxes();
419
420 // Go through them and split them
421 for (size_t i = 0; i < boxes.size(); i++) {
422 MDGridBox<MDLeanEvent<nd>, nd> *containedbox = dynamic_cast<MDGridBox<MDLeanEvent<nd>, nd> *>(boxes[i]);
423 if (containedbox)
424 recurseSplit(containedbox, atRecurseLevel + 1, recurseLimit);
425 }
426}
427
428//-------------------------------------------------------------------------------------
436template <size_t nd> static MDGridBox<MDLeanEvent<nd>, nd> *makeRecursiveMDGridBox(size_t splitInto, size_t levels) {
437 // Split at 5 events
438 auto splitter(new Mantid::API::BoxController(nd));
439 splitter->setSplitThreshold(5);
440 splitter->resetNumBoxes();
441 splitter->setMaxDepth(levels + 1);
442 // Splits into splitInto x splitInto x ... boxes
443 splitter->setSplitInto(splitInto);
444 // Set the size to splitInto*1.0 in all directions
445 auto box = std::make_unique<MDBox<MDLeanEvent<nd>, nd>>(splitter);
446 for (size_t d = 0; d < nd; d++)
447 box->setExtents(d, 0.0, static_cast<coord_t>(splitInto));
448 // Split into the gridbox.
449 auto gridbox = new MDGridBox<MDLeanEvent<nd>, nd>(box.get());
450 // Now recursively split more
451 recurseSplit(gridbox, 0, levels);
452
453 return gridbox;
454}
455
456//-------------------------------------------------------------------------------------
458template <typename MDBOX> static void extents_match(MDBOX box, size_t dim, double min, double max) {
459 TSM_ASSERT_DELTA(dim, box->getExtents(dim).getMin(), min, 1e-6);
460 TSM_ASSERT_DELTA(dim, box->getExtents(dim).getMax(), max, 1e-6);
461}
462
463void checkAndDeleteFile(const std::string &filename);
464
465//=====================================================================================
466//===================================== TEST METHODS
467//==================================
468//=====================================================================================
469
470} // namespace MDEventsTestHelper
471} // namespace DataObjects
472} // namespace Mantid
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
This class is used by MDBox and MDGridBox in order to intelligently determine optimal behavior.
Definition: BoxController.h:33
This class is shared by a few Workspace types and holds information related to a particular experimen...
Templated super-class of a multi-dimensional event "box".
Definition: MDBoxBase.h:50
Templated class for a multi-dimensional event "box".
Definition: MDBox.h:45
Templated class for the multi-dimensional event workspace.
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
Templated class for a GRIDDED multi-dimensional event "box".
Definition: MDGridBox.h:42
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition: MDLeanEvent.h:60
GeneralFrame : Any MDFrame that isn't related to momemtum transfer.
Definition: GeneralFrame.h:21
static const std::string GeneralFrameDistance
Definition: GeneralFrame.h:23
MDFrame : The coordinate frame for a dimension, or set of dimensions in a multidimensional workspace.
Definition: MDFrame.h:22
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< BoxController > BoxController_sptr
Shared ptr to BoxController.
std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix, const NexusHDF5Descriptor &descriptor)
Get the number of events in the currently opened group.
MDBox< MDLeanEvent< 1 >, 1 > * makeMDBox1(size_t splitInto=10, API::BoxController *splitter=nullptr)
Generate an empty MDBox.
std::shared_ptr< MDEventWorkspace< MDEvent< nd >, nd > > makeMDEWFull(size_t splitInto, coord_t min, coord_t max, size_t numEventsPerBox=0)
Make a MDEventWorkspace with MDEvents - updated to split dims by splitInto, not 10.
static void feedMDBox(MDBoxBase< MDLeanEvent< nd >, nd > *box, size_t repeat=1, size_t numPerSide=10, coord_t start=0.5, coord_t step=1.0)
Feed a MDGridBox with evenly-spaced events.
Mantid::DataObjects::EventWorkspace_sptr createDiffractionEventWorkspace(int numEvents, int numPixels=400, int numBins=160)
Create an EventWorkspace containing fake data of single-crystal diffraction.
MDHistoWorkspace_sptr makeFakeMDHistoWorkspace(double signal, size_t numDims, size_t numBins=10, coord_t max=10.0, double errorSquared=1.0, const std::string &name="", double numEvents=1.0)
Make a fake n-dimensional MDHistoWorkspace.
std::vector< MDLeanEvent< 1 > > makeMDEvents1(size_t num)
Return a vector with this many MDEvents, spaced evenly from 0.5, 1.5, etc.
Mantid::DataObjects::MDHistoWorkspace_sptr makeFakeMDHistoWorkspaceGeneral(size_t numDims, double signal, double errorSquared, size_t *numBins, coord_t *min, coord_t *max, const std::string &name="")
More general fake n-dimensionsal MDHistoWorkspace.
std::shared_ptr< MDEventWorkspace< MDLeanEvent< nd >, nd > > makeMDEW(size_t splitInto, coord_t min, coord_t max, size_t numEventsPerBox=0)
Make a MDEventWorkspace with MDLeanEvents.
std::shared_ptr< Mantid::DataObjects::MDEventWorkspace< MDE, nd > > makeAnyMDEWWithIndividualFrames(size_t splitInto, coord_t min, coord_t max, std::vector< Mantid::Geometry::MDFrame_sptr > frames, size_t numEventsPerBox=0, const std::string &wsName="", std::string axisNameFormat="Axis%d", std::string axisIdFormat="Axis%d")
Create a test MDEventWorkspace<nd> .
std::shared_ptr< MDEventWorkspace< MDLeanEvent< nd >, nd > > makeMDEWWithFrames(size_t splitInto, coord_t min, coord_t max, const Mantid::Geometry::MDFrame &frame, size_t numEventsPerBox=0)
Make a MDEventWorkspace with MDLeanEvents nad MDFrames.
MDBox< MDLeanEvent< 3 >, 3 > * makeMDBox3()
Generate an empty MDBox with 3 dimensions, split 10x5x2.
std::shared_ptr< Mantid::DataObjects::MDEventWorkspace< MDE, nd > > makeAnyMDEW(size_t splitInto, coord_t min, coord_t max, size_t numEventsPerBox=0, const std::string &wsName="", const std::string &axisNameFormat="Axis%d", const std::string &axisIdFormat="Axis%d")
Create a test MDEventWorkspace<nd> .
static MDGridBox< MDLeanEvent< nd >, nd > * makeRecursiveMDGridBox(size_t splitInto, size_t levels)
Generate a recursively gridded MDGridBox.
void checkAndDeleteFile(const std::string &filename)
Delete a file from disk.
std::shared_ptr< MDEventWorkspace< MDLeanEvent< nd >, nd > > makeMDEWWithIndividualFrames(size_t splitInto, coord_t min, coord_t max, const std::vector< Mantid::Geometry::MDFrame_sptr > &frame, size_t numEventsPerBox=0)
Make a MDEventWorkspace with MDLeanEvents and individual MDFrames.
std::shared_ptr< Mantid::DataObjects::MDEventWorkspace< MDE, nd > > makeAnyMDEWWithFrames(size_t splitInto, coord_t min, coord_t max, const Mantid::Geometry::MDFrame &frame, size_t numEventsPerBox=0, const std::string &wsName="", const std::string &axisNameFormat="Axis%d", const std::string &axisIdFormat="Axis%d")
Create a test MDEventWorkspace<nd> .
static void recurseSplit(MDGridBox< MDLeanEvent< nd >, nd > *box, size_t atRecurseLevel, size_t recurseLimit)
Recursively split an existing MDGridBox.
MDEventWorkspace3Lean::sptr makeFakeMDEventWorkspace(const std::string &wsName, long numEvents=10000, Kernel::SpecialCoordinateSystem coord=Kernel::None)
Make a (optionally) file backed MDEventWorkspace with 10000 fake random data points.
static MDGridBox< MDLeanEvent< nd >, nd > * makeMDGridBox(size_t split0=10, size_t split1=10, coord_t dimensionMin=0.0, coord_t dimensionMax=10.0)
Generate an empty MDBox with 2 dimensions, splitting in (default) 10x10 boxes.
static void extents_match(MDBOX box, size_t dim, double min, double max)
Helper function compares the extents of the given box.
Mantid::DataObjects::MDHistoWorkspace_sptr makeFakeMDHistoWorkspaceWithMDFrame(double signal, size_t numDims, const Mantid::Geometry::MDFrame &frame, size_t numBins=10, coord_t max=10.0, double errorSquared=1.0, const std::string &name="", double numEvents=1.0)
Creates a fake MDHistoWorkspace with MDFrame selection.
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
std::shared_ptr< MDHistoDimension > MDHistoDimension_sptr
Shared pointer to a MDHistoDimension.
bool Increment(const size_t numDims, size_t *index, size_t *index_max, size_t *index_min)
Utility function for performing arbitrarily nested for loops in a serial way.
Definition: Utils.h:165
void SetUp(const size_t numDims, size_t *out, const size_t value=0)
Set up a nested for loop by setting an array of counters.
Definition: Utils.h:82
SpecialCoordinateSystem
Special coordinate systems for Q3D.
DataObjects::MDLeanEvent< 3 > MDE
Our MDLeanEvent dimension.
Helper class which provides the Collimation Length for SANS instruments.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27