Mantid
Loading...
Searching...
No Matches
SequentialFitDialog.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 +
9#include "MantidAPI/Axis.h"
13#include "MantidAPI/Run.h"
14#include "MantidAPI/TableRow.h"
21
22#include <Poco/ActiveResult.h>
23
24#include <QFileDialog>
25#include <QInputDialog>
26#include <QMessageBox>
27#include <QUrl>
28
29namespace MantidQt {
30using API::MantidDesktopServices;
31
32namespace {
33Mantid::Kernel::Logger g_log("SequentialFitDialog");
34}
35
36namespace MantidWidgets {
37
42 : MantidDialog(fitBrowser), m_fitBrowser(fitBrowser) {
43 ui.setupUi(this);
44
45 connect(ui.btnAddFile, SIGNAL(clicked()), this, SLOT(addFile()));
46 connect(ui.btnAddWorkspace, SIGNAL(clicked()), this, SLOT(addWorkspace()));
47 connect(ui.btnDelete, SIGNAL(clicked()), this, SLOT(removeItem()));
48
49 connect(ui.btnFit, SIGNAL(clicked()), this, SLOT(accept()));
50 connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(reject()));
51 connect(ui.btnHelp, SIGNAL(clicked()), this, SLOT(helpClicked()));
52 connect(ui.ckbLogPlot, SIGNAL(toggled(bool)), this, SLOT(plotAgainstLog(bool)));
53 connect(ui.ckCreateOutput, SIGNAL(toggled(bool)), ui.ckOutputCompMembers, SLOT(setEnabled(bool)));
54 connect(ui.ckCreateOutput, SIGNAL(toggled(bool)), ui.ckConvolveMembers, SLOT(setEnabled(bool)));
55
56 ui.cbLogValue->setEditable(true);
57 ui.ckbLogPlot->setChecked(true);
58 ui.sbPeriod->setValue(1);
59
61
62 connect(fitBrowser, SIGNAL(functionChanged()), this, SLOT(functionChanged()));
63
64 // When a fit is completed finishHandle is called which emits needShowPlot
65 connect(this, SIGNAL(needShowPlot(Ui::SequentialFitDialog *, MantidQt::MantidWidgets::FitPropertyBrowser *)),
66 mantidui, SLOT(showSequentialPlot(Ui::SequentialFitDialog *, MantidQt::MantidWidgets::FitPropertyBrowser *)));
67 connect(ui.tWorkspaces, SIGNAL(cellChanged(int, int)), this, SLOT(spectraChanged(int, int)));
68 connect(ui.tWorkspaces, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
70} // namespace MantidWidgets
71
73 SelectWorkspacesDialog *dlg = new SelectWorkspacesDialog(this, "MatrixWorkspace");
74 if (dlg->exec() == QDialog::Accepted) {
76 }
77}
78
79bool SequentialFitDialog::addWorkspaces(const QStringList &wsNames) {
80 if (wsNames.isEmpty())
81 return false;
82 int row = ui.tWorkspaces->rowCount();
83 ui.tWorkspaces->model()->insertRows(row, wsNames.size());
84 int wi = m_fitBrowser->workspaceIndex();
85 QAbstractItemModel *model = ui.tWorkspaces->model();
86 foreach (QString name, wsNames) {
87 model->setData(model->index(row, 0, QModelIndex()), name);
88
89 if (row == 0) {
90 ui.ckbLogPlot->setChecked(validateLogs(name));
91 }
92
93 // disable the period cell
94 model->setData(model->index(row, 1, QModelIndex()), "");
95 QTableWidgetItem *item = ui.tWorkspaces->item(row, 1);
96 if (item) {
97 item->setBackground(QColor(Qt::lightGray));
98 item->setFlags(Qt::NoItemFlags);
99 }
100
101 if (ui.ckbLogPlot->isChecked()) {
102 // set spectrum number corresponding to the workspace index
103 Mantid::API::MatrixWorkspace_sptr ws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
104 Mantid::API::AnalysisDataService::Instance().retrieve(name.toStdString()));
105 int spec = -1;
106 if (ws) {
107 Mantid::API::Axis *y = ws->getAxis(1);
108 if (y->isSpectra()) {
109 spec = y->spectraNo(wi);
110 }
111 }
112 // model->setData(model->index(row,2,QModelIndex()),spec);
113 setSpectrum(row, spec);
114 if (row == 0) {
115 ui.sbSpectrum->setValue(spec);
116 }
117
118 // set workspace index
119 // model->setData(model->index(row,3,QModelIndex()),wi);
120 setWSIndex(row, wi);
121 }
122 ++row;
123 }
124 ui.tWorkspaces->resizeRowsToContents();
125 ui.tWorkspaces->resizeColumnsToContents();
126 return true;
127}
128
130 QFileDialog dlg(this);
131 dlg.setFileMode(QFileDialog::ExistingFiles);
132 const std::vector<std::string> &searchDirs = Mantid::Kernel::ConfigService::Instance().getDataSearchDirs();
133 QString dir;
134 if (searchDirs.empty()) {
135 dir = "";
136 } else {
137 dir = QString::fromStdString(searchDirs.front());
138 }
139 dlg.setDirectory(dir);
140 if (dlg.exec()) {
141 QStringList fileNames;
142 fileNames = dlg.selectedFiles();
143 if (fileNames.isEmpty())
144 return;
145 fileNames.sort();
146
147 int row = ui.tWorkspaces->rowCount();
148 ui.tWorkspaces->model()->insertRows(row, fileNames.size());
149 // int wi = m_fitBrowser->workspaceIndex();
150 QAbstractItemModel *model = ui.tWorkspaces->model();
151 foreach (QString name, fileNames) {
152 model->setData(model->index(row, 0, QModelIndex()), name); // file name
153 model->setData(model->index(row, 1, QModelIndex()),
154 ui.sbPeriod->value()); // period
155 model->setData(model->index(row, 2, QModelIndex()),
156 ui.sbSpectrum->value()); // spectrum
157 model->setData(model->index(row, 3, QModelIndex()), ""); // ws index
158 QTableWidgetItem *item = ui.tWorkspaces->item(row, 3);
159 if (item) {
160 item->setBackground(QColor(Qt::lightGray));
161 item->setFlags(Qt::NoItemFlags);
162 }
163 ++row;
164 }
165 ui.tWorkspaces->resizeRowsToContents();
166 ui.tWorkspaces->resizeColumnsToContents();
167 }
168}
169
171 QList<QTableWidgetSelectionRange> ranges = ui.tWorkspaces->selectedRanges();
172 while (!ranges.empty()) {
173 ui.tWorkspaces->model()->removeRows(ranges[0].topRow(), ranges[0].rowCount());
174 ranges = ui.tWorkspaces->selectedRanges();
175 }
176}
177
178bool SequentialFitDialog::validateLogs(const QString &wsName) {
179 Mantid::API::MatrixWorkspace_sptr ws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
180 Mantid::API::AnalysisDataService::Instance().retrieve(wsName.toStdString()));
181 if (ws) {
182 const std::vector<Mantid::Kernel::Property *> logs = ws->run().getLogData();
183 QStringList logNames;
184 // add the option that displays workspace names
185 logNames << "SourceName";
186 for (auto log : logs) {
188 if (!p)
189 continue;
190 logNames << QString::fromStdString(log->name());
191 }
192 int n = ui.cbLogValue->count();
193 // if the ws has no logs - do not include it
194 if (logNames.empty()) {
195 return false;
196 }
197 // if the log value combo box is empty fill it in with the log names from ws
198 if (n == 0) {
199 ui.cbLogValue->insertItems(0, logNames);
200 } else { // keep only those logs which are included in both ui.cbLogValue
201 // and logNames
202 QStringList namesToRemove;
203 for (int i = 0; i < n; ++i) {
204 QString name = ui.cbLogValue->itemText(i);
205 if (!logNames.contains(name)) {
206 namesToRemove << name;
207 }
208 }
209 foreach (QString name, namesToRemove) {
210 int i = ui.cbLogValue->findText(name);
211 if (i >= 0) {
212 ui.cbLogValue->removeItem(i);
213 }
214 }
215 if (ui.cbLogValue->count() == 0) {
216 QMessageBox::warning(m_fitBrowser, "MantidPlot - Warning",
217 "The list of the log names is empty:\n"
218 "The selected workspaces do not have common logs");
219 return false;
220 }
221 }
222 }
223 return true;
224}
225
226bool SequentialFitDialog::isFile(int row) const {
227 QTableWidgetItem *item = ui.tWorkspaces->item(row, 3);
228 return !item || item->flags().testFlag(Qt::ItemIsEnabled) == false;
229}
230
236QString SequentialFitDialog::getIndex(int row) const {
237 QString index;
238 QString spectrum = ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(row, 2)).toString();
239 QString wsIndex = ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(row, 3)).toString();
240 QString range = ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(row, 4)).toString();
241
242 if (isFile(row)) {
243 // if it is a file the ndex can be either spectrum or a range of values
244 // range takes priority over spectrum
245 if (!range.isEmpty()) {
246 index = "v" + range;
247 } else {
248 index = "sp" + spectrum;
249 }
250 } else {
251 Mantid::API::MatrixWorkspace_sptr ws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
252 Mantid::API::AnalysisDataService::Instance().retrieve(name(row).toStdString()));
253 Mantid::API::Axis *y = ws->getAxis(1);
254
255 // if it is a single workspace index can only be a range since we are doing
256 // a multiple fitting
257 if (rowCount() == 1 && range.isEmpty()) {
258 index = QString("v%1:%2").arg((*y)(0)).arg((*y)(y->length() - 1));
259 } else {
260 if (!range.isEmpty()) {
261 index = "v" + range;
262 } else {
263 index = "i" + wsIndex;
264 }
265 }
266 }
267
268 return index;
269}
270
272 QStringList inputStr;
273 for (int i = 0; i < ui.tWorkspaces->rowCount(); ++i) {
274 QString name = ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(i, 0)).toString();
275 QString parStr = name + "," + getIndex(i);
276 if (isFile(i)) { // add the period
277 parStr += QString(",") + ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(i, 1)).toString();
278 }
279 inputStr << parStr;
280 }
281 std::string funStr;
282 if (m_fitBrowser->m_compositeFunction->nFunctions() > 1) {
283 funStr = m_fitBrowser->m_compositeFunction->asString();
284 } else {
285 funStr = (m_fitBrowser->m_compositeFunction->getFunction(0))->asString();
286 }
287
290 m_outputName += "_res";
291 }
292
294 alg->initialize();
295 alg->setPropertyValue("Input", inputStr.join(";").toStdString());
296 alg->setProperty("WorkspaceIndex", m_fitBrowser->workspaceIndex());
297 // Create an array property of start and end X times, each pair startX[i]
298 // endX[i] will be used for the ith fit.
299 // At the moment we read the startX and endX from the single entry in the fit
300 // browser - and duplicate it for each input
301 auto nInputs = rowCount();
302 auto startX = m_fitBrowser->startX();
303 auto endX = m_fitBrowser->endX();
304 alg->setProperty("StartX", std::vector<double>(nInputs, startX));
305 alg->setProperty("EndX", std::vector<double>(nInputs, endX));
306 alg->setPropertyValue("OutputWorkspace", m_outputName);
307 alg->setPropertyValue("Function", funStr);
308 alg->setProperty("CreateOutput", ui.ckCreateOutput->isChecked());
309 alg->setProperty("OutputCompositeMembers", ui.ckOutputCompMembers->isChecked());
310 alg->setProperty("ConvolveMembers", ui.ckConvolveMembers->isChecked());
311 if (ui.ckbLogPlot->isChecked()) {
312 std::string logName = ui.cbLogValue->currentText().toStdString();
313 alg->setPropertyValue("LogValue", logName);
314 observeFinish(alg);
315 } else if (nInputs > 1) {
316 alg->setPropertyValue("LogValue", "SourceName");
317 } else {
318 observeFinish(alg);
319 }
320 alg->setPropertyValue("Minimizer", m_fitBrowser->minimizer());
321 alg->setPropertyValue("CostFunction", m_fitBrowser->costFunction());
322 alg->setProperty("MaxIterations", m_fitBrowser->maxIterations());
323 if (ui.rbIndividual->isChecked()) {
324 alg->setPropertyValue("FitType", "Individual");
325 }
327 alg->setProperty("EvaluationType", "Histogram");
328 }
329
330 bool passWSIndexToFunction = ui.ckbPassWS->isChecked();
331 alg->setProperty("PassWSIndexToFunction", passWSIndexToFunction);
332
333 alg->executeAsync();
334 QDialog::accept();
335}
336
338 QStringList names;
339 for (size_t i = 0; i < m_fitBrowser->m_compositeFunction->nParams(); ++i) {
340 names << QString::fromStdString(m_fitBrowser->m_compositeFunction->parameterName(i));
341 }
342 ui.cbParameter->clear();
343 ui.cbParameter->insertItems(0, names);
344}
345
347
352}
353
359 auto wsName = m_outputName;
360 if (!Mantid::API::AnalysisDataService::Instance().doesExist(wsName)) {
361 return;
362 }
363 Mantid::API::ITableWorkspace_sptr ws = std::dynamic_pointer_cast<Mantid::API::ITableWorkspace>(
365 if (!ws) {
366 return;
367 }
368 auto columnNames = ws->getColumnNames();
369
370 size_t rowNo = 0;
371 if (rowCount() > 1 && columnNames[0] == "SourceName") {
372 // first column contains ws names (only if the log value is SourceName)
373 // otherwise, the first column contains the values of the log value and
374 // cannot compare workspace names
375 auto firstColumn = ws->getColumn(0);
376 for (size_t i = 0; i < ws->rowCount(); ++i) {
377 if (firstColumn->cell<std::string>(i) == m_fitBrowser->workspaceName()) {
378 rowNo = i;
379 break;
380 }
381 }
382 } else {
383 // first column contains log names or axis-1
385 if (index < ws->rowCount()) {
386 rowNo = index;
387 }
388 }
389
390 Mantid::API::TableRow row = ws->getRow(rowNo);
391 // results parameter table contains parameter value followed by its error so
392 // increment by 2 for each value. Ignore first and last column in row as they
393 // contain name and chi-squared. Also ignore columns that aren't fitting parameters.
394 for (size_t col = 1; col < columnNames.size() - 1; col += 2) {
395 auto value = row.Double(col);
396 auto error = row.Double(col + 1);
397 auto name = columnNames[col];
398 // In case of a single function Fit doesn't create a CompositeFunction
399 if (m_fitBrowser->count() == 1) {
400 name.insert(0, "f0.");
401 }
402 if (m_fitBrowser->compositeFunction()->hasParameter(name)) {
403 size_t paramIndex = m_fitBrowser->compositeFunction()->parameterIndex(name);
404
405 m_fitBrowser->compositeFunction()->setParameter(paramIndex, value);
406 m_fitBrowser->compositeFunction()->setError(paramIndex, error);
407 }
408 }
411}
412
414 MantidDesktopServices::openUrl(QUrl("http://www.mantidproject.org/PlotPeakByLogValue"));
415}
416
425 if (!ui.ckbLogPlot->isChecked())
426 return;
427 QTableWidgetItem *item = ui.tWorkspaces->item(row, 3);
428 if (!item)
429 return;
430 if ((col == 2 || col == 3) && item->flags().testFlag(Qt::ItemIsEnabled) == true) { // it's a workspace
431 QString name = ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(row, 0)).toString();
433 try {
434 ws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
435 Mantid::API::AnalysisDataService::Instance().retrieve(name.toStdString()));
436 } catch (...) { //
437 return;
438 }
439 if (!ws)
440 return;
441 int wi = ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(row, 3)).toInt();
442 int spec = ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(row, 2)).toInt();
443 Mantid::API::Axis *y = ws->getAxis(1);
444 if (wi >= 0 && wi < static_cast<int>(ws->getNumberHistograms())) {
445 // this prevents infinite loops
446 if (!y->isSpectra() || y->spectraNo(wi) == spec)
447 return;
448 } else {
449 // return to the previous state
450 col = 2;
451 }
452 if (col == 3) // changed workspace index
453 {
454 try {
455 spec = y->spectraNo(wi);
456 // ui.tWorkspaces->model()->setData(ui.tWorkspaces->model()->index(row,2),spec);
457 setSpectrum(row, spec);
458 } catch (...) {
459 // return to the previous state
460 col = 2;
461 }
462 }
463 if (col == 2) // changed spectrum number
464 {
465 for (int i = 0; i < static_cast<int>(y->length()); ++i) {
466 if ((*y)(i) == spec) {
467 // ui.tWorkspaces->model()->setData(ui.tWorkspaces->model()->index(row,3),i);
468 setWSIndex(row, i);
469 return;
470 }
471 }
472 try {
473 // ui.tWorkspaces->model()->setData(ui.tWorkspaces->model()->index(row,2),(*y)(0));
474 setSpectrum(row, int((*y)(0)));
475 } catch (...) {
476 }
477 }
478 }
479}
480
481void SequentialFitDialog::setSpectrum(int row, int spec) {
482 ui.tWorkspaces->model()->setData(ui.tWorkspaces->model()->index(row, 2), spec);
483}
484
485void SequentialFitDialog::setWSIndex(int row, int wi) {
486 ui.tWorkspaces->model()->setData(ui.tWorkspaces->model()->index(row, 3), wi);
487}
488
489int SequentialFitDialog::rowCount() const { return ui.tWorkspaces->rowCount(); }
490
491int SequentialFitDialog::defaultSpectrum() const { return ui.sbSpectrum->value(); }
492
493QString SequentialFitDialog::name(int row) const {
494 return ui.tWorkspaces->model()->data(ui.tWorkspaces->model()->index(row, 0)).toString();
495}
496
497void SequentialFitDialog::setRange(int row, double from, double to) {
498 QString range = QString::number(from) + ":" + QString::number(to);
499 ui.tWorkspaces->model()->setData(ui.tWorkspaces->model()->index(row, 3), range);
500}
501
503 // ui.btnAddFile->setEnabled(yes);
504 // ui.btnAddWorkspace->setEnabled(yes);
505 // ui.btnDelete->setEnabled(yes);
506 ui.lblLogValue->setVisible(yes);
507 ui.cbLogValue->setVisible(yes);
508 ui.lblPeriod->setVisible(yes);
509 ui.sbPeriod->setVisible(yes);
510 ui.lblSpectrum->setVisible(yes);
511 ui.sbSpectrum->setVisible(yes);
512 // if (yes)
513 //{// plot agains log value
514 // ui.tWorkspaces->showColumn(3);
515 // ui.tWorkspaces->horizontalHeaderItem(2)->setData(Qt::DisplayRole,"Spectrum");
516 // int spec = defaultSpectrum();
517 // for(int row = 0; row < rowCount(); ++row)
518 // {
519 // setSpectrum(row,spec);
520 // }
521 //}
522 // else
523 //{// plot against "spectra" axis values
524 // if (rowCount() == 1)
525 // {
526 // ui.tWorkspaces->hideColumn(3);
527 // ui.tWorkspaces->horizontalHeaderItem(2)->setData(Qt::DisplayRole,"Range");
528 // Mantid::API::MatrixWorkspace_sptr ws =
529 // std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
530 // Mantid::API::AnalysisDataService::Instance().retrieve(name(0).toStdString())
531 // );
532 // Mantid::API::Axis* y = ws->getAxis(1);
533 // setRange(0,(*y)(0),(*y)(y->length()-1));
534 // }
535 //}
536}
537
542 ui.btnDelete->setEnabled(ui.tWorkspaces->selectionModel()->hasSelection());
543}
544} // namespace MantidWidgets
545} // namespace MantidQt
double value
The value of the point.
Definition: FitMW.cpp:51
double error
Definition: IndexPeaks.cpp:133
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
static bool openUrl(const QUrl &url)
Opens a url in the appropriate web browser.
Class FitPropertyBrowser implements QtPropertyBrowser to display and control fitting function paramet...
void updateParameters()
Update the function parameters.
bool isHistogramFit() const
Get "HistogramFit" option.
std::shared_ptr< Mantid::API::CompositeFunction > compositeFunction() const
Get Composite Function.
std::string workspaceName() const
Get the input workspace name.
int workspaceIndex() const
Get workspace index.
int maxIterations() const
Get the max number of iterations.
std::string minimizer(bool withProperties=false) const
Get the minimizer.
PropertyHandler * getHandler() const
Get handler to the root composite function.
virtual std::string outputName() const
Get the output name.
std::shared_ptr< Mantid::API::CompositeFunction > m_compositeFunction
A copy of the edited function.
std::string costFunction() const
Get the cost function.
void updateErrors()
Set all parameter error values in the manager.
This is a dialog for selecting workspaces.
QStringList getSelectedNames() const
Return the selected names.
SequentialFitDialog(FitPropertyBrowser *fitBrowser, QObject *mantidui)
Default constructor.
void addWorkspace()
Add a workspace to the data list.
void getFitResults()
Set the parameters to the fit outcome.
void needShowPlot(Ui::SequentialFitDialog *, MantidQt::MantidWidgets::FitPropertyBrowser *)
This signal is fired from finishHandle running in the algorithm's thread and caught by showPlot slot ...
bool isFile(int row) const
Return true if data source in a row is a file (rather than a workspace)
void accept() override
Start the fit and close dialog.
void setRange(int row, double from, double to)
void selectionChanged()
called when selection in the workspace table changes
void functionChanged()
Actions in response to change of function.
void finishHandle(const Mantid::API::IAlgorithm *alg) override
Called when the fit is finished.
Ui::SequentialFitDialog ui
The form generated with Qt Designer.
void addFile()
Add a file to the data list.
FitPropertyBrowser * m_fitBrowser
Pointer to the calling fit browser.
bool validateLogs(const QString &wsName)
Checks that the logs in workspace wsName are consistent with logs of other workspaces.
void setWSIndex(int row, int wi)
set workspace index for workspace/file in row row
void setSpectrum(int row, int spec)
set spectrum value for workspace/file in row row
bool addWorkspaces(const QStringList &wsNames)
Add a list of workspace names to the data list Returns false if neither of the workspaces can be load...
void spectraChanged(int row, int col)
called when spectra or workspace index change
void populateParameters()
Populate parameter combo box with possible parameter names.
void observeFinish(const IAlgorithm_const_sptr &alg)
Connect to algorithm alg and observe its finish notification.
Class to represent the axis of a workspace.
Definition: Axis.h:30
IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:45
TableRow represents a row in a TableWorkspace.
Definition: TableRow.h:39
double & Double(size_t col)
Returns a reference to the element in position col if its type is double.
Definition: TableRow.h:137
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
A specialised Property class for holding a series of time-value pairs.
The AlgorithmProgressDialogPresenter keeps track of the running algorithms and displays a progress ba...
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class