Newer
Older
#include "MantidQtCustomInterfaces/Indirect/ContainerSubtraction.h"
#include "MantidQtCustomInterfaces/UserInputValidator.h"
using namespace Mantid::API;
namespace {
Mantid::Kernel::Logger g_log("ContainerSubtraction");
}
namespace MantidQt {
namespace CustomInterfaces {
ContainerSubtraction::ContainerSubtraction(QWidget *parent)
: CorrectionsTab(parent) {
m_uiForm.setupUi(parent);
// Connect slots
connect(m_uiForm.cbGeometry, SIGNAL(currentIndexChanged(int)), this,
SLOT(handleGeometryChanged(int)));
connect(m_uiForm.dsSample, SIGNAL(dataReady(const QString &)), this,
SLOT(newData(const QString &)));
connect(m_uiForm.spPreviewSpec, SIGNAL(valueChanged(int)), this,
SLOT(plotPreview(int)));
m_uiForm.spPreviewSpec->setMinimum(0);
m_uiForm.spPreviewSpec->setMaximum(0);
void ContainerSubtraction::setup() {}
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
void ContainerSubtraction::run() {
API::BatchAlgorithmRunner::AlgorithmRuntimeProps absCorProps;
IAlgorithm_sptr applyCorrAlg =
AlgorithmManager::Instance().create("ApplyPaalmanPingsCorrection");
applyCorrAlg->initialize();
QString sampleWsName = m_uiForm.dsSample->getCurrentDataName();
MatrixWorkspace_sptr sampleWs =
AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
sampleWsName.toStdString());
m_originalSampleUnits = sampleWs->getAxis(0)->unit()->unitID();
// If not in wavelength then do conversion
if (m_originalSampleUnits != "Wavelength") {
g_log.information(
"Sample workspace not in wavelength, need to convert to continue.");
absCorProps["SampleWorkspace"] =
addConvertUnitsStep(sampleWs, "Wavelength");
} else {
absCorProps["SampleWorkspace"] = sampleWsName.toStdString();
}
QString canWsName = m_uiForm.dsContainer->getCurrentDataName();
MatrixWorkspace_sptr canWs =
AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
canWsName.toStdString());
// If not in wavelength then do conversion
std::string originalCanUnits = canWs->getAxis(0)->unit()->unitID();
if (originalCanUnits != "Wavelength") {
g_log.information("Container workspace not in wavelength, need to "
"convert to continue.");
absCorProps["CanWorkspace"] = addConvertUnitsStep(canWs, "Wavelength");
} else {
absCorProps["CanWorkspace"] = canWsName.toStdString();
}
// Check for same binning across sample and container
if (!checkWorkspaceBinningMatches(sampleWs, canWs)) {
QString text = "Binning on sample and container does not match."
"Would you like to rebin the sample to match the container?";
int result = QMessageBox::question(NULL, tr("Rebin sample?"), tr(text),
QMessageBox::Yes, QMessageBox::No,
QMessageBox::NoButton);
if (result == QMessageBox::Yes) {
addRebinStep(sampleWsName, canWsName);
} else {
m_batchAlgoRunner->clearQueue();
g_log.error("Cannot apply absorption corrections using a sample and "
"container with different binning.");
return;
}
}
// Generate output workspace name
int nameCutIndex = sampleWsName.lastIndexOf("_");
if (nameCutIndex == -1)
nameCutIndex = sampleWsName.length();
QString correctionType;
switch (m_uiForm.cbGeometry->currentIndex()) {
case 0:
correctionType = "flt";
break;
case 1:
correctionType = "cyl";
break;
}
const QString outputWsName =
sampleWsName.left(nameCutIndex) + +"_" + correctionType + "_Corrected";
applyCorrAlg->setProperty("OutputWorkspace", outputWsName.toStdString());
// Add corrections algorithm to queue
m_batchAlgoRunner->addAlgorithm(applyCorrAlg, absCorProps);
// Run algorithm queue
connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
SLOT(absCorComplete(bool)));
m_batchAlgoRunner->executeBatchAsync();
// Set the result workspace for Python script export
m_pythonExportWsName = outputWsName.toStdString();
}
/**
* Adds a rebin to workspace step to the calculation for when using a sample and
*container that
* have different binning.
*
* @param toRebin
* @param toMatch
*/
void ContainerSubtraction::addRebinStep(QString toRebin, QString toMatch) {
API::BatchAlgorithmRunner::AlgorithmRuntimeProps rebinProps;
rebinProps["WorkspaceToMatch"] = toMatch.toStdString();
IAlgorithm_sptr rebinAlg =
AlgorithmManager::Instance().create("RebinToWorkspace");
rebinAlg->initialize();
rebinAlg->setProperty("WorkspaceToRebin", toRebin.toStdString());
rebinAlg->setProperty("OutputWorkspace", toRebin.toStdString());
m_batchAlgoRunner->addAlgorithm(rebinAlg, rebinProps);
}
/**
* Validates the user input in the UI
* @return if the input was valid
*/
bool ContainerSubtraction::validate() {
UserInputValidator uiv;
uiv.checkDataSelectorIsValid("Sample", m_uiForm.dsSample);
uiv.checkDataSelectorIsValid("Container", m_uiForm.dsContainer);
MatrixWorkspace_sptr sampleWs;
QString sample = m_uiForm.dsSample->getCurrentDataName();
QString sampleType = sample.right(sample.length() - sample.lastIndexOf("_"));
QString container = m_uiForm.dsContainer->getCurrentDataName();
QString containerType =
container.right(sample.length() - container.lastIndexOf("_"));
g_log.debug() << "Sample type is: " << sampleType.toStdString() << std::endl;
g_log.debug() << "Container type is: " << containerType.toStdString()
<< std::endl;
if (containerType != sampleType)
uiv.addErrorMessage(
"Sample and can workspaces must contain the same type of data.");
// Show errors if there are any
if (!uiv.isAllInputValid())
emit showMessageBox(uiv.generateErrorMessage());
return uiv.isAllInputValid();
}
void ContainerSubtraction::loadSettings(const QSettings &settings) {
m_uiForm.dsContainer->readSettings(settings.group());
m_uiForm.dsSample->readSettings(settings.group());
}
* Displays the sample data on the plot preview
* @param dataName Name of new data source
*/
void ContainerSubtraction::newData(const QString &dataName) {
const MatrixWorkspace_sptr sampleWs =
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
AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
dataName.toStdString());
m_uiForm.spPreviewSpec->setMaximum(
static_cast<int>(sampleWs->getNumberHistograms()) - 1);
// Plot the sample curve
m_uiForm.ppPreview->clear();
m_uiForm.ppPreview->addSpectrum("Sample", sampleWs, 0, Qt::black);
}
/**
* Handles when the type of geometry changes
*
* Updates the file extension to search for
*/
void ContainerSubtraction::handleGeometryChange(int index) {
QString ext("");
switch (index) {
case 0:
// Geometry is flat
ext = "_flt_abs";
break;
case 1:
// Geometry is cylinder
ext = "_cyl_abs";
break;
case 2:
// Geometry is annulus
ext = "_ann_abs";
break;
}
/*m_uiForm.dsCorrections->setWSSuffixes(QStringList(ext));
m_uiForm.dsCorrections->setFBSuffixes(QStringList(ext + ".nxs"));*/
}
/**
* Replots the preview plot.
*
* @param specIndex Spectrum index to plot
*/
void ContainerSubtraction::plotPreview(int specIndex) {
m_uiForm.ppPreview->clear();
// Plot sample
m_uiForm.ppPreview->addSpectrum(
"Sample", m_uiForm.dsSample->getCurrentDataName(), specIndex, Qt::black);
// Plot result
if (!m_pythonExportWsName.empty())
m_uiForm.ppPreview->addSpectrum(
"Corrected", QString::fromStdString(m_pythonExportWsName), specIndex,
Qt::green);
// Plot can
m_uiForm.ppPreview->addSpectrum("Container",
m_uiForm.dsContainer->getCurrentDataName(),
specIndex, Qt::red);
void ContainerSubtraction::postProcessComplete(bool error) {
disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
SLOT(postProcessComplete(bool)));
if (error) {
emit showMessageBox("Unable to process corrected workspace.\nSee Results "
"Log for more details.");
return;
}
// Handle preview plot
plotPreview(m_uiForm.spPreviewSpec->value());
// Handle Mantid plotting
QString plotType = m_uiForm.cbPlotOutput->currentText();
if (plotType == "Spectra" || plotType == "Both")
plotSpectrum(QString::fromStdString(m_pythonExportWsName));
if (plotType == "Contour" || plotType == "Both")
plot2D(QString::fromStdString(m_pythonExportWsName));
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/**
* Handles completion of the abs. correction algorithm.
*
* @param error True if algorithm failed.
*/
void ContainerSubtraction::absCorComplete(bool error) {
disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
SLOT(absCorComplete(bool)));
if (error) {
emit showMessageBox(
"Unable to apply corrections.\nSee Results Log for more details.");
return;
}
// Convert back to original sample units
if (m_originalSampleUnits != "Wavelength") {
auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
m_pythonExportWsName);
std::string eMode("");
if (m_originalSampleUnits == "dSpacing")
eMode = "Elastic";
addConvertUnitsStep(ws, m_originalSampleUnits, "", eMode);
}
// Add save algorithms if required
bool save = m_uiForm.ckSave->isChecked();
if (save)
addSaveWorkspaceToQueue(QString::fromStdString(m_pythonExportWsName));
// Run algorithm queue
connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
SLOT(postProcessComplete(bool)));
m_batchAlgoRunner->executeBatchAsync();
}
} // namespace CustomInterfaces
} // namespace MantidQt