Newer
Older
Owen Arnold
committed
#include "MantidVatesAPI/vtkThresholdingLineFactory.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkSmartPointer.h"
#include "vtkLine.h"
#include "MantidGeometry/MDGeometry/Coordinate.h"
#include "MDDataObjects/MDIndexCalculator.h"
#include <vector>
Owen Arnold
committed
#include <boost/math/special_functions/fpclassify.hpp>
Janik Zikovsky
committed
#include "MantidAPI/IMDWorkspace.h"
using Mantid::API::IMDWorkspace;
Owen Arnold
committed
namespace Mantid
{
namespace VATES
{
vtkThresholdingLineFactory::vtkThresholdingLineFactory(const std::string& scalarName, double minThreshold, double maxThreshold) : m_scalarName(scalarName),
m_minThreshold(minThreshold), m_maxThreshold(maxThreshold)
{
}
Owen Arnold
committed
/**
Assigment operator
@param other : vtkThresholdingLineFactory to assign to this instance from.
@return ref to assigned current instance.
*/
vtkThresholdingLineFactory& vtkThresholdingLineFactory::operator=(const vtkThresholdingLineFactory& other)
{
if(this != &other)
{
this->m_scalarName = other.m_scalarName;
this->m_minThreshold = other.m_minThreshold;
this->m_maxThreshold = other.m_maxThreshold;
this->m_workspace = other.m_workspace;
}
return *this;
}
/**
Copy Constructor
@param other : instance to copy from.
*/
vtkThresholdingLineFactory::vtkThresholdingLineFactory(const vtkThresholdingLineFactory& other)
{
this->m_scalarName = other.m_scalarName;
this->m_minThreshold = other.m_minThreshold;
this->m_maxThreshold = other.m_maxThreshold;
this->m_workspace = other.m_workspace;
}
Owen Arnold
committed
vtkDataSet* vtkThresholdingLineFactory::create() const
{
validate();
//use the successor factory's creation method if this type cannot handle the dimensionality of the workspace.
size_t nonIntegratedSize = m_workspace->getNonIntegratedDimensions().size();
Owen Arnold
committed
if(nonIntegratedSize != vtkDataSetFactory::OneDimensional)
Owen Arnold
committed
{
return m_successor->create();
}
else
{
const int nBinsX = static_cast<int>( m_workspace->getXDimension()->getNBins() );
const double maxX = m_workspace-> getXDimension()->getMaximum();
const double minX = m_workspace-> getXDimension()->getMinimum();
double incrementX = (maxX - minX) / (nBinsX-1);
const int imageSize = nBinsX;
vtkPoints *points = vtkPoints::New();
points->Allocate(static_cast<int>(imageSize));
vtkFloatArray * signal = vtkFloatArray::New();
signal->Allocate(imageSize);
signal->SetName(m_scalarName.c_str());
signal->SetNumberOfComponents(1);
//The following represent actual calculated positions.
double posX;
UnstructuredPoint unstructPoint;
float signalScalar;
Owen Arnold
committed
const int nPointsX = nBinsX;
Column column(nPointsX);
//Loop through dimensions
for (int i = 0; i < nPointsX; i++)
{
posX = minX + (i * incrementX); //Calculate increment in x;
signalScalar = static_cast<float>(m_workspace->getSignalNormalizedAt(i));
Owen Arnold
committed
if (boost::math::isnan( signalScalar ) || (signalScalar < m_minThreshold) || (signalScalar > m_maxThreshold))
Owen Arnold
committed
{
//Flagged so that topological and scalar data is not applied.
unstructPoint.isSparse = true;
}
else
{
if (i < (nBinsX -1))
{
signal->InsertNextValue(static_cast<float>(signalScalar));
Owen Arnold
committed
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
}
unstructPoint.isSparse = false;
}
unstructPoint.pointId = points->InsertNextPoint(posX, 0, 0);
column[i] = unstructPoint;
}
points->Squeeze();
signal->Squeeze();
vtkUnstructuredGrid *visualDataSet = vtkUnstructuredGrid::New();
visualDataSet->Allocate(imageSize);
visualDataSet->SetPoints(points);
visualDataSet->GetCellData()->SetScalars(signal);
for (int i = 0; i < nBinsX - 1; i++)
{
//Only create topologies for those cells which are not sparse.
if (!column[i].isSparse)
{
vtkLine* line = vtkLine::New();
line->GetPointIds()->SetId(0, column[i].pointId);
line->GetPointIds()->SetId(1, column[i + 1].pointId);
visualDataSet->InsertNextCell(VTK_LINE, line->GetPointIds());
}
}
points->Delete();
signal->Delete();
visualDataSet->Squeeze();
return visualDataSet;
}
}
vtkDataSet* vtkThresholdingLineFactory::createMeshOnly() const
{
throw std::runtime_error("::createMeshOnly() does not apply for this type of factory.");
}
vtkFloatArray* vtkThresholdingLineFactory::createScalarArray() const
{
throw std::runtime_error("::createScalarArray() does not apply for this type of factory.");
}
Janik Zikovsky
committed
void vtkThresholdingLineFactory::initialize(Mantid::API::Workspace_sptr wspace_sptr)
Owen Arnold
committed
{
Janik Zikovsky
committed
m_workspace = boost::dynamic_pointer_cast<IMDWorkspace>(wspace_sptr);
Owen Arnold
committed
validate();
// When the workspace can not be handled by this type, take action in the form of delegation.
size_t nonIntegratedSize = m_workspace->getNonIntegratedDimensions().size();
Owen Arnold
committed
if(nonIntegratedSize != vtkDataSetFactory::OneDimensional)
Owen Arnold
committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
{
if(this->hasSuccessor())
{
m_successor->initialize(m_workspace);
return;
}
else
{
throw std::runtime_error("There is no successor factory set for this vtkThresholdingLineFactory type");
}
}
}
void vtkThresholdingLineFactory::validate() const
{
if(NULL == m_workspace.get())
{
throw std::runtime_error("IMDWorkspace is null");
}
}
vtkThresholdingLineFactory::~vtkThresholdingLineFactory()
{
}
}