Newer
Older
#include "MantidDataHandling/LoadILLSANS.h"
Federico Montesino Pouzols
committed
#include "MantidAPI/Axis.h"
Federico Montesino Pouzols
committed
#include "MantidAPI/MatrixWorkspace.h"
Federico Montesino Pouzols
committed
#include "MantidAPI/WorkspaceFactory.h"
Federico Montesino Pouzols
committed
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/IDetector.h"
#include <numeric> // std::accumulate
namespace Mantid {
namespace DataHandling {
using namespace Kernel;
using namespace API;
using namespace NeXus;
DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILLSANS)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
LoadILLSANS::LoadILLSANS() : m_defaultBinning(2) {
m_supportedInstruments.emplace_back("D33");
}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
//----------------------------------------------------------------------------------------------
/// Algorithm's name for identification. @see Algorithm::name
const std::string LoadILLSANS::name() const { return "LoadILLSANS"; }
/// Algorithm's version for identification. @see Algorithm::version
int LoadILLSANS::version() const { return 1; }
/// Algorithm's category for identification. @see Algorithm::category
const std::string LoadILLSANS::category() const {
return "DataHandling\\Nexus";
}
//----------------------------------------------------------------------------------------------
/**
* 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 LoadILLSANS::confidence(Kernel::NexusDescriptor &descriptor) const {
// fields existent only at the ILL for SANS machines
if (descriptor.pathExists("/entry0/reactor_power") &&
descriptor.pathExists("/entry0/instrument_name") &&
descriptor.pathExists("/entry0/mode")) {
return 80;
} else {
return 0;
}
}
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void LoadILLSANS::init() {
declareProperty(new FileProperty("Filename", "", FileProperty::Load, ".nxs"),
"Name of the SPE file to load");
declareProperty(
new WorkspaceProperty<>("OutputWorkspace", "", Direction::Output),
"The name to use for the output workspace");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void LoadILLSANS::exec() {
// Init
std::string filename = getPropertyValue("Filename");
NXRoot root(filename);
NXEntry firstEntry = root.openFirstEntry();
std::string instrumentPath = m_loader.findInstrumentNexusPath(firstEntry);
setInstrumentName(firstEntry, instrumentPath);
g_log.debug("Setting detector positions...");
DetectorPosition detPos = getDetectorPosition(firstEntry, instrumentPath);
initWorkSpace(firstEntry, instrumentPath);
// load the instrument from the IDF if it exists
runLoadInstrument();
// Move detectors
moveDetectors(detPos);
setFinalProperties();
// Set the output workspace property
setProperty("OutputWorkspace", m_localWorkspace);
}
/**
* Set member variable with the instrument name
*/
void LoadILLSANS::setInstrumentName(const NeXus::NXEntry &firstEntry,
const std::string &instrumentNamePath) {
if (instrumentNamePath == "") {
std::string message("Cannot set the instrument name from the Nexus file!");
g_log.error(message);
throw std::runtime_error(message);
}
m_instrumentName =
m_loader.getStringFromNexusPath(firstEntry, instrumentNamePath + "/name");
g_log.debug() << "Instrument name set to: " + m_instrumentName << std::endl;
}
/**
* Get detector panel distances from the nexus file
* @return a structure with the positions
*/
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
DetectorPosition
LoadILLSANS::getDetectorPosition(const NeXus::NXEntry &firstEntry,
const std::string &instrumentNamePath) {
std::string detectorPath(instrumentNamePath + "/detector");
DetectorPosition pos;
pos.distanceSampleRear =
m_loader.getDoubleFromNexusPath(firstEntry, detectorPath + "/det2_calc");
pos.distanceSampleBottomTop =
m_loader.getDoubleFromNexusPath(firstEntry, detectorPath + "/det1_calc");
pos.distanceSampleRightLeft =
pos.distanceSampleBottomTop +
m_loader.getDoubleFromNexusPath(firstEntry,
detectorPath + "/det1_panel_separation");
pos.shiftLeft = m_loader.getDoubleFromNexusPath(
firstEntry, detectorPath + "/OxL_actual") *
1e-3;
pos.shiftRight = m_loader.getDoubleFromNexusPath(
firstEntry, detectorPath + "/OxR_actual") *
1e-3;
pos.shiftUp = m_loader.getDoubleFromNexusPath(firstEntry,
detectorPath + "/OyT_actual") *
1e-3;
pos.shiftDown = m_loader.getDoubleFromNexusPath(
firstEntry, detectorPath + "/OyB_actual") *
1e-3;
g_log.debug() << pos;
return pos;
}
void LoadILLSANS::initWorkSpace(NeXus::NXEntry &firstEntry,
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
const std::string &instrumentPath) {
g_log.debug("Fetching data...");
NXData dataGroup1 = firstEntry.openNXData("data1");
NXInt dataRear = dataGroup1.openIntData();
dataRear.load();
NXData dataGroup2 = firstEntry.openNXData("data2");
NXInt dataRight = dataGroup2.openIntData();
dataRight.load();
NXData dataGroup3 = firstEntry.openNXData("data3");
NXInt dataLeft = dataGroup3.openIntData();
dataLeft.load();
NXData dataGroup4 = firstEntry.openNXData("data4");
NXInt dataDown = dataGroup4.openIntData();
dataDown.load();
NXData dataGroup5 = firstEntry.openNXData("data5");
NXInt dataUp = dataGroup5.openIntData();
dataUp.load();
g_log.debug("Checking channel numbers...");
// check number of channels
if (dataRear.dim2() != dataRight.dim2() &&
dataRight.dim2() != dataLeft.dim2() &&
dataLeft.dim2() != dataDown.dim2() && dataDown.dim2() != dataUp.dim2()) {
throw std::runtime_error(
"The time bins have not the same dimension for all the 5 detectors!");
}
int numberOfHistograms =
dataRear.dim0() * dataRear.dim1() + dataRight.dim0() * dataRight.dim1() +
dataLeft.dim0() * dataLeft.dim1() + dataDown.dim0() * dataDown.dim1() +
dataUp.dim0() * dataUp.dim1();
g_log.debug("Creating empty workspace...");
// TODO : Must put this 2 somewhere else: number of monitors!
createEmptyWorkspace(numberOfHistograms + 2, dataRear.dim2());
loadMetaData(firstEntry, instrumentPath);
std::vector<double> binningRear, binningRight, binningLeft, binningDown,
binningUp;
if (firstEntry.getFloat("mode") == 0.0) { // Not TOF
g_log.debug("Getting default wavelength bins...");
binningRear = m_defaultBinning;
binningRight = m_defaultBinning;
binningLeft = m_defaultBinning;
binningDown = m_defaultBinning;
binningUp = m_defaultBinning;
} else {
g_log.debug("Getting wavelength bins from the nexus file...");
std::string binPathPrefix(instrumentPath + "/tof/tof_wavelength_detector");
binningRear =
m_loader.getTimeBinningFromNexusPath(firstEntry, binPathPrefix + "1");
binningRight =
m_loader.getTimeBinningFromNexusPath(firstEntry, binPathPrefix + "2");
binningLeft =
m_loader.getTimeBinningFromNexusPath(firstEntry, binPathPrefix + "3");
binningDown =
m_loader.getTimeBinningFromNexusPath(firstEntry, binPathPrefix + "4");
binningUp =
m_loader.getTimeBinningFromNexusPath(firstEntry, binPathPrefix + "5");
}
g_log.debug("Loading the data into the workspace...");
size_t nextIndex = loadDataIntoWorkspaceFromMonitors(firstEntry, 0);
nextIndex = loadDataIntoWorkspaceFromHorizontalTubes(dataRear, binningRear,
nextIndex);
nextIndex = loadDataIntoWorkspaceFromVerticalTubes(dataRight, binningRight,
nextIndex);
nextIndex =
loadDataIntoWorkspaceFromVerticalTubes(dataLeft, binningLeft, nextIndex);
nextIndex = loadDataIntoWorkspaceFromHorizontalTubes(dataDown, binningDown,
nextIndex);
nextIndex =
loadDataIntoWorkspaceFromHorizontalTubes(dataUp, binningUp, nextIndex);
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
size_t
LoadILLSANS::loadDataIntoWorkspaceFromMonitors(NeXus::NXEntry &firstEntry,
size_t firstIndex) {
// let's find the monitors
// For D33 should be monitor1 and monitor2
for (std::vector<NXClassInfo>::const_iterator it =
firstEntry.groups().begin();
it != firstEntry.groups().end(); ++it) {
if (it->nxclass == "NXmonitor") {
NXData dataGroup = firstEntry.openNXData(it->nxname);
NXInt data = dataGroup.openIntData();
data.load();
g_log.debug() << "Monitor: " << it->nxname << " dims = " << data.dim0()
<< "x" << data.dim1() << "x" << data.dim2() << std::endl;
const size_t vectorSize = data.dim2() + 1;
std::vector<double> positionsBinning;
positionsBinning.reserve(vectorSize);
for (size_t i = 0; i < vectorSize; i++)
positionsBinning.push_back(static_cast<double>(i));
// Assign X
m_localWorkspace->dataX(firstIndex)
.assign(positionsBinning.begin(), positionsBinning.end());
// Assign Y
m_localWorkspace->dataY(firstIndex).assign(data(), data() + data.dim2());
// Assign Error
MantidVec &E = m_localWorkspace->dataE(firstIndex);
std::transform(data(), data() + data.dim2(), E.begin(),
LoadHelper::calculateStandardError);
// Add average monitor counts to a property:
double averageMonitorCounts =
std::accumulate(data(), data() + data.dim2(), 0) /
static_cast<double>(data.dim2());
// make sure the monitor has values!
if (averageMonitorCounts > 0) {
API::Run &runDetails = m_localWorkspace->mutableRun();
runDetails.addProperty("monitor", averageMonitorCounts, true);
}
firstIndex++;
}
}
return firstIndex;
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
size_t LoadILLSANS::loadDataIntoWorkspaceFromHorizontalTubes(
NeXus::NXInt &data, const std::vector<double> &timeBinning,
size_t firstIndex = 0) {
g_log.debug("Loading the data into the workspace:");
g_log.debug() << "\t"
<< "firstIndex = " << firstIndex << std::endl;
g_log.debug() << "\t"
<< "Number of Pixels : data.dim0() = " << data.dim0()
<< std::endl;
g_log.debug() << "\t"
<< "Number of Tubes : data.dim1() = " << data.dim1()
<< std::endl;
g_log.debug() << "\t"
<< "data.dim2() = " << data.dim2() << std::endl;
g_log.debug() << "\t"
<< "First bin = " << timeBinning[0] << std::endl;
// Workaround to get the number of tubes / pixels
size_t numberOfTubes = data.dim1();
size_t numberOfPixelsPerTube = data.dim0();
Progress progress(this, 0, 1, data.dim0() * data.dim1());
m_localWorkspace->dataX(firstIndex)
.assign(timeBinning.begin(), timeBinning.end());
size_t spec = firstIndex;
for (size_t i = 0; i < numberOfTubes; ++i) { // iterate tubes
for (size_t j = 0; j < numberOfPixelsPerTube;
++j) { // iterate pixels in the tube 256
if (spec > firstIndex) {
// just copy the time binning axis to every spectra
m_localWorkspace->dataX(spec) = m_localWorkspace->readX(firstIndex);
}
// Assign Y
int *data_p = &data(static_cast<int>(j), static_cast<int>(i), 0);
m_localWorkspace->dataY(spec).assign(data_p, data_p + data.dim2());
// Assign Error
MantidVec &E = m_localWorkspace->dataE(spec);
std::transform(data_p, data_p + data.dim2(), E.begin(),
LoadHelper::calculateStandardError);
++spec;
progress.report();
}
}
g_log.debug() << "Data loading into WS done...." << std::endl;
return spec;
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
size_t LoadILLSANS::loadDataIntoWorkspaceFromVerticalTubes(
NeXus::NXInt &data, const std::vector<double> &timeBinning,
size_t firstIndex = 0) {
g_log.debug("Loading the data into the workspace:");
g_log.debug() << "\t"
<< "firstIndex = " << firstIndex << std::endl;
g_log.debug() << "\t"
<< "Number of Tubes : data.dim0() = " << data.dim0()
<< std::endl;
g_log.debug() << "\t"
<< "Number of Pixels : data.dim1() = " << data.dim1()
<< std::endl;
g_log.debug() << "\t"
<< "data.dim2() = " << data.dim2() << std::endl;
g_log.debug() << "\t"
<< "First bin = " << timeBinning[0] << std::endl;
// Workaround to get the number of tubes / pixels
size_t numberOfTubes = data.dim0();
size_t numberOfPixelsPerTube = data.dim1();
Progress progress(this, 0, 1, data.dim0() * data.dim1());
m_localWorkspace->dataX(firstIndex)
.assign(timeBinning.begin(), timeBinning.end());
size_t spec = firstIndex;
for (size_t i = 0; i < numberOfTubes; ++i) { // iterate tubes
for (size_t j = 0; j < numberOfPixelsPerTube;
++j) { // iterate pixels in the tube 256
if (spec > firstIndex) {
// just copy the time binning axis to every spectra
m_localWorkspace->dataX(spec) = m_localWorkspace->readX(firstIndex);
}
// Assign Y
int *data_p = &data(static_cast<int>(i), static_cast<int>(j), 0);
m_localWorkspace->dataY(spec).assign(data_p, data_p + data.dim2());
// Assign Error
MantidVec &E = m_localWorkspace->dataE(spec);
std::transform(data_p, data_p + data.dim2(), E.begin(),
LoadHelper::calculateStandardError);
++spec;
progress.report();
}
}
g_log.debug() << "Data loading inti WS done...." << std::endl;
return spec;
}
/***
* Create a workspace without any data in it
*/
void LoadILLSANS::createEmptyWorkspace(int numberOfHistograms,
int numberOfChannels) {
m_localWorkspace = WorkspaceFactory::Instance().create(
"Workspace2D", numberOfHistograms, numberOfChannels + 1,
numberOfChannels);
m_localWorkspace->getAxis(0)->unit() =
UnitFactory::Instance().create("Wavelength");
m_localWorkspace->setYUnitLabel("Counts");
}
void LoadILLSANS::runLoadInstrument() {
IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument");
// Now execute the Child Algorithm. Catch and log any error, but don't stop.
try {
loadInst->setPropertyValue("InstrumentName", m_instrumentName);
loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", m_localWorkspace);
loadInst->setProperty("RewriteSpectraMap",
Mantid::Kernel::OptionalBool(true));
loadInst->execute();
} catch (...) {
g_log.information("Cannot load the instrument definition.");
}
void LoadILLSANS::moveDetectors(const DetectorPosition &detPos) {
// Move in Z
moveDetectorDistance(detPos.distanceSampleRear, "back_detector");
moveDetectorDistance(detPos.distanceSampleBottomTop, "front_detector_top");
moveDetectorDistance(detPos.distanceSampleBottomTop, "front_detector_bottom");
moveDetectorDistance(detPos.distanceSampleRightLeft, "front_detector_right");
moveDetectorDistance(detPos.distanceSampleRightLeft, "front_detector_left");
// Move in X
moveDetectorHorizontal(detPos.shiftLeft, "front_detector_left");
moveDetectorHorizontal(-detPos.shiftRight, "front_detector_right");
// Move in Y
moveDetectorVertical(detPos.shiftUp, "front_detector_top");
moveDetectorVertical(-detPos.shiftDown, "front_detector_bottom");
}
/**
* Move detectors in Z axis (X,Y are kept constant)
*/
void LoadILLSANS::moveDetectorDistance(double distance,
const std::string &componentName) {
API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");
V3D pos = getComponentPosition(componentName);
try {
mover->setProperty<MatrixWorkspace_sptr>("Workspace", m_localWorkspace);
mover->setProperty("ComponentName", componentName);
mover->setProperty("X", pos.X());
mover->setProperty("Y", pos.Y());
mover->setProperty("Z", distance);
mover->setProperty("RelativePosition", false);
mover->executeAsChildAlg();
g_log.debug() << "Moving component '" << componentName
<< "' to Z = " << distance << std::endl;
} catch (std::exception &e) {
g_log.error() << "Cannot move the component '" << componentName
<< "' to Z = " << distance << std::endl;
g_log.error() << e.what() << std::endl;
}
}
/**
* Move detectors in X
*/
void LoadILLSANS::moveDetectorHorizontal(double shift,
const std::string &componentName) {
API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");
V3D pos = getComponentPosition(componentName);
try {
mover->setProperty<MatrixWorkspace_sptr>("Workspace", m_localWorkspace);
mover->setProperty("ComponentName", componentName);
mover->setProperty("X", shift);
mover->setProperty("Y", pos.Y());
mover->setProperty("Z", pos.Z());
mover->setProperty("RelativePosition", false);
mover->executeAsChildAlg();
g_log.debug() << "Moving component '" << componentName
<< "' to X = " << shift << std::endl;
} catch (std::exception &e) {
g_log.error() << "Cannot move the component '" << componentName
<< "' to X = " << shift << std::endl;
g_log.error() << e.what() << std::endl;
}
void LoadILLSANS::moveDetectorVertical(double shift,
const std::string &componentName) {
API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");
V3D pos = getComponentPosition(componentName);
try {
mover->setProperty<MatrixWorkspace_sptr>("Workspace", m_localWorkspace);
mover->setProperty("ComponentName", componentName);
mover->setProperty("X", pos.X());
mover->setProperty("Y", shift);
mover->setProperty("Z", pos.Z());
mover->setProperty("RelativePosition", false);
mover->executeAsChildAlg();
g_log.debug() << "Moving component '" << componentName
<< "' to Y = " << shift << std::endl;
} catch (std::exception &e) {
g_log.error() << "Cannot move the component '" << componentName
<< "' to Y = " << shift << std::endl;
g_log.error() << e.what() << std::endl;
}
}
/**
* Get position in space of a componentName
*/
V3D LoadILLSANS::getComponentPosition(const std::string &componentName) {
Geometry::Instrument_const_sptr instrument =
m_localWorkspace->getInstrument();
Geometry::IComponent_const_sptr component =
instrument->getComponentByName(componentName);
return component->getPos();
}
/*
* Loads metadata present in the nexus file
*/
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
void LoadILLSANS::loadMetaData(const NeXus::NXEntry &entry,
const std::string &instrumentNamePath) {
g_log.debug("Loading metadata...");
API::Run &runDetails = m_localWorkspace->mutableRun();
int runNum = entry.getInt("run_number");
std::string run_num = boost::lexical_cast<std::string>(runNum);
runDetails.addProperty("run_number", run_num);
if (entry.getFloat("mode") == 0.0) { // Not TOF
runDetails.addProperty<std::string>("tof_mode", "Non TOF");
} else {
runDetails.addProperty<std::string>("tof_mode", "TOF");
}
std::string desc =
m_loader.getStringFromNexusPath(entry, "sample_description");
runDetails.addProperty("sample_description", desc);
std::string start_time = entry.getString("start_time");
start_time = m_loader.dateTimeInIsoFormat(start_time);
runDetails.addProperty("run_start", start_time);
std::string end_time = entry.getString("end_time");
end_time = m_loader.dateTimeInIsoFormat(end_time);
runDetails.addProperty("run_end", end_time);
double duration = entry.getFloat("duration");
runDetails.addProperty("timer", duration);
double wavelength =
entry.getFloat(instrumentNamePath + "/selector/wavelength");
g_log.debug() << "Wavelength found in the nexus file: " << wavelength
<< std::endl;
if (wavelength <= 0) {
g_log.debug() << "Mode = " << entry.getFloat("mode") << std::endl;
g_log.information("The wavelength present in the NeXus file <= 0.");
if (entry.getFloat("mode") == 0.0) { // Not TOF
throw std::runtime_error("Working in Non TOF mode and the wavelength in "
"the file is <=0 !!! Check with the instrument "
"scientist!");
}
} else {
double wavelengthRes =
entry.getFloat(instrumentNamePath + "/selector/wavelength_res");
runDetails.addProperty<double>("wavelength", wavelength);
double ei = m_loader.calculateEnergy(wavelength);
runDetails.addProperty<double>("Ei", ei, true);
// wavelength
m_defaultBinning[0] = wavelength - wavelengthRes * wavelength * 0.01 / 2;
m_defaultBinning[1] = wavelength + wavelengthRes * wavelength * 0.01 / 2;
}
// Put the detector distances:
// std::string detectorPath(instrumentNamePath + "/detector");
// // Just for Sample - RearDetector
// double sampleDetectorDistance =
// m_loader.getDoubleFromNexusPath(entry,detectorPath + "/det2_calc");
// runDetails.addProperty("sample_detector_distance",
// sampleDetectorDistance);
}
/**
* @param lambda : wavelength in Amstrongs
* @param twoTheta : twoTheta in degreess
*/
double LoadILLSANS::calculateQ(const double lambda,
const double twoTheta) const {
return (4 * M_PI * std::sin(twoTheta * (M_PI / 180) / 2)) / (lambda);
}
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
std::pair<double, double> LoadILLSANS::calculateQMaxQMin() {
double min = std::numeric_limits<double>::max(),
max = std::numeric_limits<double>::min();
g_log.debug("Calculating Qmin Qmax...");
std::size_t nHist = m_localWorkspace->getNumberHistograms();
for (std::size_t i = 0; i < nHist; ++i) {
Geometry::IDetector_const_sptr det = m_localWorkspace->getDetector(i);
if (!det->isMonitor()) {
const MantidVec &lambdaBinning = m_localWorkspace->readX(i);
Kernel::V3D detPos = det->getPos();
double r, theta, phi;
detPos.getSpherical(r, theta, phi);
double v1 = calculateQ(*(lambdaBinning.begin()), theta);
double v2 = calculateQ(*(lambdaBinning.end() - 1), theta);
// std::cout << "i=" << i << " theta="<<theta << " lambda_i=" <<
// *(lambdaBinning.begin()) << " lambda_f=" << *(lambdaBinning.end()-1) <<
// " v1=" << v1 << " v2=" << v2 << std::endl;
if (i == 0) {
min = v1;
max = v1;
}
if (v1 < min) {
min = v1;
}
if (v2 < min) {
min = v2;
}
if (v1 > max) {
max = v1;
}
if (v2 > max) {
max = v2;
}
} else
g_log.debug() << "Detector " << i << " is a Monitor : " << det->getID()
<< std::endl;
}
g_log.debug() << "Calculating Qmin Qmax. Done : [" << min << "," << max << "]"
<< std::endl;
return std::pair<double, double>(min, max);
}
void LoadILLSANS::setFinalProperties() {
API::Run &runDetails = m_localWorkspace->mutableRun();
runDetails.addProperty("is_frame_skipping", 0);
std::pair<double, double> minmax = LoadILLSANS::calculateQMaxQMin();
runDetails.addProperty("qmin", minmax.first);
runDetails.addProperty("qmax", minmax.second);
}
} // namespace DataHandling
} // namespace Mantid