Newer
Older
#include "MantidVatesAPI/MDHWInMemoryLoadingPresenter.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/IAlgorithm.h"
#include "MantidVatesAPI/MDLoadingView.h"
#include "MantidVatesAPI/MetaDataExtractorUtils.h"
#include "MantidVatesAPI/ProgressAction.h"
#include "MantidVatesAPI/vtkDataSetFactory.h"
#include "MantidVatesAPI/WorkspaceProvider.h"
#include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"
#include <qwt_double_interval.h>
#include <vtkUnstructuredGrid.h>
namespace Mantid {
namespace VATES {
/*
Constructor
@param view : MVP view
@param repository : Object for accessing the workspaces
@param wsName : Name of the workspace to use.
@throw invalid_argument if the workspace name is empty
@throw invalid_argument if the repository is null
@throw invalid_arument if view is null
*/
MDHWInMemoryLoadingPresenter::MDHWInMemoryLoadingPresenter(
MDLoadingView *view, WorkspaceProvider *repository, std::string wsName)
: MDHWLoadingPresenter(view), m_repository(repository), m_wsName(wsName),
m_wsTypeName(""), m_specialCoords(-1) {
if (m_wsName.empty()) {
throw std::invalid_argument("The workspace name is empty.");
}
if (NULL == repository) {
throw std::invalid_argument("The repository is NULL");
}
if (NULL == m_view) {
throw std::invalid_argument("View is NULL.");
}
}
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
/*
Indicates whether this presenter is capable of handling the type of file that is
attempted to be loaded.
@return false if the file cannot be read.
*/
bool MDHWInMemoryLoadingPresenter::canReadFile() const {
bool bCanReadIt = true;
if (!m_repository->canProvideWorkspace(m_wsName)) {
// The workspace does not exist.
bCanReadIt = false;
} else if (NULL ==
boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(
m_repository->fetchWorkspace(m_wsName)).get()) {
// The workspace can be found, but is not an IMDHistoWorkspace.
bCanReadIt = false;
} else {
// The workspace is present, and is of the correct type.
bCanReadIt = true;
}
return bCanReadIt;
}
/**
* @brief MDHWInMemoryLoadingPresenter::transposeWs
*
* vtkDataSets are usually provided in 3D, trying to create these where one of those dimensions
* might be integrated out leads to empty datasets. To avoid this we reorder the dimensions in our workspace
* prior to visualisation by transposing if if needed.
*
* @param histoWs : An input workspace that may integrated dimensions anywhere.
* @return A workspace that can be directly rendered from. Integrated dimensions are always last.
*/
Mantid::API::IMDHistoWorkspace_sptr MDHWInMemoryLoadingPresenter::transposeWs(
Mantid::API::IMDHistoWorkspace_sptr &histoWs) {
using namespace Mantid::API;
if (!m_cachedVisualHistoWs) {
Construct dimension indexes list for transpose. We do this by forcing
integrated
dimensions to be the last in the list. All other orderings are kept.
*/
std::vector<int> integratedDims;
std::vector<int> nonIntegratedDims;
for (int i = 0; i < int(histoWs->getNumDims()); ++i) {
auto dim = histoWs->getDimension(i);
if (dim->getIsIntegrated()) {
integratedDims.push_back(i);
} else {
nonIntegratedDims.push_back(i);
std::vector<int> orderedDims;
orderedDims = nonIntegratedDims;
orderedDims.insert(orderedDims.end(), integratedDims.begin(),
integratedDims.end());
If there has been any reordering above, then the dimension indexes will
no longer be sorted. We use that to determine if we can avoid transposing the workspace.
*/
if (!std::is_sorted(orderedDims.begin(), orderedDims.end())) {
IAlgorithm_sptr alg = AlgorithmManager::Instance().create("TransposeMD");
alg->setChild(true);
alg->initialize();
alg->setProperty("InputWorkspace", histoWs);
alg->setPropertyValue("OutputWorkspace", "dummy");
alg->setProperty("Axes", orderedDims);
alg->execute();
IMDHistoWorkspace_sptr visualHistoWs =
alg->getProperty("OutputWorkspace");
m_cachedVisualHistoWs = visualHistoWs;
} else {
// No need to transpose anything.
m_cachedVisualHistoWs = histoWs;
}
}
return m_cachedVisualHistoWs;
}
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
/*
Executes the underlying algorithm to create the MVP model.
@param factory : visualisation factory to use.
@param : Handler for GUI updates while algorithm progresses.
@param drawingProgressUpdate : Handler for GUI updates while
vtkDataSetFactory::create occurs.
*/
vtkDataSet *
MDHWInMemoryLoadingPresenter::execute(vtkDataSetFactory *factory,
ProgressAction &,
ProgressAction &drawingProgressUpdate) {
using namespace Mantid::API;
using namespace Mantid::Geometry;
Workspace_sptr ws = m_repository->fetchWorkspace(m_wsName);
IMDHistoWorkspace_sptr histoWs =
boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(ws);
auto visualHistoWs = transposeWs(histoWs);
// factory->setRecursionDepth(this->m_view->getRecursionDepth());
vtkDataSet *visualDataSet = factory->oneStepCreate(
visualHistoWs, drawingProgressUpdate); // HACK: progressUpdate should be
// argument for drawing!
/*extractMetaData needs to be re-run here because the first execution of this
from ::executeLoadMetadata will not have ensured that all dimensions
have proper range extents set.
*/
// Update the meta data min and max values with the values of the visual data
// set. This is necessary since we want the full data range of the visual
// data set and not of the actual underlying data set.
double *range = visualDataSet->GetScalarRange();
if (range) {
this->m_metadataJsonManager->setMinValue(range[0]);
this->m_metadataJsonManager->setMaxValue(range[1]);
}
this->appendMetadata(visualDataSet, histoWs->getName());
return visualDataSet;
}
/**
Executes any meta-data loading required.
*/
void MDHWInMemoryLoadingPresenter::executeLoadMetadata() {
using namespace Mantid::API;
Workspace_sptr ws = m_repository->fetchWorkspace(m_wsName);
IMDHistoWorkspace_sptr histoWs =
boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(ws);
m_wsTypeName = histoWs->id();
m_specialCoords = histoWs->getSpecialCoordinateSystem();
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
histoWs = transposeWs(histoWs);
// Set the minimum and maximum of the workspace data.
QwtDoubleInterval minMaxContainer =
m_metaDataExtractor->getMinAndMax(histoWs);
m_metadataJsonManager->setMinValue(minMaxContainer.minValue());
m_metadataJsonManager->setMaxValue(minMaxContainer.maxValue());
// Set the instrument which is associated with the workspace.
m_metadataJsonManager->setInstrument(
m_metaDataExtractor->extractInstrument(histoWs));
// Set the special coordinates
m_metadataJsonManager->setSpecialCoordinates(m_specialCoords);
// Call base-class extraction method.
this->extractMetadata(histoWs);
}
/// Destructor
MDHWInMemoryLoadingPresenter::~MDHWInMemoryLoadingPresenter() { delete m_view; }
/*
* Getter for the workspace type name.
* @return Workspace Type Name
*/
std::string MDHWInMemoryLoadingPresenter::getWorkspaceTypeName() {
return m_wsTypeName;
}
/**
* Getter for the special coordinates.
* @return the special coordinates value
*/
int MDHWInMemoryLoadingPresenter::getSpecialCoordinates() {
return m_specialCoords;
}
std::vector<int> MDHWInMemoryLoadingPresenter::getExtents() {
using namespace Mantid::API;
Workspace_sptr ws = m_repository->fetchWorkspace(m_wsName);
IMDHistoWorkspace_sptr histoWs =
boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(ws);
histoWs = transposeWs(histoWs);
std::vector<int> extents(6, 0);
extents[1] = static_cast<int>(histoWs->getXDimension()->getNBins());
extents[3] = static_cast<int>(histoWs->getYDimension()->getNBins());
extents[5] = static_cast<int>(histoWs->getZDimension()->getNBins());
return extents;
}
}