diff --git a/Code/Mantid/Vates/CMakeLists.txt b/Code/Mantid/Vates/CMakeLists.txt index a431ee4fa67c33f406f04cb0d562b1db685512b3..e8015e6dfb590e81edfd4c476fdb032c9d9f1b74 100644 --- a/Code/Mantid/Vates/CMakeLists.txt +++ b/Code/Mantid/Vates/CMakeLists.txt @@ -7,7 +7,7 @@ project ( Vates ) find_package ( VisIt ) include ( CommonVatesSetup ) -add_subdirectory ( VisitPresenters ) +add_subdirectory ( VatesAPI ) #Select either building Paraview plugins or VisIT plugins. set(USE_PARAVIEW ON CACHE BOOL "Create paraview plugins. If OFF, creates VisIT plugins.") diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt index 31e86710bd4ef9e42a56a906a3a1e4840ebaac9b..4f9c70e1477598e370d333d4918dff2f6e19958f 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt @@ -3,7 +3,7 @@ PROJECT(SQWReader) FIND_PACKAGE(ParaView REQUIRED) INCLUDE(${PARAVIEW_USE_FILE}) -set_mantid_subprojects(Vates/VisitPresenters) +set_mantid_subprojects(Vates/VatesAPI) ADD_PARAVIEW_PLUGIN(SQWReaderSMPlugin "1.0" SERVER_MANAGER_XML SQWReader.xml diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.cxx index 72fa98e776018d6be432e75d64b65e65cca54a17..07d2d21405a1689936b9faf294916932859e40da 100755 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.cxx @@ -10,7 +10,7 @@ #include "vtkFloatArray.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "MantidMDAlgorithms/PlaneImplicitFunction.h" -#include "MantidVisitPresenters/MultiDimensionalDbPresenter.h" +#include "MantidVatesAPI/MultiDimensionalDbPresenter.h" vtkCxxRevisionMacro(vtkSQWReader, "$Revision: 1.0 $"); vtkStandardNewMacro(vtkSQWReader); diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.h index d2625ae6b0c708cd2a791c656c9dd9caf444d610..c6636fc73a3e864a9243bcdf7341f961d760b8c8 100755 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/vtkSQWReader.h @@ -1,7 +1,7 @@ #ifndef _vtkSQWReader_h #define _vtkSQWReader_h -#include "MantidVisitPresenters/MultiDimensionalDbPresenter.h" +#include "MantidVatesAPI/MultiDimensionalDbPresenter.h" #include "vtkStructuredGridAlgorithm.h" class VTK_EXPORT vtkSQWReader : public vtkStructuredGridAlgorithm { diff --git a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1bbc30abbfa44813bf1bcb13f60a900bcfdfa8ff --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt @@ -0,0 +1,92 @@ +# This is mainly here so you don't get a complaint when running cmake +cmake_minimum_required ( VERSION 2.6 ) + +if(NOT USE_PARAVIEW) + include(${VISIT_INCLUDE_DIR}/PluginVsInstall.cmake) + include(${VISIT_INCLUDE_DIR}/VisItLibraryDependencies.cmake) +endif(NOT USE_PARAVIEW) + +project ( VatesAPI ) + +set ( SRC_FILES +src/Clipper.cpp +src/FieldDataToMetadata.cpp +src/MetadataToFieldData.cpp +src/MultiDimensionalDbPresenter.cpp +src/ProgressAction.cpp +src/RebinningCutterPresenter.cpp +src/RebinningCutterXMLDefinitions.cpp +src/RebinningXMLGenerator.cpp +src/vtkDataSetFactory.cpp +src/vtkClipperDataSetFactory.cpp +src/vtkProxyFactory.cpp +src/vtkRectilinearGridFactory.cpp +src/vtkStructuredGridFactory.cpp +src/vtkThresholdingUnstructuredGridFactory.cpp +) + +set ( INC_FILES +inc/MantidVatesAPI/Clipper.h +inc/MantidVatesAPI/FieldDataToMetadata.h +inc/MantidVatesAPI/MetadataToFieldData.h +inc/MantidVatesAPI/MultiDimensionalDbPresenter.h +inc/MantidVatesAPI/ProgressAction.h +inc/MantidVatesAPI/RebinningCutterPresenter.h +inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h +inc/MantidVatesAPI/RebinningXMLGenerator.h +inc/MantidVatesAPI/vtkDataSetFactory.h +inc/MantidVatesAPI/vtkClipperDataSetFactory.h +inc/MantidVatesAPI/vtkProxyFactory.h +inc/MantidVatesAPI/vtkRectilinearGridFactory.h +inc/MantidVatesAPI/vtkStructuredGridFactory.h +inc/MantidVatesAPI/vtkThresholdingUnstructuredGridFactory.h +) + +set (TEST_FILES +test/vtkClipperDataSetFactoryTest.h +test/vtkProxyFactoryTest.h +#test/vtkRectilinearGridFactoryTest.h +#test/vtkStructuredGridFactoryTest.h +#test/vtkThresholdingUnstructuredGridFactoryTest.h +test/FieldDataToMetadataTest.h +test/MultiDimensionalDbPresenterTest.h +test/MetadataToFieldDataTest.h +test/RebinningCutterTest.h +test/RebinningXMLGeneratorTest.h +) + +if( USE_PARAVIEW ) + #ParaView specific + include_directories (${VTK_SOURCE_DIR}/Filtering) + include_directories (${VTK_SOURCE_DIR}/Common) + include_directories (${ParaView_DIR}/VTK) + link_directories ( ${ParaView_DIR}/bin ) # TODO: handle /bin/Debug bin/Release +else( USE_PARAVIEW ) + #VisIT specific + include_directories (${VTK_INCLUDE_DIRS}) + include_directories (inc) + link_directories ( ${VTK_LIBRARY_DIRS} ) +endif( USE_PARAVIEW ) +include_directories (inc) + +# For Windows: +add_definitions ( -DIN_MANTID_VATESAPI ) +# Add the target for this directory +add_library ( VatesAPI ${SRC_FILES} ${INC_FILES}) +# Set the name of the generated library +set_target_properties ( VatesAPI PROPERTIES OUTPUT_NAME MantidVatesAPI ) +# Add to the 'Framework' group in VS +set_property ( TARGET VatesAPI PROPERTY FOLDER "Framework" ) + +target_link_libraries (VatesAPI +${MANTID_SUBPROJECT_LIBS} +vtkCommon +vtkFiltering +) + +# Create test file projects +if ( CXXTEST_FOUND AND GMOCK_FOUND AND GTEST_FOUND ) + cxxtest_add_test ( VatesAPITest ${TEST_FILES} ) + target_link_libraries( VatesAPITest VatesAPI ${GMOCK_LIBRARIES} ) + add_dependencies ( FrameworkTests VatesAPITest ) +endif () diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Clipper.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Clipper.h new file mode 100644 index 0000000000000000000000000000000000000000..995b1415b62d6226b3273ce1d521dfe29ed366f5 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Clipper.h @@ -0,0 +1,66 @@ +#ifndef ABSTRACT_CLIPPER_H +#define ABSTRACT_CLIPPER_H +#include "MantidKernel/System.h" + +//Forward declarations +class vtkDataSet; +class vtkUnstructuredGrid; +class vtkImplicitFunction; + +namespace Mantid +{ +namespace VATES +{ + + /** Abstract clipper type. Allows full separation of vendor specific vtk technology from back end. + + @author Owen Arnold, Tessella plc + @date 07/02/2011 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +class DLLExport Clipper +{ +public: + + virtual void SetInput(vtkDataSet* in_ds) =0; + + virtual void SetClipFunction(vtkImplicitFunction* func) =0; + + virtual void SetInsideOut(bool insideout) =0; + + virtual void SetRemoveWholeCells(bool removeWholeCells) =0; + + virtual void SetOutput(vtkUnstructuredGrid* out_ds) =0; + + virtual void Update() = 0; + + virtual ~Clipper() =0; + + virtual void Delete() = 0; +}; + +} +} + + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/FieldDataToMetadata.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/FieldDataToMetadata.h new file mode 100644 index 0000000000000000000000000000000000000000..c3e2c02ce42a578ad8f24a08dac567e7a5f3f50d --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/FieldDataToMetadata.h @@ -0,0 +1,54 @@ +#ifndef FIELDDATA_TO_METADATA_H_ +#define FIELDDATA_TO_METADATA_H_ + +#include <functional> +#include <string> +#include "MantidKernel/System.h" + +class vtkFieldData; +namespace Mantid +{ +namespace VATES +{ + +/** + * Functor Converts fielddata of type vtkFieldData to metadata (std::string). + * + @author Owen Arnold, Tessella plc + @date 09/02/2011 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +class DLLExport FieldDataToMetadata : public std::binary_function<vtkFieldData*, std::string, std::string> +{ +public: + /// Act as Functor. + std::string operator()(vtkFieldData* fieldData, std::string id) const; + + /// Explicit call to Functor execution. + std::string execute(vtkFieldData* fieldData,const std::string& id) const; +}; + +} +} + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataToFieldData.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataToFieldData.h new file mode 100644 index 0000000000000000000000000000000000000000..86a5bfef519ea5be44f092832362b5e3d6560e20 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataToFieldData.h @@ -0,0 +1,53 @@ +#ifndef METADATATOFIELDDATA_H_ +#define METADATATOFIELDDATA_H_ + +#include <functional> +#include <string> +#include "MantidKernel/System.h" +class vtkFieldData; +namespace Mantid +{ +namespace VATES +{ + +/** + * Functor converts metadata (in std::string) to vtkFieldData. + * + @author Owen Arnold, Tessella plc + @date 09/02/2011 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +class DLLExport MetadataToFieldData +{ +public: + /// Act as Functor. + void operator()(vtkFieldData* fieldData, std::string metaData, std::string id) const; + + /// Explicit call to Functor execution. + void execute(vtkFieldData* fieldData, std::string metaData, std::string id) const; +}; + +} +} + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MultiDimensionalDbPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MultiDimensionalDbPresenter.h new file mode 100644 index 0000000000000000000000000000000000000000..a7282bf0ea06a7e6b715ae8e836f071d43761803 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MultiDimensionalDbPresenter.h @@ -0,0 +1,99 @@ +#ifndef MULTIDIMENSIONAL_DBPRESENTER_H_ +#define MULTIDIMENSIONAL_DBPRESENTER_H_ + +#include <vtkStructuredGrid.h> +#include <vtkFieldData.h> +#include "MDDataObjects/MDWorkspace.h" + +namespace Mantid +{ +namespace VATES +{ +/** + + Applies indirection between visualisation framework and Mantid. This type drives data loading operations. + + @author Owen Arnold, Tessella plc + @date 21/12/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + + +class DLLExport MultiDimensionalDbPresenter +{ + +private: + + // Flag indicates successful execution. + bool m_isExecuted; + + // Rebinned dataset in form of MDWorkspace. + Mantid::MDDataObjects::MDWorkspace_sptr m_MDWorkspace; + + //Verify that execution has occured otherwise should not be able to access scalar data or mesh. + void verifyExecution() const; + +public: + + /// Constructor loads data. + MultiDimensionalDbPresenter(); + + // Performs the rebinning. + void execute(const std::string& fileName); + + /// Gets the vtk mesh; + vtkDataSet* getMesh() const; + + /// Gets the vtk scalar data for the mesh. Generated scalar data is provided with the specified name. + vtkDataArray* getScalarDataFromTimeBin(int timeBin, const char *scalarName) const; + + /// Gets the vtk scalar data for the mesh. Generated scalar data is provided with a specified name. + vtkDataArray* getScalarDataFromTime(double time, const char* scalarName) const; + + /// Gets the number of timesteps in the workspace. + int getNumberOfTimesteps() const; + + /// Get the actual timestep values to use. + std::vector<double> getTimesteps() const; + + /// Get the actual cycle values to use. + std::vector<int> getCycles() const; + + /// Get x axis name so that it may be applied to labels. + std::string getXAxisName() const; + + /// Get y axis name so that it may be applied to labels. + std::string getYAxisName() const; + + /// Get z axis name so that it may be applied to labels. + std::string getZAxisName() const; + + /// Destructor + ~MultiDimensionalDbPresenter(); + + +}; +} +} + + +#endif /* MULTIDIMENSIONALDB_PRESENTER_H_ */ diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ProgressAction.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ProgressAction.h new file mode 100644 index 0000000000000000000000000000000000000000..8552a899320f671f9b2ee96689c0225a3c99ed5f --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ProgressAction.h @@ -0,0 +1,57 @@ + +#ifndef _EVENT_HANDLER_H_ +#define _EVENT_HANDLER_H_ + +#include <Poco/ActiveMethod.h> +#include <Poco/NotificationCenter.h> +#include <Poco/Notification.h> +#include <Poco/NObserver.h> +#include <MantidAPI/Algorithm.h> +namespace Mantid +{ +namespace VATES +{ + +/** Abstract update event type. Allows notification of visualisation top layer/viewer about events without specifying a concrete interactor. + + @author Owen Arnold, Tessella plc + @date 10/02/2011 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +class DLLExport ProgressAction +{ + +public: + + /// Constructor + ProgressAction(); + + /// Handle event updates. + virtual void eventRaised(int progressPercent) = 0; + + void handler(const Poco::AutoPtr<Mantid::API::Algorithm::ProgressNotification>& pNf); + +}; +} +} +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterPresenter.h new file mode 100644 index 0000000000000000000000000000000000000000..b1114508c54322fc3e1a369e003e57e75c21b02e --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterPresenter.h @@ -0,0 +1,190 @@ +#ifndef VATES_REBINNING_PRESENTER_H_ +#define VATES_REBINNING_PRESENTER_H_ + +#include <vtkUnstructuredGrid.h> +#include <vtkBox.h> + +#include "MDDataObjects/MDWorkspace.h" +#include <MantidAPI/ImplicitFunctionFactory.h> +#include <MantidAPI/ImplicitFunction.h> +#include <MantidMDAlgorithms/CompositeImplicitFunction.h> +#include <MantidGeometry/MDGeometry/IMDDimension.h> +#include <boost/shared_ptr.hpp> +#include <MantidVatesAPI/RebinningXMLGenerator.h> +#include <MantidVatesAPI/ProgressAction.h> + +#include <Poco/ActiveMethod.h> +#include <Poco/NotificationCenter.h> +#include <Poco/Notification.h> +#include <Poco/NObserver.h> +#include <MantidAPI/Algorithm.h> + +//Forward declarations +namespace Poco +{ +namespace XML +{ +class XMLElement; +} +} + +namespace Mantid +{ +namespace VATES +{ +/** + + Applies indirection between for mappings between third-party visualisation framework and mantid. + This type supports rebinning operations. + + @author Owen Arnold, Tessella plc + @date 03/11/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +/// Vector of IMDDimension shared pointers. +typedef std::vector<boost::shared_ptr<Mantid::Geometry::IMDDimension> > DimensionVec; +/// IMDDimension as shared pointer. +typedef boost::shared_ptr<Mantid::Geometry::IMDDimension> Dimension_sptr; +/// Flags what should be don on the current iteration. +enum RebinningIterationAction { + RecalculateAll, // Rebin and create 3D visualisation slice from 4D dataset. + RecalculateVisualDataSetOnly, // 4D data set has not altered so create a new visual 3D slice only. + UseCache //There is no delta here. Use a cached vtkDataSet. +}; + +/// Forward declarations +class vtkDataSetFactory; + +/// RebinningCutterPresenter does the work of implemening requests/information provided by pipeline filters. Generates new datasets from +/// current and historical rebinning knowledge accumulated in the pipeline. +class DLLExport RebinningCutterPresenter +{ +private: + + /// Implicit function representing current and historical operations + boost::shared_ptr<Mantid::API::ImplicitFunction> m_function; + + /// initalised flag + bool m_initalized; + + /// Serializer to create and pass on rebinning metadata. + RebinningXMLGenerator m_serializer; + +public: + + /// Constructor + RebinningCutterPresenter(); + + /// Destructor + ~RebinningCutterPresenter(); + + /// Get the generated function. + boost::shared_ptr<Mantid::API::ImplicitFunction> getFunction() const; + + /// Construct reduction knowledge objects + void constructReductionKnowledge( + DimensionVec dimensions, + Dimension_sptr dimensionX, + Dimension_sptr dimensionY, + Dimension_sptr dimensionZ, + Dimension_sptr dimensiont, + Mantid::MDAlgorithms::CompositeImplicitFunction* compositeFunction, + vtkDataSet* inputDataSet); + + void handler(const Poco::AutoPtr<Mantid::API::Algorithm::ProgressNotification>& pNf); + + Mantid::MDDataObjects::MDWorkspace_sptr applyRebinningAction( + Mantid::VATES::RebinningIterationAction action + ,Mantid::VATES::ProgressAction& eventHandler) const; + + /// Apply reduction knowledge to create a vtk dataset. + vtkDataSet* createVisualDataSet(boost::shared_ptr<vtkDataSetFactory> spvtkDataSetFactory); + + /// Get the x dimension from vtkDataSet field data. + Dimension_sptr getXDimensionFromDS(vtkDataSet* vtkDataSetInput) const; + + /// Get the y dimension from vtkDataSet field data. + Dimension_sptr getYDimensionFromDS(vtkDataSet* vtkDataSetInput) const; + + /// Get the z dimension from vtkDataSet field data. + Dimension_sptr getZDimensionFromDS(vtkDataSet* vtkDataSetInput) const; + + /// Get the t dimension from vtkDataSet field data. + Dimension_sptr getTDimensionFromDS(vtkDataSet* vtkDataSetInput) const; + + /// Get the workspace geometry as an xml string. + const std::string& getWorkspaceGeometry() const; + + /// Verify that construct method has been called before anything else. + void VerifyInitalization() const; +}; + +//Non-member helper functions. + + /// Save reduction knowledge object. Serialise to xml and pass to dependent filters. + void persistReductionKnowledge(vtkDataSet * out_ds, + const RebinningXMLGenerator& xmlGenerator, const char* id); + + /// Look for and extract exisiting reduction knowledge in input visualisation dataset. + DLLExport Mantid::API::ImplicitFunction* findExistingRebinningDefinitions(vtkDataSet *in_ds, const char* id); + + //Get the workspace location from the xmlstring. xmlstring is present of vtkFieldData on vtkDataSet. + DLLExport std::string findExistingWorkspaceName(vtkDataSet *in_ds, const char* id); + + //Get the workspace location from the xmlstring. xmlstring is present of vtkFieldData on vtkDataSet. + DLLExport std::string findExistingWorkspaceLocation(vtkDataSet *in_ds, const char* id); + + //Get the workspace geometry from the xmlstring. xmlstring is present of vtkFieldData on vtkDataSet. + DLLExport Poco::XML::Element* findExistingGeometryInformation(vtkDataSet* inputDataSet, const char* id); + + /// Construct an input MDWorkspace by loading from a file. This should be achieved via a seperate loading algorithm. + Mantid::MDDataObjects::MDWorkspace_sptr constructMDWorkspace(const std::string& wsLocation); + + /// Create a geometry from dimensions and then serialise it. + DLLExport std::string constructGeometryXML(DimensionVec dimensions, + Dimension_sptr dimensionX, + Dimension_sptr dimensionY, + Dimension_sptr dimensionZ, + Dimension_sptr dimensiont); + + /// Helper method to get dimensions from a geometry xml element. + DLLExport std::vector<boost::shared_ptr<Mantid::Geometry::IMDDimension> > getDimensions(Poco::XML::Element* geometryElement, bool nonIntegratedOnly = false); + + /// Helper method to get dimensions from a geometry xml string. + DLLExport std::vector<boost::shared_ptr<Mantid::Geometry::IMDDimension> > getDimensions(const std::string& geometryXMLString, bool nonIntegratedOnly = false); + + /// helper method to get a dimension from a dimension xml element. + DLLExport Mantid::Geometry::MDDimension* createDimension(Poco::XML::Element* dimensionXML); + + /// helper method to get a dimension from a dimension xml element string. + DLLExport Mantid::VATES::Dimension_sptr createDimension(const std::string& dimensionXMLString); + + /// helper method to get a dimension from a dimension xml element string and set the number of bins for that dimension to a specified value. + DLLExport Mantid::VATES::Dimension_sptr createDimension(const std::string& dimensionXMLString, int nBins); + + /// helper method to extract the bounding box. + DLLExport std::vector<double> getBoundingBox(const std::string& functionXMLString); + +} +} +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h new file mode 100644 index 0000000000000000000000000000000000000000..ffcc1e481a808f07b59611fe30f33c2436a06e87 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h @@ -0,0 +1,116 @@ +#ifndef REBINNINGCUTTERXMLDEFINITIONS_H_ +#define REBINNINGCUTTERXMLDEFINITIONS_H_ + +#include <string> +#include "MantidKernel/System.h" +namespace Mantid +{ +namespace VATES +{ + +/** + + This type contains definitions that will be found in the xml schema for the rebinning instructions, but must be used in + code as part of the peristance/fetching routines. This file provides a single location for definitions to aid future maintenance. + + @author Owen Arnold, Tessella plc + @date 16/12/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> */ + +//TODO: these definitions may be more appropriate in API/Geometry where they can also be used as part of the parsing. + +class DLLExport XMLDefinitions +{ +public: + //XML schema tag definitions for generating xml. + static const std::string workspaceNameXMLTagStart() + { + return "<MDWorkspaceName>"; + } + static const std::string workspaceNameXMLTagEnd() + { + return "</MDWorkspaceName>"; + } + static const std::string workspaceLocationXMLTagStart() + { + return "<MDWorkspaceLocation>"; + } + static const std::string workspaceLocationXMLTagEnd() + { + return "</MDWorkspaceLocation>"; + } + static const std::string workspaceInstructionXMLTagStart() + { + return "<MDInstruction>"; + } + static const std::string workspaceInstructionXMLTagEnd() + { + return "</MDInstruction>"; + } + ///XML schema tag definitions for finding xml. + static const std::string workspaceNameElementName() + { + return "MDWorkspaceName"; + } + static const std::string functionElementName() + { + return "Function"; + } + static const std::string workspaceLocationElementName() + { + return "MDWorkspaceLocation"; + } + static const std::string workspaceGeometryElementName() + { + return "DimensionSet"; + } + ///An id for recognising specific vtkFieldData objects on inbound and outbound datasets. + static const std::string metaDataId() + { + return "VATES_Metadata"; + } + static const std::string signalName() + { + return "signal"; + } + static const std::string geometryNodeName() + { + return "geometryNodeName"; + } + static const std::string functionNodeName() + { + return "functionNodeName"; + } + static const std::string geometryOperatorInfo() + { + return "geometryOperatorInfo"; + } + static const std::string functionOperatorInfo() + { + return "functionOperatorInfo"; + } + +}; + +} +} +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningXMLGenerator.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningXMLGenerator.h new file mode 100644 index 0000000000000000000000000000000000000000..05b1a9d44cba2fb770f04bca600a004335fa47ad --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningXMLGenerator.h @@ -0,0 +1,98 @@ +#ifndef VATES_REBINNING_XML_GENERATOR_H +#define VATES_REBINNING_XML_GENERATOR_H +#include <boost/shared_ptr.hpp> +#include <string> + +namespace Mantid +{ +/// Forward Declarations; +namespace API +{ +class ImplicitFunction; +class IMDWorkspace; +} + +namespace VATES +{ +/** + + This type assists with the generation of well-formed xml meeting the xsd scehema layed-out for + Rebinning/cutting type operations. The individual components utilised here may not be able to form well-formed + xml in their own right and therefore do not have a toXMLString method. + + This implementation is based on a builder pattern using the create mechanism for xml string generation. + + @author Owen Arnold, Tessella plc + @date 14/12/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> */ + +class DLLExport RebinningXMLGenerator +{ + +private: + + boost::shared_ptr<const Mantid::API::ImplicitFunction> m_spFunction; + std::string m_wsLocationXML; + std::string m_wsNameXML; + std::string m_wsLocation; + std::string m_wsName; + std::string m_geomXML; + + +public: + + RebinningXMLGenerator(); + + /// Set the implicit function to use called. + void setImplicitFunction(boost::shared_ptr<const Mantid::API::ImplicitFunction> spFunction); + + /// Set the workspace name to apply. + void setWorkspace(boost::shared_ptr<const Mantid::API::IMDWorkspace> workspace); + + /// Set the workspace name to apply. + void setWorkspaceName(std::string wsName); + + /// Set the location to apply. + void setWorkspaceLocation(std::string wsLocation); + + /// Set the geometry xml to apply. + void setGeometryXML(std::string geomXML); + + /// Create the xml string correponding to the set values. + std::string createXMLString() const; + + /// Get the underlying workspace location. + const std::string& getWorkspaceLocation() const; + + /// Get the underlying workspace name. + const std::string& getWorkspaceName() const; + + /// Get the underlying workspace geometry. + const std::string& getWorkspaceGeometry() const; +}; + + + + +} +} +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkClipperDataSetFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkClipperDataSetFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..4abce543429fce3c01a72464adb12e9ad893b79d --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkClipperDataSetFactory.h @@ -0,0 +1,67 @@ +#ifndef MANTID_VATES_VTKCLIPPERDATASETFACTORY_H +#define MANTID_VATES_VTKCLIPPERDATASETFACTORY_H + +#include "MantidAPI/ImplicitFunction.h" +#include "MantidVatesAPI/vtkDataSetFactory.h" +#include "MantidVatesAPI/Clipper.h" +#include "boost/scoped_ptr.hpp" +#include "boost/shared_ptr.hpp" + +namespace Mantid +{ +namespace VATES +{ + +/** Factory method implementation. This is an effective vtkAlgorithm in that it uses clipping functions to slice a vtkDataSet based on a provided implicit function. + + @author Owen Arnold, Tessella plc + @date 07/02/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + + +class DLLExport vtkClipperDataSetFactory : public vtkDataSetFactory +{ +public: + /// Constructor + vtkClipperDataSetFactory(boost::shared_ptr<Mantid::API::ImplicitFunction> implicitFunction, vtkDataSet* dataSet, Clipper* clipper); + + /// Destructor + virtual ~vtkClipperDataSetFactory(); + + /// Factory Method. + virtual vtkDataSet* create() const; + +private: + /// Function describing clipping. + boost::shared_ptr<Mantid::API::ImplicitFunction> m_implicitFunction; + + /// Dataset on which to apply clipping. + vtkDataSet* m_dataset; + + boost::scoped_ptr<Clipper> m_clipper; +}; + +} +} + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..e42208b84069ff55904506c3368a4c0854c95c98 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h @@ -0,0 +1,66 @@ + + +#ifndef MANTID_VATES_VTKDATASETFACTORY_H_ +#define MANTID_VATES_VTKDATASETFACTORY_H_ + +#include "MantidKernel/System.h" +#include "boost/shared_ptr.hpp" +#include "vtkDataSet.h" + +namespace Mantid +{ +namespace VATES +{ + +/** Abstract type to generate a vtk dataset on demand from a MDWorkspace. + + @author Owen Arnold, Tessella plc + @date 24/01/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + + + +class DLLExport vtkDataSetFactory +{ + +public: + + /// Constructor + vtkDataSetFactory(); + + /// Destructor + virtual ~vtkDataSetFactory()=0; + + /// Factory Method. + virtual vtkDataSet* create() const=0; + + +}; + +typedef boost::shared_ptr<vtkDataSetFactory> vtkDataSetFactory_sptr; + +} +} + + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkProxyFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkProxyFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..23c3cb9ecb94e8eebc999ee6b2556438d36ae22c --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkProxyFactory.h @@ -0,0 +1,68 @@ +#ifndef MANTID_VATES_VTKPROXYFACTORY_H_ +#define MANTID_VATES_VTKPROXYFACTORY_H_ + +#include "boost/shared_ptr.hpp" +#include "MantidVatesAPI/vtkDataSetFactory.h" + +namespace Mantid +{ +namespace VATES +{ + +/** Proxy Factory. This type acts as a proxy for a previously generated vtkDataSet. Makes core code invarient + * to the requirement to occasionally cache datasets rather than generate them from scratch. + + @author Owen Arnold, Tessella plc + @date 04/02/2011 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +class DLLExport vtkProxyFactory : public vtkDataSetFactory +{ + +public: + + /// Constructor accepting product. + vtkProxyFactory(vtkDataSet* product); + + vtkProxyFactory(const vtkProxyFactory& other); + + vtkProxyFactory& operator=(const vtkProxyFactory& other); + + /// Destructor + virtual ~vtkProxyFactory(); + + /// Factory Method. Returns internal product reference. + virtual vtkDataSet* create() const; + +private: + + //Neither create nor destroy. + vtkDataSet* m_product; + +}; + +} +} + + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkRectilinearGridFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkRectilinearGridFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..137f6dce43cb3fe966422c2eeb230467a25ed1e9 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkRectilinearGridFactory.h @@ -0,0 +1,176 @@ +#ifndef MANTID_VATES_VTKRECTILINEARGRIDFACTORY_H_ +#define MANTID_VATES_VTKRECTILINEARGRIDFACTORY_H_ + +#include "MDDataObjects/MDWorkspace.h" +#include "MantidVatesAPI/vtkDataSetFactory.h" +#include <vtkRectilinearGrid.h> +#include <vtkCellData.h> +#include <vtkDoubleArray.h> +#include <vtkFloatArray.h> + +namespace Mantid +{ +namespace VATES +{ + +template<typename Image> +class DLLExport vtkRectilinearGridFactory : public vtkDataSetFactory +{ +public: + + vtkRectilinearGridFactory(boost::shared_ptr<Image> image, const std::string& scalarName, + const int timestep); + + ~vtkRectilinearGridFactory(); + + /// Constructional method. Have to explicitly ask for a mesh only version. + static vtkRectilinearGridFactory constructAsMeshOnly(boost::shared_ptr<Image> image); + + /// Covarient Factory Method to generate the required mesh type. + virtual vtkRectilinearGrid* create() const; + + /// Generates the geometry of the mesh only. + vtkRectilinearGrid* createMeshOnly() const; + + /// Generates a scalar array for signal. + vtkFloatArray* createScalarArray() const; + +private: + + vtkRectilinearGridFactory(boost::shared_ptr<Image> image); + + boost::shared_ptr<Image> m_image; + std::string m_scalarName; + int m_timestep; + bool m_meshOnly; + +}; + +template<typename Image> +vtkRectilinearGridFactory<Image>::~vtkRectilinearGridFactory() +{ +} + +template<typename Image> +vtkRectilinearGridFactory<Image>::vtkRectilinearGridFactory(boost::shared_ptr<Image> image, + const std::string& scalarName, const int timestep) : + m_image(image), m_scalarName(scalarName), m_timestep(timestep), m_meshOnly(false) +{ +} + +template<typename Image> +vtkRectilinearGridFactory<Image>::vtkRectilinearGridFactory(boost::shared_ptr<Image> image) : m_image(image), m_scalarName(""), m_timestep(0), m_meshOnly(true) +{ +} + +template<typename Image> +vtkRectilinearGridFactory<Image> vtkRectilinearGridFactory<Image>::constructAsMeshOnly(boost::shared_ptr<Image> image) +{ + return vtkRectilinearGridFactory<Image>(image); +} + +template<typename Image> +vtkRectilinearGrid* vtkRectilinearGridFactory<Image>::create() const +{ + vtkRectilinearGrid* visualDataSet = this->createMeshOnly(); + vtkFloatArray* scalarData = this->createScalarArray(); + visualDataSet->GetCellData()->AddArray(scalarData); + scalarData->Delete(); + return visualDataSet; +} + +template<typename Image> +vtkRectilinearGrid* vtkRectilinearGridFactory<Image>::createMeshOnly() const +{ + using namespace MDDataObjects; + //Get geometry nested type information. + typename Image::GeometryType const * const pGeometry = m_image->getGeometry(); + + const int nBinsX = pGeometry->getXDimension()->getNBins(); + const int nBinsY = pGeometry->getYDimension()->getNBins(); + const int nBinsZ = pGeometry->getZDimension()->getNBins(); + + const double maxX = pGeometry-> getXDimension()->getMaximum(); + const double minX = pGeometry-> getXDimension()->getMinimum(); + const double maxY = pGeometry-> getYDimension()->getMaximum(); + const double minY = pGeometry-> getYDimension()->getMinimum(); + const double maxZ = pGeometry-> getZDimension()->getMaximum(); + const double minZ = pGeometry-> getZDimension()->getMinimum(); + + double incrementX = (maxX - minX) / nBinsX; + double incrementY = (maxY - minY) / nBinsY; + double incrementZ = (maxZ - minZ) / nBinsZ; + + const int nPointsX = nBinsX + 1; + const int nPointsY = nBinsY + 1; + const int nPointsZ = nBinsZ + 1; + + vtkRectilinearGrid* visualDataSet = vtkRectilinearGrid::New(); + visualDataSet->SetDimensions(nPointsX, nPointsY, nPointsZ); + vtkDoubleArray* xCoords = vtkDoubleArray::New(); + vtkDoubleArray* yCoords = vtkDoubleArray::New(); + vtkDoubleArray* zCoords = vtkDoubleArray::New(); + + for (int i = 0; i < nPointsX; i++) + { + xCoords->InsertNextValue(minX + (incrementX * i)); + } + for (int j = 0; j < nPointsY; j++) + { + yCoords->InsertNextValue(minY + (incrementY * j)); + } + for (int k = 0; k < nPointsZ; k++) + { + zCoords->InsertNextValue(minZ + (incrementZ * k)); + } + + visualDataSet->SetXCoordinates(xCoords); + visualDataSet->SetYCoordinates(yCoords); + visualDataSet->SetZCoordinates(zCoords); + + return visualDataSet; +} + +template<typename Image> +vtkFloatArray* vtkRectilinearGridFactory<Image>::createScalarArray() const +{ + if(true == m_meshOnly) + { + throw std::runtime_error("This vtkRectilinearGridFactory factory has not been constructed with all the information required to create scalar data."); + } + + using namespace MDDataObjects; + //Get geometry nested type information. + typename Image::GeometryType const * const pGeometry = m_image->getGeometry(); + vtkFloatArray* scalars = vtkFloatArray::New(); + + const int nBinsX = pGeometry->getXDimension()->getNBins(); + const int nBinsY = pGeometry->getYDimension()->getNBins(); + const int nBinsZ = pGeometry->getZDimension()->getNBins(); + + scalars->Allocate(nBinsX * nBinsY * nBinsZ); + scalars->SetName(m_scalarName.c_str()); + + MD_image_point point; + for (int i = 0; i < nBinsX; i++) + { + for (int j = 0; j < nBinsY; j++) + { + for (int k = 0; k < nBinsZ; k++) + { + point = m_image->getPoint(i, j, k, m_timestep); + // Insert scalar data. + scalars->InsertNextValue(point.s); + } + } + } + scalars->Squeeze(); + return scalars; +} + + +} +} + + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkStructuredGridFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkStructuredGridFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..afa53df8129d0977990722f4c7c451ba283d09b4 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkStructuredGridFactory.h @@ -0,0 +1,234 @@ + +#ifndef GENERATESTRUCTUREDGRID_H_ +#define GENERATESTRUCTUREDGRID_H_ + +/** Creates a vtkStructuredGrid (mesh only) from a MDImage. + + @author Owen Arnold, Tessella plc + @date 11/01/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ +#include <vtkStructuredGrid.h> +#include <vtkFloatArray.h> +#include <vtkPoints.h> +#include <vtkCellData.h> +#include "MantidVatesAPI/vtkDataSetFactory.h" +#include "MDDataObjects/MDWorkspace.h" + +namespace Mantid +{ +namespace VATES +{ + +template<typename Image> +class DLLExport vtkStructuredGridFactory : public vtkDataSetFactory +{ +public: + + /// Constructor + vtkStructuredGridFactory(boost::shared_ptr<Image> image, const std::string& scalarName, const int timestep); + + /// Assignment operator + vtkStructuredGridFactory& operator=(const vtkStructuredGridFactory<Image>& other); + + /// Copy constructor. + vtkStructuredGridFactory(const vtkStructuredGridFactory<Image>& other); + + /// Destructor + ~vtkStructuredGridFactory(); + + /// Constructional method. Have to explicitly ask for a mesh only version. + static vtkStructuredGridFactory constructAsMeshOnly(boost::shared_ptr<Image> image); + + /// Factory method + vtkStructuredGrid* create() const; + + /// Generates the geometry of the mesh only. + vtkStructuredGrid* createMeshOnly() const; + + /// Generates a scalar array for signal. + vtkFloatArray* createScalarArray() const; + +private: + + /// Private constructor for use by constructional static member + vtkStructuredGridFactory(boost::shared_ptr<Image> image); + + boost::shared_ptr<Image> m_image; + std::string m_scalarName; + int m_timestep; + bool m_meshOnly; +}; + +template<typename Image> +vtkStructuredGridFactory<Image>::vtkStructuredGridFactory(boost::shared_ptr<Image> image, const std::string& scalarName, const int timestep) : + m_image(image), m_scalarName(scalarName), m_timestep(timestep), m_meshOnly(false) +{ +} + +template<typename Image> +vtkStructuredGridFactory<Image>::vtkStructuredGridFactory(const vtkStructuredGridFactory<Image>& other): + m_image(other.m_image), m_scalarName(other.m_scalarName), m_timestep(other.m_timestep), m_meshOnly(other.m_meshOnly) +{ +} + +template<typename Image> +vtkStructuredGridFactory<Image> & vtkStructuredGridFactory<Image>::operator=(const vtkStructuredGridFactory<Image>& other) +{ + if (this != &other) + { + m_meshOnly = other.m_meshOnly; + m_scalarName = other.m_scalarName; + m_timestep = other.m_timestep; + m_image = other.m_image; + } + return *this; +} + + +template<typename Image> +vtkStructuredGridFactory<Image>::vtkStructuredGridFactory(boost::shared_ptr<Image> image) : m_image(image), m_scalarName(""), m_timestep(0), m_meshOnly(true) +{ +} + +template<typename Image> +vtkStructuredGridFactory<Image> vtkStructuredGridFactory<Image>::constructAsMeshOnly(boost::shared_ptr<Image> image) +{ + return vtkStructuredGridFactory<Image>(image); +} + +template<typename Image> +vtkStructuredGridFactory<Image>::~vtkStructuredGridFactory() +{ +} + +template<typename Image> +vtkStructuredGrid* vtkStructuredGridFactory<Image>::create() const +{ + vtkStructuredGrid* visualDataSet = this->createMeshOnly(); + vtkFloatArray* scalarData = this->createScalarArray(); + visualDataSet->GetCellData()->AddArray(scalarData); + scalarData->Delete(); + return visualDataSet; +} + +template<typename Image> +vtkStructuredGrid* vtkStructuredGridFactory<Image>::createMeshOnly() const +{ + typename Image::GeometryType const * const pGeometry = m_image->getGeometry(); + + const int nBinsX = pGeometry->getXDimension()->getNBins(); + const int nBinsY = pGeometry->getYDimension()->getNBins(); + const int nBinsZ = pGeometry->getZDimension()->getNBins(); + + const double maxX = pGeometry->getXDimension()->getMaximum(); + const double minX = pGeometry->getXDimension()->getMinimum(); + const double maxY = pGeometry->getYDimension()->getMaximum(); + const double minY = pGeometry->getYDimension()->getMinimum(); + const double maxZ = pGeometry->getZDimension()->getMaximum(); + const double minZ = pGeometry->getZDimension()->getMinimum(); + + double incrementX = (maxX - minX) / nBinsX; + double incrementY = (maxY - minY) / nBinsY; + double incrementZ = (maxZ - minZ) / nBinsZ; + + const int imageSize = (nBinsX + 1) * (nBinsY + 1) * (nBinsZ + 1); + vtkStructuredGrid* visualDataSet = vtkStructuredGrid::New(); + vtkPoints *points = vtkPoints::New(); + points->Allocate(imageSize); + + //The following represent actual calculated positions. + double posX, posY, posZ; + //Loop through dimensions + double currentXIncrement, currentYIncrement; + + int nPointsX = nBinsX+1; + int nPointsY = nBinsY+1; + int nPointsZ = nBinsZ+1; + for (int i = 0; i < nPointsX; i++) + { + currentXIncrement = i*incrementX; + for (int j = 0; j < nPointsY; j++) + { + currentYIncrement = j*incrementY; + for (int k = 0; k < nPointsZ; k++) + { + posX = minX + currentXIncrement; //Calculate increment in x; + posY = minY + currentYIncrement; //Calculate increment in y; + posZ = minZ + k*incrementZ; //Calculate increment in z; + points->InsertNextPoint(posX, posY, posZ); + } + } + } + + //Attach points to dataset. + visualDataSet->SetPoints(points); + visualDataSet->SetDimensions(nPointsZ, nPointsY, nPointsX); + points->Delete(); + return visualDataSet; +} + +template<typename Image> +vtkFloatArray* vtkStructuredGridFactory<Image>::createScalarArray() const +{ + if(true == m_meshOnly) + { + throw std::runtime_error("This vtkStructuredGridFactory factory has not been constructed with all the information required to create scalar data."); + } + + using namespace MDDataObjects; + //Get geometry nested type information. + typename Image::GeometryType const * const pGeometry = m_image->getGeometry(); + + //Add scalar data to the mesh. + vtkFloatArray* scalars = vtkFloatArray::New(); + + const int sizeX = pGeometry->getXDimension()->getNBins(); + const int sizeY = pGeometry->getYDimension()->getNBins(); + const int sizeZ = pGeometry->getZDimension()->getNBins(); + scalars->Allocate(sizeX * sizeY * sizeZ); + scalars->SetName(m_scalarName.c_str()); + + MD_image_point point; + for (int i = 0; i < sizeX; i++) + { + for (int j = 0; j < sizeY; j++) + { + for (int k = 0; k < sizeZ; k++) + { + // Create an image from the point data. + point = m_image->getPoint(i, j, k, m_timestep); + // Insert scalar data. + scalars->InsertNextValue(point.s); + } + } + } + scalars->Squeeze(); + return scalars; +} + +} +} + + + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkThresholdingUnstructuredGridFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkThresholdingUnstructuredGridFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..5f58dcb1ee2196825e10d8c31df30dd81d4aea49 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkThresholdingUnstructuredGridFactory.h @@ -0,0 +1,243 @@ +#ifndef MANTID_VATES_VTKUNSTRUCTUREDGRIDFACTORY_H_ +#define MANTID_VATES_VTKUNSTRUCTUREDGRIDFACTORY_H_ + +/** Concrete implementation of vtkDataSetFactory. Creates a vtkUnStructuredGrid. Uses Thresholding technique + * to create sparse representation of data. + + @author Owen Arnold, Tessella plc + @date 24/01/2010 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +#include "MantidVatesAPI/vtkDataSetFactory.h" +#include "MDDataObjects/MDWorkspace.h" +#include <vtkUnstructuredGrid.h> +#include <vtkFloatArray.h> +#include <vtkCellData.h> +#include <vtkHexahedron.h> + +namespace Mantid +{ +namespace VATES +{ + +/// Helper struct allows recognition of points that we should not bother to draw. +struct UnstructuredPoint +{ + bool isSparse; + vtkIdType pointId; +}; + +template<typename Image> +class DLLExport vtkThresholdingUnstructuredGridFactory: public vtkDataSetFactory +{ +public: + + /// Constructor + vtkThresholdingUnstructuredGridFactory(boost::shared_ptr<Image> image, const std::string& scalarname, + const int timestep, double threshold = 0); + + /// Destructor + ~vtkThresholdingUnstructuredGridFactory(); + + /// Factory method + vtkUnstructuredGrid* create() const; + + typedef std::vector<std::vector<std::vector<UnstructuredPoint> > > PointMap; + + typedef std::vector<std::vector<UnstructuredPoint> > Plane; + + typedef std::vector<UnstructuredPoint> Column; + +private: + + /// Image from which to draw. + boost::shared_ptr<Image> m_image; + + /// timestep obtained from framework. + const int m_timestep; + + /// Name of the scalar to provide on mesh. + const std::string m_scalarName; + + /// Threshold for signal value, below which we do not provide unstructured topologies for. + const double m_threshold; + + /// Create a hexahedron. + inline vtkHexahedron* createHexahedron(PointMap& pointMap, const int& i, const int& j, const int& k) const; + +}; + +template<typename Image> +vtkThresholdingUnstructuredGridFactory<Image>::vtkThresholdingUnstructuredGridFactory(boost::shared_ptr< + Image> image, const std::string& scalarName, const int timestep, double threshold) : + m_image(image), m_timestep(timestep), m_scalarName(scalarName), m_threshold(threshold) +{ +} + +template<typename Image> +vtkUnstructuredGrid* vtkThresholdingUnstructuredGridFactory<Image>::create() const +{ + using namespace Mantid::MDDataObjects; + typename Image::GeometryType const * const pGeometry = m_image->getGeometry(); + + const int nBinsX = pGeometry->getXDimension()->getNBins(); + const int nBinsY = pGeometry->getYDimension()->getNBins(); + const int nBinsZ = pGeometry->getZDimension()->getNBins(); + + const double maxX = pGeometry-> getXDimension()->getMaximum(); + const double minX = pGeometry-> getXDimension()->getMinimum(); + const double maxY = pGeometry-> getYDimension()->getMaximum(); + const double minY = pGeometry-> getYDimension()->getMinimum(); + const double maxZ = pGeometry-> getZDimension()->getMaximum(); + const double minZ = pGeometry-> getZDimension()->getMinimum(); + + double incrementX = (maxX - minX) / nBinsX; + double incrementY = (maxY - minY) / nBinsY; + double incrementZ = (maxZ - minZ) / nBinsZ; + + const int imageSize = (nBinsX + 1) * (nBinsY + 1) * (nBinsZ + 1); + vtkPoints *points = vtkPoints::New(); + points->Allocate(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, posY, posZ; + + UnstructuredPoint unstructPoint; + double currentXIncrement, currentYIncrement; + double signalScalar; + const int nPointsX = nBinsX + 1; + const int nPointsY = nBinsY + 1; + const int nPointsZ = nBinsZ + 1; + PointMap pointMap(nPointsX); + + //Loop through dimensions + for (int i = 0; i < nPointsX; i++) + { + currentXIncrement = i * incrementX; + Plane plane(nPointsY); + for (int j = 0; j < nPointsY; j++) + { + currentYIncrement = j * incrementY; + Column col(nPointsX); + for (int k = 0; k < nPointsZ; k++) + { + posX = minX + currentXIncrement; //Calculate increment in x; + posY = minY + currentYIncrement; //Calculate increment in y; + posZ = minZ + k * incrementZ; //Calculate increment in z; + signalScalar = m_image->getPoint(i, j, k, m_timestep).s; + + if (signalScalar <= m_threshold) + { + //Flagged so that topological and scalar data is not applied. + unstructPoint.isSparse = true; + } + else + { + if ((i < nBinsX) && (j < nBinsY) && (k < nBinsZ)) + { + signal->InsertNextValue(signalScalar); + } + unstructPoint.isSparse = false; + } + unstructPoint.pointId = points->InsertNextPoint(posX, posY, posZ); + col[k] = unstructPoint; + } + plane[j] = col; + } + pointMap[i] = plane; + } + + points->Squeeze(); + signal->Squeeze(); + + vtkUnstructuredGrid *visualDataSet = vtkUnstructuredGrid::New(); + visualDataSet->Allocate(imageSize); + visualDataSet->SetPoints(points); + visualDataSet->GetCellData()->SetScalars(signal); + + for (int i = 0; i < nBinsX; i++) + { + for (int j = 0; j < nBinsY; j++) + { + for (int k = 0; k < nBinsZ; k++) + { + //Only create topologies for those cells which are not sparse. + if (!pointMap[i][j][k].isSparse) + { + // create a hexahedron topology + vtkHexahedron* hexahedron = createHexahedron(pointMap, i, j, k); + visualDataSet->InsertNextCell(VTK_HEXAHEDRON, hexahedron->GetPointIds()); + hexahedron->Delete(); + } + } + } + } + + points->Delete(); + signal->Delete(); + visualDataSet->Squeeze(); + return visualDataSet; +} + +template<typename Image> +inline vtkHexahedron* vtkThresholdingUnstructuredGridFactory<Image>::createHexahedron(PointMap& pointMap, const int& i, const int& j, const int& k) const +{ + vtkIdType id_xyz = pointMap[i][j][k].pointId; + vtkIdType id_dxyz = pointMap[i + 1][j][k].pointId; + vtkIdType id_dxdyz = pointMap[i + 1][j + 1][k].pointId; + vtkIdType id_xdyz = pointMap[i][j + 1][k].pointId; + + vtkIdType id_xydz = pointMap[i][j][k + 1].pointId; + vtkIdType id_dxydz = pointMap[i + 1][j][k + 1].pointId; + vtkIdType id_dxdydz = pointMap[i + 1][j + 1][k + 1].pointId; + vtkIdType id_xdydz = pointMap[i][j + 1][k + 1].pointId; + + //create the hexahedron + vtkHexahedron *theHex = vtkHexahedron::New(); + theHex->GetPointIds()->SetId(0, id_xyz); + theHex->GetPointIds()->SetId(1, id_dxyz); + theHex->GetPointIds()->SetId(2, id_dxdyz); + theHex->GetPointIds()->SetId(3, id_xdyz); + theHex->GetPointIds()->SetId(4, id_xydz); + theHex->GetPointIds()->SetId(5, id_dxydz); + theHex->GetPointIds()->SetId(6, id_dxdydz); + theHex->GetPointIds()->SetId(7, id_xdydz); + return theHex; +} + + +template <typename Image> +vtkThresholdingUnstructuredGridFactory<Image>::~vtkThresholdingUnstructuredGridFactory() +{ +} + + +} +} + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/src/Clipper.cpp b/Code/Mantid/Vates/VatesAPI/src/Clipper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7aa867cbf75017b6ece46a60b6a94f931d7fd7bc --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/Clipper.cpp @@ -0,0 +1,13 @@ +#include "MantidVatesAPI/Clipper.h" + +namespace Mantid +{ +namespace VATES +{ + +Clipper::~Clipper() +{ +} + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/FieldDataToMetadata.cpp b/Code/Mantid/Vates/VatesAPI/src/FieldDataToMetadata.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a7f0b736dbd43db3df29f40a0daa6311c8575b4d --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/FieldDataToMetadata.cpp @@ -0,0 +1,41 @@ +#include "MantidVatesAPI/FieldDataToMetadata.h" +#include <boost/algorithm/string.hpp> +#include "vtkFieldData.h" +#include "vtkCharArray.h" + +namespace Mantid +{ +namespace VATES +{ + +std::string FieldDataToMetadata::operator()(vtkFieldData* fieldData, std::string id) const +{ + return execute(fieldData, id); +} + +std::string FieldDataToMetadata::execute(vtkFieldData* fieldData, const std::string& id) const +{ + std::string sXml; + vtkDataArray* arry = fieldData->GetArray(id.c_str()); + if(arry == NULL) + { + throw std::runtime_error("The specified vtk array does not exist"); + } + if (vtkCharArray* carry = dynamic_cast<vtkCharArray*> (arry)) + { + carry->Squeeze(); + for (int i = 0; i < carry->GetSize(); i++) + { + char c = carry->GetValue(i); + if (int(c) > 1) + { + sXml.push_back(c); + } + } + boost::trim(sXml); + } + return sXml; +} + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/MetadataToFieldData.cpp b/Code/Mantid/Vates/VatesAPI/src/MetadataToFieldData.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ca4cfb1005ee8d3e3f30e24727b22765716f4ca --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/MetadataToFieldData.cpp @@ -0,0 +1,37 @@ +#include "MantidVatesAPI/MetadataToFieldData.h" +#include "vtkCharArray.h" +#include "vtkFieldData.h" + +namespace Mantid +{ +namespace VATES +{ + +void MetadataToFieldData::operator()(vtkFieldData* fieldData, std::string metaData, std::string id) const +{ + execute(fieldData, metaData, id); +} + +void MetadataToFieldData::execute(vtkFieldData* fieldData, std::string metaData, std::string id) const +{ + //clean out existing. + vtkDataArray* arry = fieldData->GetArray(id.c_str()); + if(NULL != arry) + { + fieldData->RemoveArray(id.c_str()); + } + //create new. + vtkCharArray* newArry = vtkCharArray::New(); + newArry->Allocate(metaData.size()); + newArry->SetName(id.c_str()); + fieldData->AddArray(newArry); + + for(unsigned int i = 0 ; i < metaData.size(); i++) + { + newArry->InsertNextValue(metaData.at(i)); + } + newArry->Delete(); +} + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/MultiDimensionalDbPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MultiDimensionalDbPresenter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9956a2c5ce5a70e92d86b51c0e3b105a5b2a839d --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/MultiDimensionalDbPresenter.cpp @@ -0,0 +1,184 @@ +#include "MantidVatesAPI/MultiDimensionalDbPresenter.h" +#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/RebinningXMLGenerator.h" +#include "MantidVatesAPI/vtkStructuredGridFactory.h" +#include "MantidVatesAPI/MetadataToFieldData.h" +#include <MantidGeometry/MDGeometry/MDGeometry.h> +#include <MDDataObjects/IMD_FileFormat.h> +#include <MDDataObjects/MD_FileFormatFactory.h> +#include <MDDataObjects/MDWorkspace.h> +#include <MantidMDAlgorithms/CenterpieceRebinning.h> +#include "MantidMDAlgorithms/Load_MDWorkspace.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/WorkspaceFactory.h" +#include <vtkFloatArray.h> +#include <vtkFieldData.h> +#include <boost/shared_ptr.hpp> +#include <vtkCharArray.h> + +namespace Mantid +{ +namespace VATES +{ +MultiDimensionalDbPresenter::MultiDimensionalDbPresenter() : m_isExecuted(false) +{ + +} + +void MultiDimensionalDbPresenter::execute(const std::string& fileName) +{ + using namespace Mantid::MDAlgorithms; + using namespace Mantid::MDDataObjects; + using namespace Mantid::API; + + Load_MDWorkspace wsLoaderAlg; + wsLoaderAlg.initialize(); + std::string wsId = "InputMDWs"; + wsLoaderAlg.setPropertyValue("inFilename", fileName); + wsLoaderAlg.setPropertyValue("MDWorkspace",wsId); + wsLoaderAlg.execute(); + Workspace_sptr result=AnalysisDataService::Instance().retrieve(wsId); + MDWorkspace_sptr inputWS = boost::dynamic_pointer_cast<MDWorkspace>(result); + this->m_MDWorkspace = inputWS; + + m_isExecuted = true; +} + +void MultiDimensionalDbPresenter::verifyExecution() const +{ + if(!this->m_isExecuted) + { + throw std::runtime_error("Cannot get mesh or get variables until rebinning has occured via ::execute()"); + } +} + +std::string MultiDimensionalDbPresenter::getXAxisName() const +{ + //Sanity check. Must run execution sucessfully first. + verifyExecution(); + + return m_MDWorkspace->getGeometry()->getXDimension()->getDimensionId(); +} + +std::string MultiDimensionalDbPresenter::getYAxisName() const +{ + //Sanity check. Must run execution sucessfully first. + verifyExecution(); + + return m_MDWorkspace->getGeometry()->getYDimension()->getDimensionId(); +} + +std::string MultiDimensionalDbPresenter::getZAxisName() const +{ + //Sanity check. Must run execution sucessfully first. + verifyExecution(); + + return m_MDWorkspace->getGeometry()->getZDimension()->getDimensionId(); +} + +vtkDataSet* MultiDimensionalDbPresenter::getMesh() const +{ + using namespace Mantid::MDDataObjects; + + //Sanity check. Must run execution sucessfully first. + verifyExecution(); + + //Create the mesh + vtkStructuredGridFactory<MDImage> factory = vtkStructuredGridFactory<MDImage>::constructAsMeshOnly(m_MDWorkspace->get_spMDImage()); + vtkDataSet* visualDataSet = factory.createMeshOnly(); + + vtkFieldData* outputFD = vtkFieldData::New(); + + //Serialize metadata + RebinningXMLGenerator serializer; + serializer.setWorkspaceName(m_MDWorkspace->getName()); + serializer.setWorkspaceLocation(m_MDWorkspace->getWSLocation()); + serializer.setGeometryXML(m_MDWorkspace->get_const_MDGeometry().toXMLString()); + std::string xmlString = serializer.createXMLString(); + + //Add metadata to dataset. + + MetadataToFieldData convert; + convert(outputFD, xmlString, XMLDefinitions::metaDataId().c_str()); + visualDataSet->SetFieldData(outputFD); + outputFD->Delete(); + return visualDataSet; +} + + +int MultiDimensionalDbPresenter::getNumberOfTimesteps() const +{ + verifyExecution(); + return m_MDWorkspace->gettDimension()->getNBins(); +} + +std::vector<int> MultiDimensionalDbPresenter::getCycles() const +{ + verifyExecution(); + std::vector<int> cycles(m_MDWorkspace->gettDimension()->getNBins()); + for(unsigned int i=0; i < cycles.size(); i++) + { + cycles[i] = i; + } + return cycles; +} + +std::vector<double> MultiDimensionalDbPresenter::getTimesteps() const +{ + using namespace Mantid::Geometry; + verifyExecution(); + boost::shared_ptr<const IMDDimension> tDimension = m_MDWorkspace->gettDimension(); + const double increment = (tDimension->getMaximum() - tDimension->getMinimum())/tDimension->getNBins(); + std::vector<double> times(tDimension->getNBins()); + for(unsigned int i=0; i < tDimension->getNBins(); i++) + { + times[i] = tDimension->getMinimum() + (i*increment); + } + return times; +} + +vtkDataArray* MultiDimensionalDbPresenter::getScalarDataFromTimeBin(int timeBin, const char* scalarName) const +{ + using namespace Mantid::MDDataObjects; + + verifyExecution(); + if(timeBin >= getNumberOfTimesteps()) + { + throw std::range_error("A timestep larger than the range of available timesteps has been requested."); + } + + vtkStructuredGridFactory<MDImage> scalarFactory(m_MDWorkspace->get_spMDImage(), std::string(scalarName), timeBin); + return scalarFactory.createScalarArray(); +} + +vtkDataArray* MultiDimensionalDbPresenter::getScalarDataFromTime(double time, const char* scalarName) const +{ + using namespace Mantid::MDDataObjects; + + verifyExecution(); + //Find the timebin corresponding to the time value provided. + std::vector<double> timeBins = this->getTimesteps(); + double timeBin = timeBins.size() - 1; //Assume it is last. + for(int i = 0; i < timeBins.size()-1; i++) + { + double currentTime = timeBins[i]; + double nextTime = timeBins[i+1]; + if(time >= currentTime && time < nextTime) + { + timeBin = i; + break; + } + } + + return getScalarDataFromTimeBin(timeBin, scalarName); +} + + + +MultiDimensionalDbPresenter::~MultiDimensionalDbPresenter() +{ +} + +} +} + diff --git a/Code/Mantid/Vates/VatesAPI/src/ProgressAction.cpp b/Code/Mantid/Vates/VatesAPI/src/ProgressAction.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1cd5f56f7d7019490a74c260c0e289a4ff4d47fd --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/ProgressAction.cpp @@ -0,0 +1,19 @@ +#include "MantidVatesAPI/ProgressAction.h" + +namespace Mantid +{ +namespace VATES +{ + +ProgressAction::ProgressAction() +{ +} + +void ProgressAction::handler(const Poco::AutoPtr<Mantid::API::Algorithm::ProgressNotification>& pNf) +{ + this->eventRaised(pNf->progress); +} + +} +} + diff --git a/Code/Mantid/Vates/VatesAPI/src/RebinningCutterPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/RebinningCutterPresenter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53328cf22b37bff589ad0780c7befbde3ac5d044 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/RebinningCutterPresenter.cpp @@ -0,0 +1,480 @@ +#include <vtkCharArray.h> +#include <vtkFieldData.h> +#include <vtkHexahedron.h> +#include <sstream> +#include <exception> +#include <boost/shared_ptr.hpp> +#include <vtkImplicitFunction.h> +#include <vtkStructuredGrid.h> +#include <vtkRectilinearGrid.h> +#include <vtkFloatArray.h> +#include <vtkDoubleArray.h> +#include <vtkPointData.h> +#include <vtkCellData.h> +#include <vtkMath.h> + +#include "MantidMDAlgorithms/Load_MDWorkspace.h" +#include "MantidMDAlgorithms/BoxInterpreter.h" +#include "MantidVatesAPI/RebinningCutterPresenter.h" +#include "MantidVatesAPI/RebinningXMLGenerator.h" +#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/vtkStructuredGridFactory.h" +#include "MantidVatesAPI/vtkThresholdingUnstructuredGridFactory.h" +#include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/FieldDataToMetadata.h" + +#include "MantidMDAlgorithms/DimensionFactory.h" +#include "MantidMDAlgorithms/BoxImplicitFunction.h" +#include "MantidMDAlgorithms/DynamicRebinFromXML.h" +#include "MantidGeometry/MDGeometry/MDGeometry.h" +#include "MantidGeometry/MDGeometry/MDGeometryDescription.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MDDataObjects/MD_FileFormatFactory.h" +#include "MantidAPI/AnalysisDataService.h" + +#include "Poco/DOM/DOMParser.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/NodeList.h" +#include "Poco/DOM/NodeIterator.h" +#include "Poco/DOM/NodeFilter.h" +#include "Poco/DOM/NamedNodeMap.h" + +#include <boost/algorithm/string.hpp> +#include <boost/regex.hpp> + +#include "MDDataObjects/MDWorkspace.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidMDAlgorithms/CenterpieceRebinning.h" +#include "MantidMDAlgorithms/Load_MDWorkspace.h" + +namespace Mantid +{ +namespace VATES +{ + +using namespace Mantid::MDAlgorithms; +using namespace Mantid::MDDataObjects; +using namespace Mantid::Geometry; +using namespace Mantid::API; + +struct findID : public std::unary_function <IMDDimension, bool> +{ + const std::string m_id; + findID(const std::string id) : + m_id(id) + { + } + bool operator ()(const boost::shared_ptr<IMDDimension> obj) const + { + return m_id == obj->getDimensionId(); + } +}; + +RebinningCutterPresenter::RebinningCutterPresenter() : m_initalized(false), m_serializer() +{ +} + +RebinningCutterPresenter::~RebinningCutterPresenter() +{ + +} + + +void RebinningCutterPresenter::constructReductionKnowledge( + DimensionVec dimensions, + Dimension_sptr dimensionX, + Dimension_sptr dimensionY, + Dimension_sptr dimensionZ, + Dimension_sptr dimensiont, + CompositeImplicitFunction* compFunction, + vtkDataSet* inputDataSet) +{ + using namespace Mantid::MDAlgorithms; + + //Add existing functions. + Mantid::API::ImplicitFunction* existingFunctions = findExistingRebinningDefinitions(inputDataSet, XMLDefinitions::metaDataId().c_str()); + if (existingFunctions != NULL) + { + compFunction->addFunction(boost::shared_ptr<ImplicitFunction>(existingFunctions)); + } + + m_function = boost::shared_ptr<ImplicitFunction>(compFunction); + //Apply the implicit function. + m_serializer.setImplicitFunction(m_function); + //Apply the geometry. + m_serializer.setGeometryXML(constructGeometryXML(dimensions, dimensionX, dimensionY, dimensionZ, dimensiont)); + //Apply the workspace name after extraction from the input xml. + m_serializer.setWorkspaceName( findExistingWorkspaceName(inputDataSet, XMLDefinitions::metaDataId().c_str())); + //Apply the workspace location after extraction from the input xml. + m_serializer.setWorkspaceLocation( findExistingWorkspaceLocation(inputDataSet, XMLDefinitions::metaDataId().c_str())); + + this->m_initalized = true; +} + +Mantid::MDDataObjects::MDWorkspace_sptr RebinningCutterPresenter::applyRebinningAction( + RebinningIterationAction action, + ProgressAction& eventHandler) const +{ + //Verify that constuction has occured properly first/ + VerifyInitalization(); + + const std::string outputWorkspace = "RebinnedWS"; + if(RecalculateAll == action) + { + //Get the input workspace location and name. + std::string wsLocation = m_serializer.getWorkspaceLocation(); + std::string wsName = m_serializer.getWorkspaceName(); + + MDWorkspace_sptr baseWs = constructMDWorkspace(wsLocation); + AnalysisDataService::Instance().addOrReplace(wsName, baseWs); + + Mantid::MDAlgorithms::DynamicRebinFromXML xmlRebinAlg; + xmlRebinAlg.setRethrows(true); + xmlRebinAlg.initialize(); + + xmlRebinAlg.setPropertyValue("OutputWorkspace", outputWorkspace); + + //Use the serialisation utility to generate well-formed xml expressing the rebinning operation. + std::string xmlString = m_serializer.createXMLString(); + xmlRebinAlg.setPropertyValue("XMLInputString", xmlString); + + Poco::NObserver<ProgressAction, Mantid::API::Algorithm::ProgressNotification> observer(eventHandler, &ProgressAction::handler); + //Add observer. + xmlRebinAlg.addObserver(observer); + //Run the rebinning algorithm. + xmlRebinAlg.execute(); + //Remove observer + xmlRebinAlg.removeObserver(observer); + + } + + //Use the generated workspace to access the underlying image, which may be rendered. + MDWorkspace_sptr outputWs = boost::dynamic_pointer_cast<MDWorkspace>( + AnalysisDataService::Instance().retrieve(outputWorkspace)); + + return outputWs; +} + + +vtkDataSet* RebinningCutterPresenter::createVisualDataSet(vtkDataSetFactory_sptr spvtkDataSetFactory) +{ + + VerifyInitalization(); + + //Generate the visualisation dataset. + vtkDataSet* visualImageData = spvtkDataSetFactory->create(); + + //save the work performed as part of this filter instance into the pipeline. + persistReductionKnowledge(visualImageData, this->m_serializer, XMLDefinitions::metaDataId().c_str()); + return visualImageData; +} + +boost::shared_ptr<Mantid::API::ImplicitFunction> RebinningCutterPresenter::getFunction() const +{ + VerifyInitalization(); + return m_function; +} + +Dimension_sptr RebinningCutterPresenter::getXDimensionFromDS(vtkDataSet* vtkDataSetInput) const +{ + Poco::XML::Element* geometryXMLElement = findExistingGeometryInformation(vtkDataSetInput, XMLDefinitions::metaDataId().c_str() ); + + std::vector<boost::shared_ptr<IMDDimension> > dimensionVec = getDimensions(geometryXMLElement); + + //Find the requested xDimension alignment from the dimension id provided in the xml. + Poco::XML::Element* xDimensionElement = geometryXMLElement->getChildElement("XDimension"); + std::string xDimId = xDimensionElement->getChildElement("RefDimensionId")->innerText(); + DimensionVecIterator xDimensionIt = find_if(dimensionVec.begin(), dimensionVec.end(), findID(xDimId)); + + if (xDimensionIt == dimensionVec.end()) + { + throw std::invalid_argument("Cannot determine x-dimension mapping."); + } + + return *xDimensionIt; +} + +Dimension_sptr RebinningCutterPresenter::getYDimensionFromDS(vtkDataSet* vtkDataSetInput) const +{ + Poco::XML::Element* geometryXMLElement = findExistingGeometryInformation(vtkDataSetInput, XMLDefinitions::metaDataId().c_str() ); + + std::vector<boost::shared_ptr<IMDDimension> > dimensionVec = getDimensions(geometryXMLElement); + + //Find the requested xDimension alignment from the dimension id provided in the xml. + Poco::XML::Element* yDimensionElement = geometryXMLElement->getChildElement("YDimension"); + std::string yDimId = yDimensionElement->getChildElement("RefDimensionId")->innerText(); + DimensionVecIterator yDimensionIt = find_if(dimensionVec.begin(), dimensionVec.end(), findID(yDimId)); + + if (yDimensionIt == dimensionVec.end()) + { + throw std::invalid_argument("Cannot determine y-dimension mapping."); + } + + return *yDimensionIt; +} + +Dimension_sptr RebinningCutterPresenter::getZDimensionFromDS(vtkDataSet* vtkDataSetInput) const +{ + + Poco::XML::Element* geometryXMLElement = findExistingGeometryInformation(vtkDataSetInput, XMLDefinitions::metaDataId().c_str() ); + + std::vector<boost::shared_ptr<IMDDimension> > dimensionVec = getDimensions(geometryXMLElement); + + //Find the requested xDimension alignment from the dimension id provided in the xml. + Poco::XML::Element* zDimensionElement = geometryXMLElement->getChildElement("ZDimension"); + std::string zDimId = zDimensionElement->getChildElement("RefDimensionId")->innerText(); + DimensionVecIterator zDimensionIt = find_if(dimensionVec.begin(), dimensionVec.end(), findID(zDimId)); + + if (zDimensionIt == dimensionVec.end()) + { + throw std::invalid_argument("Cannot determine z-dimension mapping."); + } + + return *zDimensionIt; +} + +Dimension_sptr RebinningCutterPresenter::getTDimensionFromDS(vtkDataSet* vtkDataSetInput) const +{ + Poco::XML::Element* geometryXMLElement = findExistingGeometryInformation(vtkDataSetInput, XMLDefinitions::metaDataId().c_str() ); + + std::vector<boost::shared_ptr<IMDDimension> > dimensionVec = getDimensions(geometryXMLElement); + + //Find the requested xDimension alignment from the dimension id provided in the xml. + Poco::XML::Element* tDimensionElement = geometryXMLElement->getChildElement("TDimension"); + std::string tDimId = tDimensionElement->getChildElement("RefDimensionId")->innerText(); + DimensionVecIterator tDimensionIt = find_if(dimensionVec.begin(), dimensionVec.end(), findID(tDimId)); + + if (tDimensionIt == dimensionVec.end()) + { + throw std::invalid_argument("Cannot determine t-dimension mapping."); + } + + return *tDimensionIt; +} + +const std::string& RebinningCutterPresenter::getWorkspaceGeometry() const +{ + VerifyInitalization(); + return m_serializer.getWorkspaceGeometry(); +} + +void RebinningCutterPresenter::VerifyInitalization() const +{ + if(!m_initalized) + { + //To ensure that constructReductionKnowledge is always called first. + throw std::runtime_error("This instance has not been properly initialised via the construct method."); + } +} + +Mantid::VATES::Dimension_sptr createDimension(const std::string& dimensionXMLString) +{ + DimensionFactory factory = DimensionFactory::createDimensionFactory(dimensionXMLString); + return Mantid::VATES::Dimension_sptr(factory.create()); +} + +Mantid::VATES::Dimension_sptr createDimension(const std::string& dimensionXMLString, int nBins) +{ + DimensionFactory factory = DimensionFactory::createDimensionFactory(dimensionXMLString); + MDDimension* dimension = factory.createAsMDDimension(); + double currentMin = dimension->getMinimum(); + double currentMax = dimension->getMaximum(); + //Set the number of bins to use for a given dimension. + dimension->setRange(currentMin, currentMax, nBins); + return Mantid::VATES::Dimension_sptr(dimension); +} + +std::vector<boost::shared_ptr<Mantid::Geometry::IMDDimension> > getDimensions( + Poco::XML::Element* geometryXMLElement, bool nonIntegratedOnly) +{ + using namespace Mantid::Geometry; + Poco::XML::NodeList* dimensionsXML = geometryXMLElement->getElementsByTagName("Dimension"); + std::vector<boost::shared_ptr<IMDDimension> > dimensionVec; + + //Extract dimensions + int nDimensions = dimensionsXML->length(); + for (int i = 0; i < nDimensions; i++) + { + Poco::XML::Element* dimensionXML = static_cast<Poco::XML::Element*> (dimensionsXML->item(i)); + DimensionFactory factory(dimensionXML); + IMDDimension* dimension = factory.create(); + if (!nonIntegratedOnly || (dimension->getNBins() > 1)) + { + dimensionVec.push_back(boost::shared_ptr<IMDDimension>(dimension)); + } + } + return dimensionVec; +} + +std::vector<boost::shared_ptr<Mantid::Geometry::IMDDimension> > getDimensions( + const std::string& geometryXMLString, bool nonIntegratedOnly) +{ + Poco::XML::DOMParser pParser; + Poco::XML::Document* pDoc = pParser.parseString(geometryXMLString); + Poco::XML::Element* pGeometryElem = pDoc->documentElement(); + return getDimensions(pGeometryElem, nonIntegratedOnly); +} + +std::vector<double> getBoundingBox(const std::string& functionXMLString) +{ + using namespace Mantid::API; + ImplicitFunction* function =ImplicitFunctionFactory::Instance().createUnwrapped(functionXMLString); + Mantid::MDAlgorithms::BoxInterpreter box; + return box(function); +} + +// helper method to construct a near-complete geometry. +std::string constructGeometryXML( + DimensionVec dimensions, + Dimension_sptr dimensionX, + Dimension_sptr dimensionY, + Dimension_sptr dimensionZ, + Dimension_sptr dimensiont) +{ + using namespace Mantid::Geometry; + std::set<MDBasisDimension> basisDimensions; + for(unsigned int i = 0; i < dimensions.size(); i++) + { + //read dimension. + std::string dimensionId = dimensions[i]->getDimensionId(); + bool isReciprocal = dimensions[i]->isReciprocal(); + //basis dimension. + basisDimensions.insert(MDBasisDimension(dimensionId, isReciprocal, i)); + + //NB: Geometry requires both a basis and geometry description to work. Initially all cuts and dimensions treated as orthogonal. + //So that congruent checks pass on the geometry, the basis is fabricated from the dimensions. This is not an ideal implementation. Other designs will + //be considered. + } + + UnitCell cell; // Unit cell currently does nothing. + MDGeometryBasis basis(basisDimensions, cell); + + //TODO: Get Rotation matrix from Plane ImplicitFunction + RotationMatrix identityMatrix(9, 0); + identityMatrix[0] = 1; + identityMatrix[4] = 1; + identityMatrix[8] = 1; + MDGeometryDescription description(dimensions, dimensionX, dimensionY, dimensionZ, dimensiont, identityMatrix); + + //Create a geometry. + MDGeometry geometry(basis, description); + return geometry.toXMLString(); + +} + +void persistReductionKnowledge(vtkDataSet* out_ds, const + RebinningXMLGenerator& xmlGenerator, const char* id) +{ + vtkFieldData* fd = vtkFieldData::New(); + + MetadataToFieldData convert; + convert(fd, xmlGenerator.createXMLString().c_str(), id); + + out_ds->SetFieldData(fd); + fd->Delete(); +} + + +Mantid::API::ImplicitFunction* findExistingRebinningDefinitions( + vtkDataSet* inputDataSet, const char* id) +{ + Mantid::API::ImplicitFunction* function = NULL; + + FieldDataToMetadata convert; + std::string xmlString = convert(inputDataSet->GetFieldData(), id); + if (false == xmlString.empty()) + { + Poco::XML::DOMParser pParser; + Poco::XML::Document* pDoc = pParser.parseString(xmlString); + Poco::XML::Element* pRootElem = pDoc->documentElement(); + Poco::XML::Element* functionElem = pRootElem->getChildElement(XMLDefinitions::functionElementName()); + if(NULL != functionElem) + { + function = Mantid::API::ImplicitFunctionFactory::Instance().createUnwrapped(functionElem); + } + } + return function; +} + +//Get the workspace location from the xmlstring. + std::string findExistingWorkspaceName(vtkDataSet *inputDataSet, const char* id) +{ + FieldDataToMetadata convert; + std::string xmlString = convert(inputDataSet->GetFieldData(), id); + + Poco::XML::DOMParser pParser; + Poco::XML::Document* pDoc = pParser.parseString(xmlString); + Poco::XML::Element* pRootElem = pDoc->documentElement(); + Poco::XML::Element* wsNameElem = pRootElem->getChildElement(XMLDefinitions::workspaceNameElementName()); + if(wsNameElem == NULL) + { + throw std::runtime_error("The element containing the workspace name must be present."); + } + return wsNameElem->innerText(); + +} + + //Get the workspace location from the xmlstring. + std::string findExistingWorkspaceLocation(vtkDataSet *inputDataSet, const char* id) + { + FieldDataToMetadata convert; + std::string xmlString = convert(inputDataSet->GetFieldData(), id); + + Poco::XML::DOMParser pParser; + Poco::XML::Document* pDoc = pParser.parseString(xmlString); + Poco::XML::Element* pRootElem = pDoc->documentElement(); + Poco::XML::Element* wsLocationElem = pRootElem->getChildElement(XMLDefinitions::workspaceLocationElementName()); + if(wsLocationElem == NULL) + { + throw std::runtime_error("The element containing the workspace location must be present."); + } + return wsLocationElem->innerText(); + } + +Poco::XML::Element* findExistingGeometryInformation(vtkDataSet* inputDataSet, const char* id) +{ + FieldDataToMetadata convert; + std::string xmlString = convert(inputDataSet->GetFieldData(), id); + + Poco::XML::DOMParser pParser; + Poco::XML::Document* pDoc = pParser.parseString(xmlString); + Poco::XML::Element* pRootElem = pDoc->documentElement(); + Poco::XML::Element* geometryElem = pRootElem->getChildElement(XMLDefinitions::workspaceGeometryElementName()); + if (geometryElem == NULL) + { + throw std::runtime_error("The element containing the workspace geometry must be present."); + } + return geometryElem; +} + + + //NB: At present, the input workspace is required by the dynamicrebinningfromxml algorithm, but not by the + //sub-algorithm running centerpiece rebinning. + Mantid::MDDataObjects::MDWorkspace_sptr constructMDWorkspace(const std::string& wsLocation) + { + using namespace Mantid::MDDataObjects; + using namespace Mantid::Geometry; + using namespace Mantid::API; + + Mantid::MDAlgorithms::Load_MDWorkspace wsLoaderAlg; + wsLoaderAlg.initialize(); + std::string wsId = "InputMDWs"; + wsLoaderAlg.setPropertyValue("inFilename", wsLocation); + wsLoaderAlg.setPropertyValue("MDWorkspace", wsId); + wsLoaderAlg.execute(); + Workspace_sptr result=AnalysisDataService::Instance().retrieve(wsId); + MDWorkspace_sptr workspace = boost::dynamic_pointer_cast<MDWorkspace>(result); + + return workspace; + } + +} +} + + + + + + diff --git a/Code/Mantid/Vates/VatesAPI/src/RebinningCutterXMLDefinitions.cpp b/Code/Mantid/Vates/VatesAPI/src/RebinningCutterXMLDefinitions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..735d83185fd4b14eaf19fbf129a23706ca4ecf78 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/RebinningCutterXMLDefinitions.cpp @@ -0,0 +1,9 @@ +#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" + +namespace Mantid +{ +namespace VATES +{ + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/RebinningXMLGenerator.cpp b/Code/Mantid/Vates/VatesAPI/src/RebinningXMLGenerator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79fc454aa51a4d24e82f9202b2a33269af4601bc --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/RebinningXMLGenerator.cpp @@ -0,0 +1,95 @@ +#include <MantidAPI/ImplicitFunction.h> +#include <boost/shared_ptr.hpp> +#include <MantidAPI/IMDWorkspace.h> +#include "boost/algorithm/string.hpp" +#include "boost/format.hpp" +#include "MantidVatesAPI/RebinningXMLGenerator.h" +#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" + +namespace Mantid +{ +namespace VATES +{ + +RebinningXMLGenerator::RebinningXMLGenerator() : m_spFunction(), m_wsLocationXML(""), m_wsNameXML(""), m_wsLocation(""), m_wsName(""), m_geomXML("") +{ +} + +void RebinningXMLGenerator::setImplicitFunction(boost::shared_ptr<const Mantid::API::ImplicitFunction> spFunction) +{ + this->m_spFunction = spFunction; +} + +/// Set the workspace name to apply. +void RebinningXMLGenerator::setWorkspace(boost::shared_ptr<const Mantid::API::IMDWorkspace> workspace) +{ + this->m_wsNameXML = XMLDefinitions::workspaceNameXMLTagStart() + workspace->getName() + XMLDefinitions::workspaceNameXMLTagEnd(); + this->m_wsLocation = workspace->getWSLocation(); + this->m_wsLocationXML = XMLDefinitions::workspaceLocationXMLTagStart() + this->m_wsLocation + XMLDefinitions::workspaceLocationXMLTagEnd(); + this->m_geomXML = workspace->getGeometryXML(); +} + +void RebinningXMLGenerator::setWorkspaceName(std::string wsName) +{ + this->m_wsName = wsName; + this->m_wsNameXML = std::string(XMLDefinitions::workspaceNameXMLTagStart() + wsName + XMLDefinitions::workspaceNameXMLTagEnd()); +} + +void RebinningXMLGenerator::setWorkspaceLocation(std::string wsLocation) +{ + + this->m_wsLocation = wsLocation; + this->m_wsLocationXML = std::string(XMLDefinitions::workspaceLocationXMLTagStart() + wsLocation + XMLDefinitions::workspaceLocationXMLTagEnd() ); +} + +void RebinningXMLGenerator::setGeometryXML(std::string geomXML) +{ + this->m_geomXML = geomXML; +} + +/// Create the xml string correponding to the set values. +std::string RebinningXMLGenerator::createXMLString() const +{ + + if(true == this->m_geomXML.empty()) + { + throw std::runtime_error("No geometry provided on workspace."); + } + if(this->m_wsLocationXML == (XMLDefinitions::workspaceLocationXMLTagStart() + XMLDefinitions::workspaceLocationXMLTagEnd())) + { + throw std::runtime_error("No workspace location provided on workspace."); + } + if(this->m_wsNameXML == (XMLDefinitions::workspaceNameXMLTagStart() + XMLDefinitions::workspaceNameXMLTagEnd())) + { + throw std::runtime_error("No workspace name provided on workspace."); + } + + //Check to see if a function has been provided. + if(NULL != m_spFunction.get()) + { + return std::string(XMLDefinitions::workspaceInstructionXMLTagStart() + m_wsNameXML + m_wsLocationXML + m_geomXML + m_spFunction->toXMLString() + XMLDefinitions::workspaceInstructionXMLTagEnd()); + } + else + { + //Functions are optional, so don't provide them as part of the completed xml if not present. + return std::string(XMLDefinitions::workspaceInstructionXMLTagStart() + m_wsNameXML + m_wsLocationXML + m_geomXML + XMLDefinitions::workspaceInstructionXMLTagEnd()); + } +} + +const std::string& RebinningXMLGenerator::getWorkspaceLocation() const +{ + return this->m_wsLocation; +} + +const std::string& RebinningXMLGenerator::getWorkspaceName() const +{ + return this->m_wsName; +} + +const std::string& RebinningXMLGenerator::getWorkspaceGeometry() const +{ + return this->m_geomXML; +} + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkClipperDataSetFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkClipperDataSetFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0be74ca2811e66ee0fbb01d604be6cf1811c9cd4 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkClipperDataSetFactory.cpp @@ -0,0 +1,56 @@ +#include "MantidVatesAPI/vtkClipperDataSetFactory.h" +#include "MantidMDAlgorithms/BoxImplicitFunction.h" +#include "MantidMDAlgorithms/BoxInterpreter.h" +#include "vtkUnstructuredGrid.h" +#include "vtkBox.h" + +namespace Mantid +{ +namespace VATES +{ +/// Constructor +vtkClipperDataSetFactory::vtkClipperDataSetFactory( + boost::shared_ptr<Mantid::API::ImplicitFunction> implicitFunction, + vtkDataSet* dataset, Clipper* clipper) : + m_implicitFunction(implicitFunction), m_dataset(dataset), m_clipper(clipper) +{ +} + +vtkClipperDataSetFactory::~vtkClipperDataSetFactory() +{ +} + +vtkDataSet* vtkClipperDataSetFactory::create() const +{ + using namespace Mantid::MDAlgorithms; + + BoxInterpreter interpreter; + boxVector boxFunctions = interpreter.getAllBoxes(m_implicitFunction.get()); + vtkUnstructuredGrid* output = vtkUnstructuredGrid::New(); + + boxVector::const_iterator it = boxFunctions.begin(); + + for (it; it != boxFunctions.end(); ++it) + { + boost::shared_ptr<BoxImplicitFunction> boxFunction = *it; + vtkBox* box = vtkBox::New(); + box->SetBounds( + boxFunction->getLowerX(), + boxFunction->getUpperX(), + boxFunction->getLowerY(), + boxFunction->getUpperY(), + boxFunction->getLowerZ(), + boxFunction->getUpperZ()); + + m_clipper->SetInput(m_dataset); + m_clipper->SetClipFunction(box); + m_clipper->SetInsideOut(true); + m_clipper->SetRemoveWholeCells(true); + m_clipper->SetOutput(output); + m_clipper->Update(); + box->Delete(); + } + return output; +} +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b99ae50a604231ce26749ddac67f103439881ff7 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetFactory.cpp @@ -0,0 +1,17 @@ +#include "MantidVatesAPI/vtkDataSetFactory.h" + +namespace Mantid +{ +namespace VATES +{ + +vtkDataSetFactory::vtkDataSetFactory() +{ +} + +vtkDataSetFactory::~vtkDataSetFactory() +{ +} + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkProxyFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkProxyFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d1fac638dbf35dfa70076edf7ad851b5b6e6e971 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkProxyFactory.cpp @@ -0,0 +1,37 @@ +#include "MantidVatesAPI/vtkProxyFactory.h" + +namespace Mantid +{ +namespace VATES +{ + +vtkProxyFactory::vtkProxyFactory(vtkDataSet* product) : m_product(product) +{ +} + +vtkProxyFactory::~vtkProxyFactory() +{ +} + +vtkProxyFactory::vtkProxyFactory(const vtkProxyFactory& other) : m_product(other.m_product) +{ +} + +vtkProxyFactory& vtkProxyFactory::operator=(const vtkProxyFactory& other) +{ + if(&other != this) + { + //this->m_product->Delete(); + this->m_product = other.m_product; + } + return *this; +} + +vtkDataSet* vtkProxyFactory::create() const +{ + //Essentially do nothing other than return the cached product. + return this->m_product; +} + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkRectilinearGridFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkRectilinearGridFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5cad118706d29ada5ba47abb3f242663f1f72dd --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkRectilinearGridFactory.cpp @@ -0,0 +1,13 @@ +#include "MantidVatesAPI/vtkRectilinearGridFactory.h" +#include <vtkCellData.h> +#include <vtkDoubleArray.h> +#include <vtkFloatArray.h> + +namespace Mantid +{ + namespace VATES + { + + } +} + diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkStructuredGridFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkStructuredGridFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..05d556eb5f39486a3a25e03701b4d1ffe43a8e2b --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkStructuredGridFactory.cpp @@ -0,0 +1,11 @@ +#include "MantidVatesAPI/vtkStructuredGridFactory.h" + +namespace Mantid +{ +namespace VATES +{ + + +} +} + diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkThresholdingUnstructuredGridFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkThresholdingUnstructuredGridFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..484230a8e7ce05d23619f4ea62f7e14a8985d2b9 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkThresholdingUnstructuredGridFactory.cpp @@ -0,0 +1,10 @@ +#include "MantidVatesAPI/vtkThresholdingUnstructuredGridFactory.h" + + +namespace Mantid +{ +namespace VATES +{ + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/test/ClipperTest.h b/Code/Mantid/Vates/VatesAPI/test/ClipperTest.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Code/Mantid/Vates/VatesAPI/test/FieldDataToMetadataTest.h b/Code/Mantid/Vates/VatesAPI/test/FieldDataToMetadataTest.h new file mode 100644 index 0000000000000000000000000000000000000000..512c97feec7130a766ccf0709629cd38e4e9b82a --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/FieldDataToMetadataTest.h @@ -0,0 +1,79 @@ +#ifndef FIELDDATATOMETADATATEST_H_ +#define FIELDDATATOMETADATATEST_H_ + +#include <cxxtest/TestSuite.h> +#include <vtkCharArray.h> +#include <vtkFieldData.h> +#include "MantidVatesAPI/FieldDataToMetadata.h" + +using Mantid::VATES::FieldDataToMetadata; + +class FieldDataToMetadataTest : public CxxTest::TestSuite +{ + +private: + + //Helper method + static vtkFieldData* createFieldDataWithCharArray(std::string testData, std::string id) + { + vtkFieldData* fieldData = vtkFieldData::New(); + vtkCharArray* charArray = vtkCharArray::New(); + charArray->SetName(id.c_str()); + charArray->Allocate(100); + for(unsigned int i = 0; i < testData.size(); i++) + { + char cNextVal = testData.at(i); + if(int(cNextVal) > 1) + { + charArray->InsertNextValue(cNextVal); + + } + } + fieldData->AddArray(charArray); + charArray->Delete(); + return fieldData; + } + +public: + + void testExecute() + { + const std::string id = "1"; + const std::string testData = "abc"; + vtkFieldData* fieldData = createFieldDataWithCharArray(testData, id); + + FieldDataToMetadata function; + std::string metadata = function.execute(fieldData, id); + + TSM_ASSERT_EQUALS("The Function failed to properly convert field data to metadata", testData, metadata); + fieldData->Delete(); + } + + void testOperatorOverload() + { + const std::string id = "1"; + const std::string testData = "abc"; + vtkFieldData* fieldData = createFieldDataWithCharArray(testData, id); + + typedef std::binary_function<vtkFieldData*, std::string, std::string> BaseType; + FieldDataToMetadata function; + TSM_ASSERT_EQUALS("Results from two equivalent methods differ.", function(fieldData, id), function.execute(fieldData, id)); + fieldData->Delete(); + } + + void testThrowsIfNotFound() + { + const std::string id = "1"; + const std::string testData = "abc"; + vtkFieldData* fieldData = createFieldDataWithCharArray(testData, id); + + FieldDataToMetadata function; + TSM_ASSERT_THROWS("Unknown id requested. Should have thrown.", function.execute(fieldData, "x"), std::runtime_error ); + fieldData->Delete(); + } + + +}; + + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/MetadataToFieldDataTest.h b/Code/Mantid/Vates/VatesAPI/test/MetadataToFieldDataTest.h new file mode 100644 index 0000000000000000000000000000000000000000..fd341a44da092b99b7de2eabffd75b57d037d101 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/MetadataToFieldDataTest.h @@ -0,0 +1,73 @@ +#ifndef METADATATOFIELDDATATEST_H_ +#define METADATATOFIELDDATATEST_H_ + +#include <cxxtest/TestSuite.h> +#include <vtkCharArray.h> +#include <vtkFieldData.h> +#include "MantidVatesAPI/MetadataToFieldData.h" +#include "boost/algorithm/string.hpp" + +using Mantid::VATES::MetadataToFieldData; + +class MetadataToFieldDataTest: public CxxTest::TestSuite +{ +private: + + //helper method + static std::string convertCharArrayToString(vtkCharArray* carry) + { + std::string sResult; + for (int i = 0; i < carry->GetSize(); i++) + { + char c = carry->GetValue(i); + if (int(c) > 1) + { + sResult.push_back(c); + } + } + boost::trim(sResult); + return sResult; + } + +public: + + void testMetaDataToFieldData() + { + std::string testData = "<test data/>%s"; + const std::string id = "1"; + + vtkFieldData* fieldData = vtkFieldData::New(); + vtkCharArray* charArray = vtkCharArray::New(); + charArray->SetName(id.c_str()); + fieldData->AddArray(charArray); + + MetadataToFieldData function; + function(fieldData, testData, id); + + //convert vtkchararray back into a string. + vtkCharArray* carry = dynamic_cast<vtkCharArray*> (fieldData->GetArray(id.c_str())); + + TSM_ASSERT_EQUALS("The result does not match the input. Metadata not properly converted.", testData, convertCharArrayToString(carry)); + charArray->Delete(); + fieldData->Delete(); + } + + void testMetaDataToFieldDataWithEmptyFieldData() + { + std::string testData = "<test data/>%s"; + const std::string id = "1"; + + vtkFieldData* emptyFieldData = vtkFieldData::New(); + MetadataToFieldData function; + function(emptyFieldData, testData.c_str(), id.c_str()); + + //convert vtkchararray back into a string. + vtkCharArray* carry = dynamic_cast<vtkCharArray*> (emptyFieldData->GetArray(id.c_str())); + + TSM_ASSERT_EQUALS("The result does not match the input. Metadata not properly converted.", testData, convertCharArrayToString(carry)); + emptyFieldData->Delete(); + } + +}; + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/MultiDimensionalDbPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/MultiDimensionalDbPresenterTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1fbe8da8318c4a16bd793013a39be01756553948 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/MultiDimensionalDbPresenterTest.h @@ -0,0 +1,103 @@ +#ifndef MULTIDIMENSIONAL_DB_PRESENTER_TEST_H_ +#define MULTIDIMENSIONAL_DB_PRESENTER_TEST_H_ + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> +#include <vtkPointData.h> +#include "MantidVatesAPI/MultiDimensionalDbPresenter.h" + +using namespace Mantid::VATES; + +class MultiDimensionalDbPresenterTest : public CxxTest::TestSuite +{ + +private: + + static std::string getTestFileName(){return "fe_demo_30.sqw";} + +public: + +//Simple schenario testing end-to-end working of this presenter. +void testConstruction() +{ + MultiDimensionalDbPresenter mdPresenter; + mdPresenter.execute(getTestFileName()); + + vtkDataArray* data = mdPresenter.getScalarDataFromTimeBin(1, "signal"); + vtkDataSet* visData = mdPresenter.getMesh(); + TSM_ASSERT_EQUALS("Incorrect number of scalar signal points.", 125000, data->GetSize()); + TSM_ASSERT_EQUALS("Incorrect number of visualisation vtkPoints generated", 132651, visData->GetNumberOfPoints()); + TSM_ASSERT_EQUALS("Incorrect number of timesteps returned", 30, mdPresenter.getNumberOfTimesteps()); + data->Delete(); + visData->Delete(); +} + +void testGetCycles() +{ + MultiDimensionalDbPresenter mdPresenter; + mdPresenter.execute(getTestFileName()); + std::vector<int> vecCycles = mdPresenter.getCycles(); + TSM_ASSERT_EQUALS("Wrong number of cycles in cycles collection.", vecCycles.size(), mdPresenter.getNumberOfTimesteps()); +} + +void testGetTimesteps() +{ + MultiDimensionalDbPresenter mdPresenter; + mdPresenter.execute(getTestFileName()); + std::vector<double> vecTimes = mdPresenter.getTimesteps(); + TSM_ASSERT_EQUALS("Wrong number of times in times collection.", vecTimes.size(), mdPresenter.getNumberOfTimesteps()); +} + +void testGetScalarDataThrows() +{ + MultiDimensionalDbPresenter mdPresenter; + + //No execution call. Test that type cannot be used improperly. + + TSM_ASSERT_THROWS("Accessing scalar data without first calling execute should not be possible", mdPresenter.getScalarDataFromTimeBin(1, "signal"), std::runtime_error); +} + +void testGetMeshThrows() +{ + MultiDimensionalDbPresenter mdPresenter; + + //No execution call. Test that type cannot be used improperly. + + TSM_ASSERT_THROWS("Accessing mesh data without first calling execute should not be possible", mdPresenter.getMesh(), std::runtime_error); +} + +void testGetNumberOfTimestepsThrows() +{ + MultiDimensionalDbPresenter mdPresenter; + + //No execution call. Test that type cannot be used improperly. + + TSM_ASSERT_THROWS("Accessing timestep number data without first calling execute should not be possible", mdPresenter.getNumberOfTimesteps(), std::runtime_error); +} + +void testGetCylesThrows() +{ + MultiDimensionalDbPresenter mdPresenter; + + //No execution call. Test that type cannot be used improperly. + + TSM_ASSERT_THROWS("Accessing cycles data without first calling execute should not be possible", mdPresenter.getCycles(), std::runtime_error); + +} + +void testGetTimestepsThrows() +{ + + MultiDimensionalDbPresenter mdPresenter; + + //No execution call. Test that type cannot be used improperly. + + TSM_ASSERT_THROWS("Accessing timestep data without first calling execute should not be possible", mdPresenter.getTimesteps(), std::runtime_error); + +} + + +}; + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/RebinningCutterTest.h b/Code/Mantid/Vates/VatesAPI/test/RebinningCutterTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0567351f23b27e8fa5dbeafe0ece553366c1aa --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/RebinningCutterTest.h @@ -0,0 +1,434 @@ +#ifndef REBINNING_CUTTER_TEST_H_ +#define REBINNING_CUTTER_TEST_H_ + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> +#include <boost/shared_ptr.hpp> +#include <cmath> +#include <typeinfo> + +#include "MantidGeometry/MDGeometry/MDDimensionRes.h" +#include "MantidMDAlgorithms/CompositeImplicitFunction.h" +#include "MantidMDAlgorithms/BoxImplicitFunction.h" +#include "MantidAPI/Point3D.h" +#include <vtkFieldData.h> +#include <vtkCharArray.h> +#include <vtkDataSet.h> +#include "MantidVatesAPI/RebinningCutterPresenter.h" +#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/vtkStructuredGridFactory.h" +#include <boost/algorithm/string.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/regex.hpp> + +using namespace Mantid::VATES; + +class RebinningCutterTest: public CxxTest::TestSuite +{ + +private: + + class MockProgressAction : public ProgressAction + { + virtual void eventRaised(int progressPercent) + { + //Do nothing. + } + }; + + class PsudoFilter + { + private: + + std::vector<double> m_origin; + + public: + PsudoFilter(std::vector<double> origin) : + m_origin(origin) + { + } + + vtkDataSet* Execute(vtkDataSet* in_ds) + { + using namespace Mantid::VATES; + using namespace Mantid::Geometry; + using namespace Mantid::MDAlgorithms; + using Mantid::VATES::DimensionVec; + using Mantid::VATES::Dimension_sptr; + using Mantid::MDDataObjects::MDImage; + using Mantid::MDDataObjects::MDWorkspace_sptr; + + RebinningCutterPresenter presenter; + + DimensionVec vec; + MDDimensionRes* pDimQx = new MDDimensionRes("qx", q1); //In reality these commands come from UI inputs. + pDimQx->setRange(-1.5, 5, 5); + Dimension_sptr dimX = Dimension_sptr(pDimQx); + + MDDimensionRes* pDimQy = new MDDimensionRes("qy", q2); //In reality these commands come from UI inputs. + pDimQy->setRange(-6.6, 6.6, 5); + Dimension_sptr dimY = Dimension_sptr(pDimQy); + + MDDimensionRes* pDimQz = new MDDimensionRes("qz", q3); //In reality these commands come from UI inputs. + pDimQz->setRange(-6.6, 6.6, 5); + Dimension_sptr dimZ = Dimension_sptr(pDimQz); + + MDDimension* pDimEn = new MDDimension("en"); + pDimEn->setRange(0, 150, 5); + Dimension_sptr dimT = Dimension_sptr(pDimEn); + + vec.push_back(dimX); + vec.push_back(dimY); + vec.push_back(dimZ); + vec.push_back(dimT); + + OriginParameter originParam = OriginParameter(m_origin.at(0), m_origin.at(1), m_origin.at(2)); + WidthParameter widthParam = WidthParameter(1); + HeightParameter heightParam = HeightParameter(2); + DepthParameter depthParam = DepthParameter(3); + + //Create the composite holder. + Mantid::MDAlgorithms::CompositeImplicitFunction* compFunction = new Mantid::MDAlgorithms::CompositeImplicitFunction; + + presenter.constructReductionKnowledge(vec, dimX, dimY, dimZ, dimT, compFunction, in_ds); + MockProgressAction action; + MDWorkspace_sptr spRebinnedWs = presenter.applyRebinningAction(RecalculateAll, action); + vtkDataSetFactory_sptr spDataSetFactory = vtkDataSetFactory_sptr(new vtkStructuredGridFactory<MDImage>(spRebinnedWs->get_spMDImage(), "", 1)); + vtkDataSet *ug = presenter.createVisualDataSet(spDataSetFactory); + + in_ds->Delete(); + return ug; + } + }; + +//helper method; +std::string getXMLInstructions() +{ + return std::string("<Function><Type>BoxImplicitFunction</Type><ParameterList><Parameter><Type>WidthParameter</Type><Value>1.0000</Value></Parameter><Parameter><Type>DepthParameter</Type><Value>3.0000</Value></Parameter><Parameter><Type>HeightParameter</Type><Value>2.0000</Value></Parameter><Parameter><Type>OriginParameter</Type><Value>2.0000, 3.0000, 4.0000</Value></Parameter></ParameterList></Function>"); +} + +//helper method +std::string getComplexXMLInstructions() +{ + return std::string("<?xml version=\"1.0\" encoding=\"utf-8\"?>") + +"<MDInstruction>" + + "<MDWorkspaceName>Input</MDWorkspaceName>" + + "<MDWorkspaceLocation>fe_demo_30.sqw</MDWorkspaceLocation>" + + "<DimensionSet>" + + "<Dimension ID=\"en\">" + + "<Name>Energy</Name>" + + "<UpperBounds>150</UpperBounds>" + + "<LowerBounds>0</LowerBounds>" + + "<NumberOfBins>5</NumberOfBins>" + + "</Dimension>" + + "<Dimension ID=\"qx\">" + + "<Name>Qx</Name>" + + "<UpperBounds>5</UpperBounds>" + + "<LowerBounds>-1.5</LowerBounds>" + + "<NumberOfBins>5</NumberOfBins>" + + "<ReciprocalDimensionMapping>q1</ReciprocalDimensionMapping>" + + "</Dimension>" + + "<Dimension ID=\"qy\">" + + "<Name>Qy</Name>" + + "<UpperBounds>6.6</UpperBounds>" + + "<LowerBounds>-6.6</LowerBounds>" + + "<NumberOfBins>5</NumberOfBins>" + + "<ReciprocalDimensionMapping>q2</ReciprocalDimensionMapping>" + + "</Dimension>" + + "<Dimension ID=\"qz\">" + + "<Name>Qz</Name>" + + "<UpperBounds>6.6</UpperBounds>" + + "<LowerBounds>-6.6</LowerBounds>" + + "<NumberOfBins>5</NumberOfBins>" + + "<ReciprocalDimensionMapping>q3</ReciprocalDimensionMapping>" + + "</Dimension>" + + "<XDimension>" + + "<RefDimensionId>qx</RefDimensionId>" + + "</XDimension>" + + "<YDimension>" + + "<RefDimensionId>qy</RefDimensionId>" + + "</YDimension>" + + "<ZDimension>" + + "<RefDimensionId>qz</RefDimensionId>" + + "</ZDimension>" + + "<TDimension>" + + "<RefDimensionId>en</RefDimensionId>" + + "</TDimension>" + + "</DimensionSet>" + + "<Function>" + + "<Type>CompositeImplicitFunction</Type>" + + "<ParameterList/>" + + "<Function>" + + "<Type>BoxImplicitFunction</Type>" + + "<ParameterList>" + + "<Parameter>" + + "<Type>HeightParameter</Type>" + + "<Value>6</Value>" + + "</Parameter>" + + "<Parameter>" + + "<Type>WidthParameter</Type>" + + "<Value>1.5</Value>" + + "</Parameter>" + + "<Parameter>" + + "<Type>DepthParameter</Type>" + + "<Value>6</Value>" + + "</Parameter>" + + "<Parameter>" + + "<Type>OriginParameter</Type>" + + "<Value>0, 0, 0</Value>" + + "</Parameter>" + + "</ParameterList>" + + "</Function>" + + "<Function>" + + "<Type>CompositeImplicitFunction</Type>" + + "<ParameterList/>" + + "<Function>" + + "<Type>BoxImplicitFunction</Type>" + + "<ParameterList>" + + "<Parameter>" + + "<Type>WidthParameter</Type>" + + "<Value>4</Value>" + + "</Parameter>" + + "<Parameter>" + + "<Type>HeightParameter</Type>" + + "<Value>1.5</Value>" + + "</Parameter>" + + "<Parameter>" + + "<Type>DepthParameter</Type>" + + "<Value>6</Value>" + + "</Parameter>" + + "<Parameter>" + + "<Type>OriginParameter</Type>" + + "<Value>0, 0, 0</Value>" + + "</Parameter>" + + "</ParameterList>" + + "</Function>" + + "</Function>" + + "</Function>" + +"</MDInstruction>"; + } + +//helper method +std::string convertCharArrayToString(vtkCharArray* carry) +{ + std::string sResult; + for (int i = 0; i < carry->GetSize(); i++) + { + char c = carry->GetValue(i); + if(int(c) > 1) + { + sResult.push_back(c); + } + } + boost::trim(sResult); + return sResult; +} + +//helper method +vtkFieldData* createFieldDataWithCharArray(std::string testData, std::string id) +{ + vtkFieldData* fieldData = vtkFieldData::New(); + vtkCharArray* charArray = vtkCharArray::New(); + charArray->SetName(id.c_str()); + charArray->Allocate(100); + for(unsigned int i = 0; i < testData.size(); i++) + { + char cNextVal = testData.at(i); + if(int(cNextVal) > 1) + { + charArray->InsertNextValue(cNextVal); + + } + } + fieldData->AddArray(charArray); + charArray->Delete(); + return fieldData; +} + +//Helper method to construct a dataset identical to what would be expected as the input to a RebinningCutterFilter without the any geometric/topological data. +vtkDataSet* constructInputDataSet() +{ + + vtkDataSet* dataset = vtkUnstructuredGrid::New(); + std::string id = XMLDefinitions::metaDataId(); + vtkFieldData* fieldData =createFieldDataWithCharArray(getComplexXMLInstructions(), id); + dataset->SetFieldData(fieldData); + fieldData->Delete(); + return dataset; +} + +public: + +//Simple schenario testing end-to-end working of this presenter. +void testExecution() +{ + //Create an input dataset with the field data. + vtkDataSet* in_ds = constructInputDataSet(); + + PsudoFilter filter(std::vector<double>(3,0)); + + vtkDataSet* out_ds = filter.Execute(in_ds); + + //NB 125 = 5 * 5 * 5 see pseudo filter execution method's number of bins above. + TSM_ASSERT_EQUALS("An empty visualisation data set has been generated.", out_ds->GetNumberOfPoints() , 216); + + out_ds->Delete(); + +} + +//A more complex version of the above testExecution. Uses filter chaining as would occur in real pipeline. +void testExecutionInChainedSchenario() +{ + //Create an input dataset with the field data. + vtkDataSet* in_ds = constructInputDataSet(); + + PsudoFilter a(std::vector<double>(3,0)); + PsudoFilter b(std::vector<double>(3,0)); + PsudoFilter c(std::vector<double>(3,0)); + + vtkDataSet* out_ds = c.Execute(b.Execute(a.Execute(in_ds))); + out_ds->Delete(); +} + +void testgetMetaDataID() +{ + + TSM_ASSERT_EQUALS("The expected id for the slicing metadata was not found", "VATES_Metadata", XMLDefinitions::metaDataId()); +} + +void testFindExistingRebinningDefinitions() +{ + using namespace Mantid::API; + using namespace Mantid::MDAlgorithms; + std::string id = XMLDefinitions::metaDataId(); + vtkDataSet* dataset = constructInputDataSet(); + + ImplicitFunction* func = findExistingRebinningDefinitions(dataset, id.c_str()); + + TSM_ASSERT("There was a previous definition of a function that should have been recognised and generated." + , CompositeImplicitFunction::functionName() == func->getName()); + + dataset->Delete(); + delete func; +} + + +void testNoExistingRebinningDefinitions() +{ + using namespace Mantid::API; + + vtkDataSet* dataset = vtkUnstructuredGrid::New(); + TSM_ASSERT_THROWS("There were no previous definitions carried through. Should have thrown.", findExistingRebinningDefinitions(dataset, XMLDefinitions::metaDataId().c_str()), std::runtime_error); + dataset->Delete(); +} + +// +//void testCreateVisualDataSetThrows() +//{ +// using namespace Mantid::API; +// using namespace Mantid::MDAlgorithms; +// +// Mantid::VATES::RebinningCutterPresenter presenter; +// +// TSM_ASSERT_THROWS("Should have thrown if constructReductionKnowledge not called first.", presenter.createVisualDataSet("", false,1), std::runtime_error); +//} + +void testFindWorkspaceName() +{ + std::string id = XMLDefinitions::metaDataId(); + vtkDataSet* dataset = constructInputDataSet(); + + std::string name = findExistingWorkspaceName(dataset, id.c_str()); + + TSM_ASSERT_EQUALS("The workspace name is different from the xml value.", "Input", name ); + dataset->Delete(); +} + +void testFindWorkspaceLocation() +{ + std::string id = XMLDefinitions::metaDataId(); + vtkDataSet* dataset = constructInputDataSet(); + + std::string location = findExistingWorkspaceLocation(dataset, id.c_str()); + static const boost::regex match(".*(fe_demo_30.sqw)$"); + + TSM_ASSERT("The workspace location is differrent from the xml value.", regex_match(location, match)); + dataset->Delete(); +} + +void testFindWorkspaceNameThrows() +{ + vtkDataSet* dataset = vtkUnstructuredGrid::New(); + std::string id = XMLDefinitions::metaDataId(); + dataset->SetFieldData(createFieldDataWithCharArray("<IncorrectXML></IncorrectXML>", id.c_str())); + + TSM_ASSERT_THROWS("The xml does not contain a name element, so should throw.", findExistingWorkspaceName(dataset, id.c_str()), std::runtime_error); + dataset->Delete(); +} + +void testFindWorkspaceLocationThrows() +{ + vtkDataSet* dataset = vtkUnstructuredGrid::New(); + std::string id = XMLDefinitions::metaDataId(); + dataset->SetFieldData(createFieldDataWithCharArray("<IncorrectXML></IncorrectXML>", id.c_str())); + + TSM_ASSERT_THROWS("The xml does not contain a location element, so should throw.", findExistingWorkspaceLocation(dataset, id.c_str()), std::runtime_error); + dataset->Delete(); +} + +void testGetXDimension() +{ + Mantid::VATES::RebinningCutterPresenter presenter; + vtkDataSet* dataSet = constructInputDataSet(); //Creates a vtkDataSet with fielddata containing geomtry xml. + Mantid::VATES::Dimension_sptr xDimension = presenter.getXDimensionFromDS(dataSet); + TSM_ASSERT_EQUALS("Wrong number of x dimension bins", 5, xDimension->getNBins()); + TSM_ASSERT_EQUALS("Wrong minimum x obtained", 5, xDimension->getMaximum()); + TSM_ASSERT_EQUALS("Wrong maximum x obtained", -1.5, xDimension->getMinimum()); + dataSet->Delete(); +} + +void testGetYDimension() +{ + Mantid::VATES::RebinningCutterPresenter presenter; + vtkDataSet* dataSet = constructInputDataSet(); //Creates a vtkDataSet with fielddata containing geomtry xml. + Mantid::VATES::Dimension_sptr yDimension = presenter.getYDimensionFromDS(dataSet); + TSM_ASSERT_EQUALS("Wrong number of y dimension bins", 5, yDimension->getNBins()); + TSM_ASSERT_EQUALS("Wrong minimum y obtained", 6.6, yDimension->getMaximum()); + TSM_ASSERT_EQUALS("Wrong maximum y obtained", -6.6, yDimension->getMinimum()); + dataSet->Delete(); +} + +void testGetZDimension() +{ + Mantid::VATES::RebinningCutterPresenter presenter; + vtkDataSet* dataSet = constructInputDataSet(); //Creates a vtkDataSet with fielddata containing geomtry xml. + Mantid::VATES::Dimension_sptr zDimension = presenter.getZDimensionFromDS(dataSet); + TSM_ASSERT_EQUALS("Wrong number of z dimension bins", 5, zDimension->getNBins()); + TSM_ASSERT_EQUALS("Wrong minimum z obtained", -6.6, zDimension->getMinimum()); + TSM_ASSERT_EQUALS("Wrong maximum z obtained", 6.6, zDimension->getMaximum()); + dataSet->Delete(); +} + +void testGettDimension() +{ + Mantid::VATES::RebinningCutterPresenter presenter; + vtkDataSet* dataSet = constructInputDataSet(); //Creates a vtkDataSet with fielddata containing geomtry xml. + Mantid::VATES::Dimension_sptr tDimension = presenter.getTDimensionFromDS(dataSet); + TSM_ASSERT_EQUALS("Wrong number of z dimension bins", 5, tDimension->getNBins()); + TSM_ASSERT_EQUALS("Wrong minimum t obtained", 0, tDimension->getMinimum()); + TSM_ASSERT_EQUALS("Wrong maximum t obtained", 150, tDimension->getMaximum()); + dataSet->Delete(); +} + +void testGetWorkspaceGeometryThrows() +{ + Mantid::VATES::RebinningCutterPresenter presenter; + TSM_ASSERT_THROWS("Not properly initalized. Getting workspace geometry should throw.", presenter.getWorkspaceGeometry(), std::runtime_error); +} + + +}; + + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/RebinningXMLGeneratorTest.h b/Code/Mantid/Vates/VatesAPI/test/RebinningXMLGeneratorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..03c2b047e5374a5c932c45278ce2d24eaefb118a --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/RebinningXMLGeneratorTest.h @@ -0,0 +1,231 @@ +#ifndef REBINNING_XML_GENERATOR_TEST_H +#define REBINNING_XML_GENERATOR_TEST_H + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> +#include <MantidGeometry/MDGeometry/MDPoint.h> +#include <MantidGeometry/MDGeometry/IMDDimension.h> +#include "MantidVatesAPI/RebinningXMLGenerator.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidAPI/ImplicitFunction.h" +#include "boost/shared_ptr.hpp" + +using namespace Mantid::VATES; + +class RebinningXMLGeneratorTest: public CxxTest::TestSuite +{ +private: + + //Helper class + class MockImplicitFunction: public Mantid::API::ImplicitFunction + { + public: + MOCK_CONST_METHOD1(evaluate, bool(const Mantid::API::Point3D* pPoint)); + MOCK_CONST_METHOD0(getName, std::string()); + MOCK_CONST_METHOD0(toXMLString, std::string()); + ~MockImplicitFunction() + { + } + }; + + //Helper class. Not all methods can be mocked. + + class MockIMDWorkspace: public Mantid::API::IMDWorkspace + { + public: + + MOCK_CONST_METHOD0(id, const std::string()); + MOCK_CONST_METHOD0(getMemorySize, size_t()); + MOCK_CONST_METHOD1(getPoint,const Mantid::Geometry::SignalAggregate&(unsigned int index)); + MOCK_CONST_METHOD1(getCell,const Mantid::Geometry::SignalAggregate&(unsigned int dim1Increment)); + MOCK_CONST_METHOD2(getCell,const Mantid::Geometry::SignalAggregate&(unsigned int dim1Increment, unsigned int dim2Increment)); + MOCK_CONST_METHOD3(getCell,const Mantid::Geometry::SignalAggregate&(unsigned int dim1Increment, unsigned int dim2Increment, unsigned int dim3Increment)); + MOCK_CONST_METHOD4(getCell,const Mantid::Geometry::SignalAggregate&(unsigned int dim1Increment, unsigned int dim2Increment, unsigned int dim3Increment, unsigned int dim4Increment)); + + MOCK_CONST_METHOD0(getWSLocation,std::string()); + MOCK_CONST_METHOD0(getGeometryXML,std::string()); + + boost::shared_ptr<const Mantid::Geometry::IMDDimension> getXDimension() const + { + throw std::runtime_error("Not Implemented"); + } + boost::shared_ptr<const Mantid::Geometry::IMDDimension> getYDimension() const + { + throw std::runtime_error("Not Implemented"); + } + boost::shared_ptr<const Mantid::Geometry::IMDDimension> getZDimension() const + { + throw std::runtime_error("Not Implemented"); + } + boost::shared_ptr<const Mantid::Geometry::IMDDimension> gettDimension() const + { + throw std::runtime_error("Not Implemented"); + } + boost::shared_ptr<const Mantid::Geometry::IMDDimension> getDimension(std::string id) const + { + throw std::runtime_error("Not Implemented"); + } + const Mantid::Geometry::SignalAggregate& getCell(...) const + { + throw std::runtime_error("Not Implemented"); + } + virtual uint64_t getNPoints() const + { + throw std::runtime_error("Not Implemented"); + } + virtual int getNDimensions() const + { + throw std::runtime_error("Not Implemented"); + } + virtual const std::vector<std::string> getDimensionIDs() const + { + throw std::runtime_error("Not Implemented"); + } + + //constructor allows a workspace name to be provide. + MockIMDWorkspace(std::string name) + { + setName(name); + } + + MockIMDWorkspace() + { + } +}; + +//Test methods + +public: + +void testNoWorkspaceThrows() +{ + RebinningXMLGenerator generator; + boost::shared_ptr<const Mantid::API::ImplicitFunction> impFunction(new MockImplicitFunction); + generator.setImplicitFunction(impFunction); + TSM_ASSERT_THROWS("Cannot generate the xml without the workspace", generator.createXMLString(), std::runtime_error); +} + +void testNoImplicitFunctionThrows() +{ + RebinningXMLGenerator generator; + MockIMDWorkspace* pWorkspace = new MockIMDWorkspace; + EXPECT_CALL(*pWorkspace, getGeometryXML()).Times(1); + EXPECT_CALL(*pWorkspace, getWSLocation()).Times(1); + boost::shared_ptr<const Mantid::API::IMDWorkspace> workspace(pWorkspace); + generator.setWorkspace(workspace); + TSM_ASSERT_THROWS("Cannot generate the xml without the implicitFunction", generator.createXMLString(), std::runtime_error); +} + +void testNoGeometryXMLThrows() +{ + boost::shared_ptr<const Mantid::API::ImplicitFunction> impFunction(new MockImplicitFunction); + MockIMDWorkspace* pWorkspace = new MockIMDWorkspace; + EXPECT_CALL(*pWorkspace, getGeometryXML()).Times(1).WillRepeatedly(testing::Return("")); + EXPECT_CALL(*pWorkspace, getWSLocation()).Times(1).WillRepeatedly(testing::Return("../somelocation/somefile.sqw")); + boost::shared_ptr<const Mantid::API::IMDWorkspace> workspace(pWorkspace); + RebinningXMLGenerator generator; + generator.setImplicitFunction(impFunction); + generator.setWorkspace(workspace); + + TSM_ASSERT_THROWS("Cannot create the xml without geometry xml", generator.createXMLString(), std::runtime_error); +} + +void testNoLocationThrows() +{ + boost::shared_ptr<const Mantid::API::ImplicitFunction> impFunction(new MockImplicitFunction); + MockIMDWorkspace* pWorkspace = new MockIMDWorkspace; + EXPECT_CALL(*pWorkspace, getGeometryXML()).Times(1).WillRepeatedly(testing::Return("<DimensionSet/>")); + EXPECT_CALL(*pWorkspace, getWSLocation()).Times(1).WillRepeatedly(testing::Return("")); + boost::shared_ptr<const Mantid::API::IMDWorkspace> workspace(pWorkspace); + RebinningXMLGenerator generator; + generator.setImplicitFunction(impFunction); + generator.setWorkspace(workspace); + + TSM_ASSERT_THROWS("Cannot create the xml without the workspace location", generator.createXMLString(), + std::runtime_error); +} + +void testNoNameThrows() +{ + boost::shared_ptr<const Mantid::API::ImplicitFunction> impFunction(new MockImplicitFunction); + MockIMDWorkspace* pWorkspace = new MockIMDWorkspace; + EXPECT_CALL(*pWorkspace, getGeometryXML()).Times(1).WillRepeatedly(testing::Return("<DimensionSet/>")); + EXPECT_CALL(*pWorkspace, getWSLocation()).Times(1).WillRepeatedly(testing::Return("..../somelocation/somefile.sqw")); + boost::shared_ptr<const Mantid::API::IMDWorkspace> workspace(pWorkspace); + RebinningXMLGenerator generator; + generator.setImplicitFunction(impFunction); + generator.setWorkspace(workspace); + + TSM_ASSERT_THROWS("Cannot create the xml without the workspace name", generator.createXMLString(), + std::runtime_error); +} + +void testCreateXMLWithWorkspace() //Uses the workspace settter. +{ + MockImplicitFunction* pImpFunction = new MockImplicitFunction; + EXPECT_CALL(*pImpFunction, toXMLString()).Times(1).WillRepeatedly(testing::Return("<ImplicitFunction/>")); + + MockIMDWorkspace* pWorkspace = new MockIMDWorkspace("name"); + EXPECT_CALL(*pWorkspace, getGeometryXML()).Times(1).WillRepeatedly(testing::Return("<DimensionSet/>")); + EXPECT_CALL(*pWorkspace, getWSLocation()).Times(1).WillRepeatedly(testing::Return("location")); + + boost::shared_ptr<const Mantid::API::IMDWorkspace> workspace(pWorkspace); + boost::shared_ptr<const Mantid::API::ImplicitFunction> impFunction(pImpFunction); + RebinningXMLGenerator generator; + + //Apply setters. + generator.setImplicitFunction(impFunction); + generator.setWorkspace(workspace); + + std::string xml = generator.createXMLString(); + + TSM_ASSERT_EQUALS("The xml has been created, but is incorrect.", "<MDInstruction><MDWorkspaceName>name</MDWorkspaceName><MDWorkspaceLocation>location</MDWorkspaceLocation><DimensionSet/><ImplicitFunction/></MDInstruction>" ,xml) +} + +void testCreateXMLWithComponents() //Uses individual setters for geometry, location and name. +{ + MockImplicitFunction* pImpFunction = new MockImplicitFunction; + EXPECT_CALL(*pImpFunction, toXMLString()).Times(1).WillRepeatedly(testing::Return("<ImplicitFunction/>")); + boost::shared_ptr<const Mantid::API::ImplicitFunction> impFunction(pImpFunction); + + RebinningXMLGenerator generator; + //Apply setters. + generator.setImplicitFunction(impFunction); + generator.setWorkspaceName("name"); + generator.setWorkspaceLocation("location"); + generator.setGeometryXML("<DimensionSet/>"); + + std::string xml = generator.createXMLString(); + + TSM_ASSERT_EQUALS("The xml has been created, but is incorrect.", "<MDInstruction><MDWorkspaceName>name</MDWorkspaceName><MDWorkspaceLocation>location</MDWorkspaceLocation><DimensionSet/><ImplicitFunction/></MDInstruction>" ,xml) +} + +void testCreateXMLWithoutFunction() +{ + RebinningXMLGenerator generator; + //Apply setters. + generator.setWorkspaceName("name"); + generator.setWorkspaceLocation("location"); + generator.setGeometryXML("<DimensionSet/>"); + + std::string xml = generator.createXMLString(); + TSM_ASSERT_EQUALS("The xml has been created without a function incorrectly", "<MDInstruction><MDWorkspaceName>name</MDWorkspaceName><MDWorkspaceLocation>location</MDWorkspaceLocation><DimensionSet/></MDInstruction>", xml); +} + +void testGetGeometryXML() +{ + RebinningXMLGenerator generator; + generator.setWorkspaceName("name"); + generator.setWorkspaceLocation("location"); + std::string dimensionXMLString = "<DimensionSet/>"; + generator.setGeometryXML(dimensionXMLString); + + std::string xml = generator.getWorkspaceGeometry(); + TSM_ASSERT_EQUALS("The geometry xml fetched is not the same as that provided", dimensionXMLString, generator.getWorkspaceGeometry()); +} + + +}; + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/runTests.sh b/Code/Mantid/Vates/VatesAPI/test/runTests.sh new file mode 100755 index 0000000000000000000000000000000000000000..abd7d3f6609280868d39228febe6475e159568a6 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/runTests.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Simple script to build and run the tests. +# Will run all tests in the directory if no arguments are supplied, +# or alternatively just the test files given as arguments. +# +# You will need to have the directories containing the Mantid +# .so libraries in your LD_LIBRARY_PATH environment variable +# +# Author: Owen Arnold 02/12/2010 +# + +# Clean up any old executable +rm -rf runner.* + +echo "Generating the source file from the test header files..." +# Chaining all tests together can have effects that you don't think of +# - it's always a good idea to run your new/changed test on its own +test_files="" +if [ $# -eq 0 ]; then + test_files=*.h +else + test_files=$* +fi + +cxxtestgen=../../../../Third_Party/src/cxxtest/cxxtestgen.py +python $cxxtestgen --runner=MantidPrinter -o runner.cpp $test_files + + +echo "Compiling the test executable..." + +#TODO set path properly +mantid_libpath=~/workspace/MantidDebug/bin +#TODO set path properly +vtk_libpath=/usr/local/2.1.1/linux-x86_64/lib +#TODO set path properly +gmock_libpath=../../../TestingTools/lib/ubuntu-10.10 + +g++ -O0 -g3 -DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG -o runner.exe runner.cpp -I../../../Framework/Kernel/inc -I../../../Framework/MDDataObjects/inc -I../../../Framework/MDAlgorithms/inc -I../../../Framework/API/inc -I../inc/VisitPlugins -I/usr/local/2.1.1/linux-x86_64/include/vtk/include/vtk-5.0 -I../../../Framework/Geometry/inc -I ../inc \ + -I ../../../../Third_Party/src/cxxtest -I ../../../../Third_Party/include -I ../../../TestingTools/include -L$vtk_libpath -L$mantid_libpath -L$gmock_libpath -lvtkCommon -lvtkFiltering -lMantidKernel -lMantidGeometry -lMantidAPI -lboost_date_time-mt -lgmock -lMantidMDAlgorithms -lMantidDataObjects -lMantidMDDataObjects -lMantidVisitPresenters -lhdf5 -Wno-deprecated + +echo + +echo "Running the tests..." +ln ../../../Framework/Build/Tests/*.properties . +LD_LIBRARY_PATH=$vtk_libpath:$mantid_libpath:$LD_LIBRARY_PATH ./runner.exe +#valgrind --leak-check=full --show-reachable=yes --track-origins=yes ~/mantid/Code/Vates/VisitPresenters/test/runner.exe +echo + +# Remove the generated files to ensure that they're not inadvertently run +# when something in the chain has failed. +echo "Cleaning up..." +rm -f *.properties +rm -f *Test.log +rm -f *.so +echo "Done." diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkClipperDataSetFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkClipperDataSetFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..568bc4703ea36ac6482313bc498362e6c0ae5d7d --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkClipperDataSetFactoryTest.h @@ -0,0 +1,128 @@ +#ifndef VTK_CLIPPER_DATASETFACTORY_TEST_H +#define VTK_CLIPPER_DATASETFACTORY_TEST_H + +#include <cxxtest/TestSuite.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include "MantidVatesAPI/vtkClipperDataSetFactory.h" +#include "MantidMDAlgorithms/CompositeImplicitFunction.h" +#include "MantidMDAlgorithms/BoxImplicitFunction.h" +#include "vtkRectilinearGrid.h" + +class vtkClipperDataSetFactoryTest: public CxxTest::TestSuite +{ +private: + +class MockClipper: public Mantid::VATES::Clipper + { + public: + MOCK_METHOD1(SetInput, void(vtkDataSet* in_ds)); + MOCK_METHOD1(SetClipFunction, void(vtkImplicitFunction* func)); + MOCK_METHOD1(SetInsideOut, void(bool insideout)); + MOCK_METHOD1(SetRemoveWholeCells, void(bool removeWholeCells)); + MOCK_METHOD1(SetOutput, void(vtkUnstructuredGrid* out_ds)); + MOCK_METHOD0(Update, void()); + MOCK_METHOD0(Delete,void()); + MOCK_METHOD0(die, void()); + virtual ~MockClipper() + { + die(); + } + }; + + class vtkMockRectilinearGrid: public vtkRectilinearGrid + { + public: + static vtkMockRectilinearGrid* New() + { + vtkMockRectilinearGrid* newProduct = new vtkMockRectilinearGrid(); + return newProduct; + } + MOCK_METHOD0(die, void()); + virtual void Delete() + { + die(); + vtkRectilinearGrid::Delete(); + } + + }; + + // Mock type to represent other implicit functions. + class MockImplicitFunction: public Mantid::API::ImplicitFunction + { + public: + MOCK_CONST_METHOD1(evaluate, bool(const Mantid::API::Point3D* pPoint3D)); + MOCK_CONST_METHOD0(getName, std::string()); + MOCK_CONST_METHOD0(toXMLString, std::string()); + MOCK_METHOD0(die, void()); + ~MockImplicitFunction() + { + die(); + } + }; + +public: + + void testCleansUp() + { + using Mantid::VATES::vtkClipperDataSetFactory; + using namespace Mantid::API; + + MockImplicitFunction* mockFunction = new MockImplicitFunction; + vtkMockRectilinearGrid* mockGrid = vtkMockRectilinearGrid::New(); + MockClipper* mockClipper = new MockClipper; + EXPECT_CALL(*mockFunction, die()).Times(1); + EXPECT_CALL(*mockGrid, die()).Times(0); //VisIT framework expects that input datasets are not destroyed. + EXPECT_CALL(*mockClipper, die()).Times(1); + { + vtkClipperDataSetFactory factory(boost::shared_ptr<ImplicitFunction>(mockFunction), mockGrid, mockClipper); + } + + mockGrid->Delete(); //Clean up in test scenario + + TSM_ASSERT("RAII not correct on accepted implicit function", testing::Mock::VerifyAndClearExpectations(mockFunction)); + TSM_ASSERT("RAII not correct on accepted vtkDataSet", testing::Mock::VerifyAndClearExpectations(mockGrid)); + TSM_ASSERT("RAII not correct on accepted vtkDataSet", testing::Mock::VerifyAndClearExpectations(mockClipper)); + } + + void testAppliesCuts() + { + using namespace Mantid::MDAlgorithms; + using namespace Mantid::API; + + OriginParameter originOne(0, 0, 0); + WidthParameter widthOne(1); + HeightParameter heightOne(4); + DepthParameter depthOne(5); + BoxImplicitFunction* boxOne = new BoxImplicitFunction(widthOne, heightOne, depthOne, originOne); + + OriginParameter originTwo(0, 0, 0); + WidthParameter widthTwo(2); + HeightParameter heightTwo(3); + DepthParameter depthTwo(6); + BoxImplicitFunction* boxTwo = new BoxImplicitFunction(widthTwo, heightTwo, depthTwo, originTwo); + + CompositeImplicitFunction* compositeFunction = new CompositeImplicitFunction; + compositeFunction->addFunction(boost::shared_ptr<ImplicitFunction>(boxOne)); + compositeFunction->addFunction(boost::shared_ptr<ImplicitFunction>(boxTwo)); + + + MockClipper* mockClipper = new MockClipper; + EXPECT_CALL(*mockClipper, SetInput(testing::_)).Times(2); + EXPECT_CALL(*mockClipper, SetClipFunction(testing::_)).Times(2); + EXPECT_CALL(*mockClipper, SetInsideOut(true)).Times(2); + EXPECT_CALL(*mockClipper, SetRemoveWholeCells(true)).Times(2); + EXPECT_CALL(*mockClipper, SetOutput(testing::_)).Times(2); + EXPECT_CALL(*mockClipper, Update()).Times(2); + EXPECT_CALL(*mockClipper, die()).Times(1); + + { + Mantid::VATES::vtkClipperDataSetFactory factory(boost::shared_ptr<ImplicitFunction>(compositeFunction), vtkRectilinearGrid::New(), mockClipper); + factory.create(); + } + + + TSM_ASSERT("Clipper not used correctly.", testing::Mock::VerifyAndClearExpectations(mockClipper)); + } +}; +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..b6c6e69d19277460d397d41b3a9b2b4ba6f8f055 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetFactoryTest.h @@ -0,0 +1,96 @@ + +#ifndef VTKDATASETFACTORYTEST_H_ +#define VTKDATASETFACTORYTEST_H_ + +#include "MantidMDAlgorithms/Load_MDWorkspace.h" +#include "MDDataObjects/MDWorkspace.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> + + +class vtkDataSetFactoryTest +{ + +protected: + + /// Geometry Policy utilises compile-time polymorphism in vtkDataSetFactories + /// for testing purposes. Otherwise too unwieldy to generate MDGeometry from scratch. + class GeometryPolicy + { + public: + + GeometryPolicy(int i, int j, int k, int t) : m_i(i), m_j(j), m_k(k), m_t(t) + { + } + + boost::shared_ptr<Mantid::Geometry::IMDDimension> getXDimension() const + { + using namespace Mantid::Geometry; + MDDimension* dimension = new MDDimension("qx"); + dimension->setRange(0, 1, m_i); + return boost::shared_ptr<IMDDimension>(dimension); + } + boost::shared_ptr<Mantid::Geometry::IMDDimension> getYDimension() const + { + using namespace Mantid::Geometry; + MDDimension* dimension = new MDDimension("qy"); + dimension->setRange(0, 1, m_j); + return boost::shared_ptr<IMDDimension>(dimension); + } + boost::shared_ptr<Mantid::Geometry::IMDDimension> getZDimension() const + { + using namespace Mantid::Geometry; + MDDimension* dimension = new MDDimension("qz"); + dimension->setRange(0, 1, m_k); + return boost::shared_ptr<IMDDimension>(dimension); + } + boost::shared_ptr<Mantid::Geometry::IMDDimension> getTDimension() const + { + using namespace Mantid::Geometry; + MDDimension* dimension = new MDDimension("t"); + dimension->setRange(0, 1, m_t); + return boost::shared_ptr<IMDDimension>(dimension); + } + + private: + const int m_i; + const int m_j; + const int m_k; + const int m_t; + }; + + /// Image Policy utilises compile-time polymorphism in vtkDataSetFactories + /// for testing purposes. Otherwise too unwieldy to generate MDImage from scratch. + class ImagePolicy + { + + + public: + /// Embedded type information + typedef GeometryPolicy GeometryType; + /// Get the Geometry + + ImagePolicy(int i, int j, int k, int t): m_geometry(i, j, k, t) + { + } + + GeometryType* getGeometry() + { + return &m_geometry; + } + + /// Get the MDImagePoint + Mantid::MDDataObjects::MD_image_point getPoint(int i, int j, int k, int t) const + { + Mantid::MDDataObjects::MD_image_point point; + point.s = i; + return point; + } + + private: + GeometryPolicy m_geometry; + }; + +} + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkProxyFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkProxyFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..874f0e86a9e8ed37b0011b7851d759b46b952095 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkProxyFactoryTest.h @@ -0,0 +1,61 @@ +#ifndef VTK_PROXY_FACTORY_TEST_H_ +#define VTK_PROXY_FACTORY_TEST_H_ + +#include <cxxtest/TestSuite.h> +#include <vtkRectilinearGrid.h> +#include "MantidVatesAPI/vtkProxyFactory.h" + +class vtkProxyFactoryTest: public CxxTest::TestSuite +{ +public: + + void testCreation() + { + using Mantid::VATES::vtkProxyFactory; + + vtkRectilinearGrid* A = vtkRectilinearGrid::New(); + vtkProxyFactory factory(A); + vtkDataSet* B = factory.create(); + + TSM_ASSERT_EQUALS("The construction parameter and product should both be of the same type", A->GetClassName(), B->GetClassName()); + TSM_ASSERT_EQUALS("The construction parameter and product should point to the same memory location", A, B); + B->Delete(); + } + + void testCopy() + { + using Mantid::VATES::vtkProxyFactory; + + vtkRectilinearGrid* inputProduct = vtkRectilinearGrid::New(); + vtkProxyFactory factoryA(inputProduct); + vtkProxyFactory copyFactory(factoryA); + vtkDataSet* productA = factoryA.create(); + vtkDataSet* productB = copyFactory.create(); + + TSM_ASSERT_EQUALS("The vtkDataSet from the original factory and copy should point to the same memory location", productA, productB); + productA->Delete(); + } + + void testAssignment() + { + using Mantid::VATES::vtkProxyFactory; + + vtkRectilinearGrid* inputProductA = vtkRectilinearGrid::New(); + vtkRectilinearGrid* inputProductB = vtkRectilinearGrid::New(); + vtkProxyFactory factoryA(inputProductA); + vtkProxyFactory factoryB(inputProductB); + + factoryA = factoryB; + vtkDataSet* productA = factoryA.create(); + vtkDataSet* productB = factoryB.create(); + + TSM_ASSERT_EQUALS("The vtkDataSet from the original factory and copy should point to the same memory location", productA, productB); + TSM_ASSERT_EQUALS("The vtkDataSet produced by both factories should correspond to the rhs factories constructor argument", productA, inputProductB); + + inputProductA->Delete(); + inputProductB->Delete(); + } + +}; + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkRectilinearGridFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkRectilinearGridFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..47b6adf3d6b54ed2b852dd9c6831a6b9c8570119 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkRectilinearGridFactoryTest.h @@ -0,0 +1,87 @@ +#ifndef VTK_RECTILINEAR_GRID_FACTORY_TEST_H_ +#define VTK_RECTILINEAR_GRID_FACTORY_TEST_H_ + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> +#include "vtkDataSetFactoryTest.h" +#include "MantidVatesAPI/vtkRectilinearGridFactory.h" + + +using namespace Mantid::VATES; +using namespace Mantid::MDDataObjects; + +class vtkRectilinearGridFactoryTest: public CxxTest::TestSuite, public vtkDataSetFactoryTest +{ +private: + + // Common helper method to generate a simple product mesh. + static vtkRectilinearGrid* createProduct(const int nbins) + { + //Easy to construct image policy for testing. + boost::shared_ptr<ImagePolicy> spImage(new ImagePolicy(nbins, nbins, nbins, nbins)); + std::string scalarName = "signal"; + const int timestep = 0; + + vtkRectilinearGridFactory<ImagePolicy> factory(spImage, scalarName, timestep); + return factory.create(); + } + + public: + + void testNumberOfPointsGenerated() + { + const int nbins = 10; + vtkRectilinearGrid* product = createProduct(nbins); + const int correctPointNumber = (nbins + 1) * (nbins + 1) * (nbins + 1); + TSM_ASSERT_EQUALS("The number of points in the product vtkRectilinearGrid is incorrect.", correctPointNumber, product->GetNumberOfPoints()); + product->Delete(); + } + + void testSignalDataType() + { + const int nbins = 10; + vtkRectilinearGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + TSM_ASSERT_EQUALS("The obtained signal array is not of the correct type.", std::string("vtkFloatArray"), signalData->GetClassName()); + product->Delete(); + } + + void testNumberOfArrays() + { + const int nbins = 10; + vtkRectilinearGrid* product = createProduct(nbins); + TSM_ASSERT_EQUALS("A single array should be present on the product dataset.", 1, product->GetCellData()->GetNumberOfArrays()); + product->Delete(); + } + + void testSignalDataName() + { + const int nbins = 10; + vtkRectilinearGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + TSM_ASSERT_EQUALS("The obtained cell data has the wrong name.", std::string("signal"), signalData->GetName()); + product->Delete(); + } + + void testSignalDataSize() + { + const int nbins = 10; + vtkRectilinearGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + const int correctCellNumber = (nbins) * (nbins) * (nbins); + TSM_ASSERT_EQUALS("The number of signal values generated is incorrect.", correctCellNumber, signalData->GetSize()); + product->Delete(); + } + +// void testIsVtkDataSetFactory() +// { +// const vtkDataSetFactory& factory = vtkRectilinearGridFactory<ImagePolicy>(boost::shared_ptr<ImagePolicy>(new ImagePolicy(1, 1, 1, 1)), "", 0); +// vtkDataSet* product = factory.create(); +// TSM_ASSERT("There is no point data in the polymorhic product.", product->GetNumberOfPoints() > 0); +// product->Delete(); +// } + +}; + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkStructuredGridFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkStructuredGridFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..240b3324fae4bb4d8fe2beea07305cd77c628b3b --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkStructuredGridFactoryTest.h @@ -0,0 +1,150 @@ +#ifndef VTK_STRUCTURED_GRID_FACTORY_TEST_H_ +#define VTK_STRUCTURED_GRID_FACTORY_TEST_H_ + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> +#include "vtkDataSetFactoryTest.h" +#include "MantidVatesAPI/vtkStructuredGridFactory.h" + + +class vtkStructuredGridFactoryTest: public CxxTest::TestSuite, public vtkDataSetFactoryTest +{ +public: + + // Common helper method to generate a simple product mesh. + static vtkStructuredGrid* createProduct(const int nbins) + { + using namespace Mantid::VATES; + //Easy to construct image policy for testing. + boost::shared_ptr<ImagePolicy> spImage(new ImagePolicy(nbins, nbins, nbins, nbins)); + std::string scalarName = "signal"; + const int timestep = 0; + + vtkStructuredGridFactory<ImagePolicy> factory(spImage, scalarName, timestep); + return factory.create(); + } + +public: + + void testCopy() + { + using namespace Mantid::VATES; + const int nbins = 10; + vtkStructuredGridFactory<ImagePolicy> factory(boost::shared_ptr<ImagePolicy>(new ImagePolicy(1, 1, 1, 1)), "", 0); + vtkStructuredGridFactory<ImagePolicy> factoryCopy(factory); + + vtkStructuredGrid* productA = factory.create(); + vtkStructuredGrid* productB = factoryCopy.create(); + + //Check that both products are equal. + TSM_ASSERT_EQUALS("Unequal number of points.", productA->GetNumberOfPoints(), productB->GetNumberOfPoints()); + TSM_ASSERT_EQUALS("Unequal number of cell arrays.", productA->GetCellData()->GetNumberOfArrays(), productB->GetCellData()->GetNumberOfArrays()); + productA->Delete(); + productB->Delete(); + } + + void testAssignment() + { + using namespace Mantid::VATES; + vtkStructuredGridFactory<ImagePolicy> factoryA(boost::shared_ptr<ImagePolicy>(new ImagePolicy(1, 1, 1, 1)), "", 0); + vtkStructuredGridFactory<ImagePolicy> factoryB(boost::shared_ptr<ImagePolicy>(new ImagePolicy(2, 2, 2, 2)), "", 0); + + vtkStructuredGrid* productA = factoryA.create(); + vtkStructuredGrid* productB = factoryB.create(); + + //Check that both products are NOT equal. + TSM_ASSERT_DIFFERS("Equal number of points.", productB->GetNumberOfPoints(), productA->GetNumberOfPoints()); + + //Perform assignment and create products. + factoryA = factoryB; + productA = factoryA.create(); + productB = factoryB.create(); + + //Check that both products are equal. + TSM_ASSERT_EQUALS("Unequal number of points.", productB->GetNumberOfPoints(), productA->GetNumberOfPoints()); + productA->Delete(); + productB->Delete(); + } + + void testMeshOnly() + { + using namespace Mantid::VATES; + vtkStructuredGridFactory<ImagePolicy> factory = + vtkStructuredGridFactory<ImagePolicy>::constructAsMeshOnly(boost::shared_ptr<ImagePolicy>(new ImagePolicy(1, 1, 1, 1))); + vtkStructuredGrid* product = factory.createMeshOnly(); + TSM_ASSERT_EQUALS("This is not a mesh-only product.", 0,product->GetCellData()->GetNumberOfArrays()); + product->Delete(); + } + + void testMeshOnlyCausesThrow() + { + using namespace Mantid::VATES; + vtkStructuredGridFactory<ImagePolicy> factory = + vtkStructuredGridFactory<ImagePolicy>::constructAsMeshOnly(boost::shared_ptr<ImagePolicy>( + new ImagePolicy(1, 1, 1, 1))); + TSM_ASSERT_THROWS("Created a mesh-only instance and then attempted to get non-mesh information. Should throw.", factory.createScalarArray(), std::runtime_error ); + } + + void testNumberOfPointsGenerated() + { + using namespace Mantid::VATES; + const int nbins = 10; + vtkStructuredGrid* product = createProduct(nbins); + const int correctPointNumber = (nbins + 1) * (nbins + 1) * (nbins + 1); + TSM_ASSERT_EQUALS("The number of points in the product vtkRectilinearGrid is incorrect.", correctPointNumber, product->GetNumberOfPoints()); + product->Delete(); + } + + void testSignalDataType() + { + using namespace Mantid::VATES; + const int nbins = 10; + vtkStructuredGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + TSM_ASSERT_EQUALS("The obtained signal array is not of the correct type.", std::string("vtkFloatArray"), signalData->GetClassName()); + product->Delete(); + } + + void testSignalDataName() + { + using namespace Mantid::VATES; + const int nbins = 10; + vtkStructuredGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + TSM_ASSERT_EQUALS("The obtained cell data has the wrong name.", std::string("signal"), signalData->GetName()); + product->Delete(); + } + + void testNumberOfArrays() + { + using namespace Mantid::VATES; + const int nbins = 10; + vtkStructuredGrid* product = createProduct(nbins); + TSM_ASSERT_EQUALS("A single array should be present on the product dataset.", 1, product->GetCellData()->GetNumberOfArrays()); + product->Delete(); + } + + void testSignalDataSize() + { + using namespace Mantid::VATES; + const int nbins = 10; + vtkStructuredGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + const int correctCellNumber = (nbins) * (nbins) * (nbins); + TSM_ASSERT_EQUALS("The number of signal values generated is incorrect.", correctCellNumber, signalData->GetSize()); + product->Delete(); + } + + void testIsVtkDataSetFactory() + { + using namespace Mantid::VATES; + const vtkDataSetFactory& factory = vtkStructuredGridFactory<ImagePolicy> (boost::shared_ptr< + ImagePolicy>(new ImagePolicy(1, 1, 1, 1)), "", 0); + vtkDataSet* product = factory.create(); + TSM_ASSERT("There is no point data in the polymorhic product.", product->GetNumberOfPoints() > 0); + product->Delete(); + } +}; + +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkThresholdingUnstructuredGridFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkThresholdingUnstructuredGridFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1cac53271a7aba1388de49416fb0347575439dbb --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkThresholdingUnstructuredGridFactoryTest.h @@ -0,0 +1,86 @@ +#ifndef VTK_THRESHOLDING_UNSTRUCTURED_GRID_FACTORY_TEST_H_ +#define VTK_THRESHOLDING_UNSTRUCTURED_GRID_FACTORY_TEST_H_ + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> +#include "vtkDataSetFactoryTest.h" +#include "MantidVatesAPI/vtkThresholdingUnstructuredGridFactory.h" + + +class vtkThresholdingUnstructuredGridFactoryTest: public CxxTest::TestSuite, public vtkDataSetFactoryTest +{ + // Common helper method to generate a simple product mesh. + static vtkUnstructuredGrid* createProduct(const int nbins) + { + using namespace Mantid::VATES; + //Easy to construct image policy for testing. + boost::shared_ptr<ImagePolicy> spImage(new ImagePolicy(nbins, nbins, nbins, nbins)); + std::string scalarName = "signal"; + const int timestep = 0; + + vtkThresholdingUnstructuredGridFactory<ImagePolicy> factory(spImage, scalarName, timestep); + return factory.create(); + } + + public: + + void testNumberOfPointsGenerated() + { + const int nbins = 10; + vtkUnstructuredGrid* product = createProduct(nbins); + const int correctPointNumber = (nbins + 1) * (nbins + 1) * (nbins + 1); + TSM_ASSERT_EQUALS("The number of points in the product vtkUnstructuredGrid is incorrect.", correctPointNumber, product->GetNumberOfPoints()); + product->Delete(); + } + + void testSignalDataType() + { + const int nbins = 10; + vtkUnstructuredGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + TSM_ASSERT_EQUALS("The obtained signal array is not of the correct type.", std::string("vtkFloatArray"), signalData->GetClassName()); + product->Delete(); + } + + void testNumberOfArrays() + { + const int nbins = 10; + vtkUnstructuredGrid* product = createProduct(nbins); + TSM_ASSERT_EQUALS("A single array should be present on the product dataset.", 1, product->GetCellData()->GetNumberOfArrays()); + product->Delete(); + } + + void testSignalDataName() + { + const int nbins = 10; + vtkUnstructuredGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + TSM_ASSERT_EQUALS("The obtained cell data has the wrong name.", std::string("signal"), signalData->GetName()); + product->Delete(); + } + + void testSignalDataSize() + { + const int nbins = 10; + vtkUnstructuredGrid* product = createProduct(nbins); + vtkDataArray* signalData = product->GetCellData()->GetArray(0); + const int correctCellNumber = (nbins - 1) * (nbins) * (nbins); //see getPoints implemenation in base class. when i is zero signal is zero. + TSM_ASSERT_EQUALS("The number of signal values generated is incorrect.", correctCellNumber, signalData->GetSize()); + product->Delete(); + } + + void testIsVtkDataSetFactory() + { + using namespace Mantid::VATES; + const vtkDataSetFactory& factory = vtkThresholdingUnstructuredGridFactory<ImagePolicy>(boost::shared_ptr<ImagePolicy>(new ImagePolicy(1, 1, 1, 1)), "", 0); + vtkDataSet* product = factory.create(); + TSM_ASSERT("There is no point data in the polymorhic product.", product->GetNumberOfPoints() > 0); + product->Delete(); + } + + + +}; + +#endif diff --git a/Code/Mantid/Vates/VisitDataBases/CMakeLists.txt b/Code/Mantid/Vates/VisitDataBases/CMakeLists.txt index dc6f4c67cef2c95519d39903e7a477f6e2d2baab..1055c733e31b3aac36c7bee28e2a5ee117ff2158 100644 --- a/Code/Mantid/Vates/VisitDataBases/CMakeLists.txt +++ b/Code/Mantid/Vates/VisitDataBases/CMakeLists.txt @@ -5,7 +5,7 @@ INCLUDE(${VISIT_INCLUDE_DIR}/VisItLibraryDependencies.cmake) PROJECT(MDFileReader) -set_mantid_subprojects(Vates/VisitPresenters) +set_mantid_subprojects(Vates/VatesAPI) SET(COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/MDFileReaderPluginInfo.C diff --git a/Code/Mantid/Vates/VisitPlugins/CutterOperator/CMakeLists.txt b/Code/Mantid/Vates/VisitPlugins/CutterOperator/CMakeLists.txt index e72cacb86dd28ad2607ee4e26568305ac8411464..79c1826db1cf9d6b7561adf4ee4905904e7c2497 100644 --- a/Code/Mantid/Vates/VisitPlugins/CutterOperator/CMakeLists.txt +++ b/Code/Mantid/Vates/VisitPlugins/CutterOperator/CMakeLists.txt @@ -5,7 +5,7 @@ INCLUDE(${VISIT_INCLUDE_DIR}/VisItLibraryDependencies.cmake) PROJECT(CutterOperator) -set_mantid_subprojects(Vates/VisitPresenters) +set_mantid_subprojects(Vates/VatesAPI) SET(COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/CutterOperatorPluginInfo.C diff --git a/Code/Mantid/Vates/VisitPlugins/RebinningCutterOperator/CMakeLists.txt b/Code/Mantid/Vates/VisitPlugins/RebinningCutterOperator/CMakeLists.txt index 71e7218323ee5dbac110ad0d00f0fb6cfadbe5d3..2b70c2118fd89bd3092470376cddc76b83514cf3 100644 --- a/Code/Mantid/Vates/VisitPlugins/RebinningCutterOperator/CMakeLists.txt +++ b/Code/Mantid/Vates/VisitPlugins/RebinningCutterOperator/CMakeLists.txt @@ -5,7 +5,7 @@ INCLUDE(${VISIT_INCLUDE_DIR}/VisItLibraryDependencies.cmake) PROJECT(RebinningCutter) -set_mantid_subprojects(Vates/VisitPresenters) +set_mantid_subprojects(Vates/VatesAPI) SET(COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/RebinningCutterPluginInfo.C