-
Notifications
You must be signed in to change notification settings - Fork 122
/
LoadEmptyInstrument.cpp
166 lines (148 loc) · 6.87 KB
/
LoadEmptyInstrument.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidDataHandling/LoadEmptyInstrument.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/RegisterFileLoader.h"
#include "MantidAPI/SpectrumInfo.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidDataHandling/LoadGeometry.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidDataObjects/WorkspaceCreation.h"
#include "MantidGeometry/Instrument.h"
#include "MantidIndexing/IndexInfo.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/OptionalBool.h"
#include "MantidNexusGeometry/NexusGeometryParser.h"
namespace Mantid {
namespace DataHandling {
// Register the algorithm into the algorithm factory as a file loading algorithm
DECLARE_FILELOADER_ALGORITHM(LoadEmptyInstrument)
using namespace Kernel;
using namespace API;
using namespace Geometry;
using namespace DataObjects;
using namespace HistogramData;
/**
* Return the confidence with with this algorithm can load the file
* @param descriptor A descriptor for the file
* @returns An integer specifying the confidence level. 0 indicates it will not
* be used
*/
int LoadEmptyInstrument::confidence(Kernel::FileDescriptor &descriptor) const {
const std::string &filePath = descriptor.filename();
int confidence(0);
if (descriptor.isAscii()) // Only consider an Ascii file
{
// Filename must contain "Definition"
std::string::size_type stripPath = filePath.find_last_of("\\/");
if (stripPath == std::string::npos)
stripPath = 0;
if (filePath.find("Definition", stripPath) != std::string::npos) {
// We have some confidence and it depends on the filetype.
if (descriptor.extension() == "xml") {
confidence = 80;
} else {
confidence = 20;
}
} // Has "Definition"
} // Ascii file
return confidence;
}
/// Initialisation method.
void LoadEmptyInstrument::init() {
declareProperty(
std::make_unique<FileProperty>("Filename", "", FileProperty::OptionalLoad, LoadGeometry::validExtensions()),
"The filename (including its full or relative path) of an instrument "
"definition file. The file extension must either be .xml or .XML when "
"specifying an instrument definition file. Files can also be .hdf5 or "
".nxs for usage with NeXus Geometry files. Note Filename or "
"InstrumentName must be specified but not both.");
declareProperty("InstrumentName", "",
"Name of instrument. Can be used instead of Filename to "
"specify an IDF");
declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
"The name of the workspace in which to store the imported instrument");
auto mustBePositive = std::make_shared<BoundedValidator<double>>();
mustBePositive->setLower(0.0);
declareProperty("DetectorValue", 1.0, mustBePositive,
"This value affects the colour of the detectors in the instrument\n"
"display window (default 1)");
declareProperty("MonitorValue", 2.0, mustBePositive,
"This value affects the colour of the monitors in the instrument\n"
"display window (default 2)");
declareProperty(std::make_unique<PropertyWithValue<bool>>("MakeEventWorkspace", false),
"Set to True to create an EventWorkspace (with no events) "
"instead of a Workspace2D.");
}
/** Executes the algorithm. Reading in the file and creating and populating
* the output workspace
*
* @throw std::runtime_error If the instrument cannot be loaded by the
*LoadInstrument ChildAlgorithm
* @throw InstrumentDefinitionError Thrown if issues with the content of XML
*instrument file not covered by LoadInstrument
* @throw std::invalid_argument If the optional properties are set to invalid
*values
*/
void LoadEmptyInstrument::exec() {
// load the instrument into this workspace
const std::string filename = getPropertyValue("Filename");
const std::string instrumentname = getPropertyValue("InstrumentName");
Instrument_const_sptr instrument;
Progress prog(this, 0.0, 1.0, 10);
// Call LoadIstrument as a child algorithm
MatrixWorkspace_sptr ws = this->runLoadInstrument(filename, instrumentname);
instrument = ws->getInstrument();
// Get number of detectors stored in instrument
const size_t number_spectra = instrument->getNumberDetectors();
// Check that we have some spectra for the workspace
if (number_spectra == 0) {
g_log.error("Instrument has no detectors, unable to create workspace for it");
throw Kernel::Exception::InstrumentDefinitionError("No detectors found in instrument");
}
Indexing::IndexInfo indexInfo(number_spectra);
bool MakeEventWorkspace = getProperty("MakeEventWorkspace");
prog.reportIncrement(5, "Creating Data");
if (MakeEventWorkspace) {
setProperty("OutputWorkspace", create<EventWorkspace>(std::move(instrument), indexInfo,
BinEdges{0.0, std::numeric_limits<double>::min()}));
} else {
const double detector_value = getProperty("DetectorValue");
const double monitor_value = getProperty("MonitorValue");
auto ws2D = create<Workspace2D>(
std::move(instrument), indexInfo,
Histogram(BinEdges{0.0, 1.0}, Counts(1, detector_value), CountStandardDeviations(1, detector_value)));
Counts v_monitor_y(1, monitor_value);
CountStandardDeviations v_monitor_e(1, monitor_value);
const auto &spectrumInfo = ws2D->spectrumInfo();
const auto size = static_cast<int64_t>(spectrumInfo.size());
#pragma omp parallel for
for (int64_t i = 0; i < size; i++) {
if (spectrumInfo.isMonitor(i)) {
ws2D->setCounts(i, v_monitor_y);
ws2D->setCountStandardDeviations(i, v_monitor_e);
}
}
setProperty("OutputWorkspace", std::move(ws2D));
}
}
/// Run the Child Algorithm LoadInstrument (or LoadInstrumentFromRaw)
API::MatrixWorkspace_sptr LoadEmptyInstrument::runLoadInstrument(const std::string &filename,
const std::string &instrumentname) {
auto loadInst = createChildAlgorithm("LoadInstrument", 0, 0.5);
loadInst->setPropertyValue("Filename", filename);
loadInst->setPropertyValue("InstrumentName", instrumentname);
loadInst->setProperty("RewriteSpectraMap", OptionalBool(true));
auto ws = WorkspaceFactory::Instance().create("Workspace2D", 1, 2, 1);
loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", ws);
loadInst->execute();
return ws;
}
} // namespace DataHandling
} // namespace Mantid