diff --git a/Code/Mantid/Framework/CMakeLists.txt b/Code/Mantid/Framework/CMakeLists.txt index 5aab1d64cd15cbabe5072eada4389032cd8c8eaa..4bc68f0e7546abf52c38191e4e5b6e393c26bf75 100644 --- a/Code/Mantid/Framework/CMakeLists.txt +++ b/Code/Mantid/Framework/CMakeLists.txt @@ -91,6 +91,9 @@ add_subdirectory (Algorithms) add_subdirectory (CurveFitting) add_subdirectory (ICat) +# Unit test helper package -- Disabled for the moment +#add_subdirectory (TestHelpers) + if ( MAKE_VATES ) add_subdirectory (MDDataObjects) include_directories(MDDataObjects/inc) diff --git a/Code/Mantid/Framework/TestHelpers/CMakeLists.txt b/Code/Mantid/Framework/TestHelpers/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2c2af6b32fd757a4010746ba12c25772ef6fe2ea --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/CMakeLists.txt @@ -0,0 +1,20 @@ +set ( SRC_FILES src/WorkspaceCreationHelper.cpp + src/ComponentCreationHelper.cpp + src/TestChannel.cpp ) + +set ( INC_FILES inc/MantidTestHelpers/DLLExport.h + inc/MantidTestHelpers/WorkspaceCreationHelper.h + inc/MantidTestHelpers/ComponentCreationHelper.h + inc/MantidTestHelpers/TestChannel.h ) + +include_directories ( inc ) + +# For Windows: +add_definitions ( -DIN_MANTID_TESTHELPERS ) + +# Add the target for this directory +add_library ( TestHelpers ${SRC_FILES} ${INC_FILES}) +# Set the name of the generated library +set_target_properties ( TestHelpers PROPERTIES OUTPUT_NAME MantidTestHelpers ) +# Set library dependencies +target_link_libraries ( TestHelpers ${MANTIDLIBS} ) diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..9ec63aaafda0c5179664fa78563ff94b9aa6e86e --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h @@ -0,0 +1,98 @@ +#ifndef COMPONENTCREATIONHELPER_H_ +#define COMPONENTCREATIONHELPER_H_ + +#include "MantidTestHelpers/DLLExport.h" + +#include "MantidGeometry/Instrument/CompAssembly.h" +#include "MantidGeometry/Instrument/ObjComponent.h" +#include "MantidGeometry/Instrument/DetectorGroup.h" +#include "MantidGeometry/Instrument/Detector.h" +#include "MantidGeometry/Instrument/Instrument.h" +#include "MantidGeometry/Instrument/RectangularDetector.h" +#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Objects/ShapeFactory.h" + +namespace ComponentCreationHelper +{ + +using namespace Mantid; +using namespace Mantid::Geometry; + + /** + A set of helper functions for creating various component structures for the unit tests. + + 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> + */ + + + //---------------------------------------------------------------------------------------------- + /** + * Create a capped cylinder object + */ + DLL_TESTHELPERS Object_sptr createCappedCylinder(double radius, double height, const V3D & baseCentre, const V3D & axis, const std::string & id); + /** + * Return the XML for a sphere. + */ + DLL_TESTHELPERS std::string sphereXML(double radius, const V3D & centre, const std::string & id); + /** + * Create a sphere object + */ + DLL_TESTHELPERS Object_sptr createSphere(double radius, const V3D & centre, const std::string & id); + /** Create a cuboid shape for your pixels */ + DLL_TESTHELPERS Object_sptr createCuboid(double x_side_length, double y_side_length = -1.0, double z_side_length = -1.0); + /** + * Create a component assembly at the origin made up of 4 cylindrical detectors + */ + DLL_TESTHELPERS boost::shared_ptr<CompAssembly> createTestAssemblyOfFourCylinders(); + /** + * Create an object component that has a defined shape + */ + DLL_TESTHELPERS ObjComponent * createSingleObjectComponent(); + /** + * Create a hollow shell, i.e. the intersection of two spheres or radius r1 and r2 + */ + DLL_TESTHELPERS Object_sptr createHollowShell(double innerRadius, double outerRadius, const V3D & centre = V3D()); + /** + * Create a detector group containing 5 detectors + */ + DLL_TESTHELPERS boost::shared_ptr<DetectorGroup> createDetectorGroupWith5CylindricalDetectors(); + /** + * Create a group of two monitors + */ + DLL_TESTHELPERS boost::shared_ptr<DetectorGroup> createGroupOfTwoMonitors(); + /** + * Create an test instrument with n panels of 9 cylindrical detectors, a source and spherical sample shape. + * + * @param num_banks: number of 9-cylinder banks to create + * @param verbose: prints out the instrument after creation. + */ + DLL_TESTHELPERS IInstrument_sptr createTestInstrumentCylindrical(int num_banks, bool verbose = false); + /** + * Create an test instrument with n panels of rectangular detectors, pixels*pixels in size, a source and spherical sample shape. + * + * @param num_banks: number of 9-cylinder banks to create + * @param verbose: prints out the instrument after creation. + */ + DLL_TESTHELPERS IInstrument_sptr createTestInstrumentRectangular(int num_banks, int pixels); + +} + +#endif //COMPONENTCREATIONHELPERS_H_ diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/DLLExport.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/DLLExport.h new file mode 100644 index 0000000000000000000000000000000000000000..a963837c991724bf6fbb391670c86941aa4543ec --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/DLLExport.h @@ -0,0 +1,14 @@ +#ifndef MANTID_TESTHELPERS_DLLEXPORT_H_ +#define MANTID_TESTHELPERS_DLLEXPORT_H_ +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include "MantidKernel/System.h" + +#ifdef IN_MANTID_TESTHELPERS +#define DLL_TESTHELPERS DLLExport +#else +#define DLL_TESTHELPERS DLLImport +#endif + +#endif //MANTID_TESTHELPERS_DLLEXPORT_H_ diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/TestChannel.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/TestChannel.h new file mode 100644 index 0000000000000000000000000000000000000000..1dadaf8a1f789feaa68770c28ab8856a95e29ddb --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/TestChannel.h @@ -0,0 +1,67 @@ +// +// TestChannel.h +// +// $Id: //poco/1.3/Foundation/testsuite/src/TestChannel.h#1 $ +// +// Definition of the TestChannel class. +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef TESTCHANNEL_H_ +#define TESTCHANNEL_H_ + +#include "MantidTestHelpers/DLLExport.h" + +#include "Poco/Channel.h" +#include "Poco/Message.h" +#include <list> + +namespace Mantid +{ + namespace TestHelpers + { + + class DLL_TESTHELPERS TestChannel: public Poco::Channel + { + public: + typedef std::list<Poco::Message> MsgList; + + TestChannel(); + ~TestChannel(); + + void log(const Poco::Message& msg); + MsgList& list(); + void clear(); + private: + MsgList _msgList; + }; + + } +} + +#endif // TESTCHANNEL_H_ diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..7b9c3602f966784d9a4fcc777421432899aa574c --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h @@ -0,0 +1,106 @@ +#ifndef WORKSPACECREATIONHELPER_H_ +#define WORKSPACECREATIONHELPER_H_ +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include "MantidTestHelpers/DLLExport.h" + +#include <cmath> + +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidGeometry/Instrument/Detector.h" +#include "MantidGeometry/Instrument/ParameterMap.h" +#include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidDataObjects/Workspace1D.h" +#include "MantidDataObjects/WorkspaceSingleValue.h" +// Other Helper +#include "ComponentCreationHelper.h" + +using namespace Mantid; +using namespace Mantid::DataObjects; +using namespace Mantid::Kernel; +using namespace Mantid::API; +using namespace Mantid::Geometry; + +namespace WorkspaceCreationHelper +{ + /// Create a fibonacci series + template<typename T> + struct FibSeries + { + private: + T x1; /// Initial value 1; + T x2; /// Initial value 2; + public: + inline FibSeries() : x1(1),x2(1) {} + inline T operator()() { const T out(x1+x2); x1=x2; x2=out; return out; } + }; + + DLL_TESTHELPERS Workspace1D_sptr Create1DWorkspaceRand(int size); + DLL_TESTHELPERS Workspace1D_sptr Create1DWorkspaceConstant(int size, double value, double error); + DLL_TESTHELPERS Workspace1D_sptr Create1DWorkspaceFib(int size); + DLL_TESTHELPERS Workspace2D_sptr Create2DWorkspace(int xlen, int ylen); + DLL_TESTHELPERS Workspace2D_sptr Create2DWorkspace123(int xlen, int ylen,bool isHist=0, const std::set<int> & + maskedWorkspaceIndices = std::set<int>()); + DLL_TESTHELPERS Workspace2D_sptr Create2DWorkspace154(int xlen, int ylen,bool isHist=0, + const std::set<int> & maskedWorkspaceIndices = std::set<int>()); + DLL_TESTHELPERS Workspace2D_sptr maskSpectra(DLL_TESTHELPERS Workspace2D_sptr workspace, + const std::set<int> & maskedWorkspaceIndices); + /** Create a 2D workspace with this many histograms and bins. + * Filled with Y = 2.0 and E = sqrt(2.0)w + */ + DLL_TESTHELPERS Workspace2D_sptr Create2DWorkspaceBinned(int nhist, int nbins, double x0=0.0, double deltax = 1.0); + + /** Create a 2D workspace with this many histograms and bins. The bins are assumed to be non-uniform and given by the input array + * Filled with Y = 2.0 and E = sqrt(2.0)w + */ + DLL_TESTHELPERS Workspace2D_sptr Create2DWorkspaceBinned(int nhist, const int numBoundaries, + const double xBoundaries[]); + /** + * Create a test workspace with a fully defined instrument + * Each spectra will have a cylindrical detector defined 2*cylinder_radius away from the centre of the + * pervious. + * Data filled with: Y: 2.0, E: sqrt(2.0), X: nbins of width 1 starting at 0 + */ + DLL_TESTHELPERS Workspace2D_sptr create2DWorkspaceWithFullInstrument(int nhist, int nbins, + bool includeMonitors = false); + DLL_TESTHELPERS WorkspaceSingleValue_sptr CreateWorkspaceSingleValue(double value); + DLL_TESTHELPERS WorkspaceSingleValue_sptr CreateWorkspaceSingleValueWithError(double value, double error); + /** Perform some finalization on event workspace stuff */ + DLL_TESTHELPERS void EventWorkspace_Finalize(EventWorkspace_sptr ew); + /** Create event workspace with: + * 500 pixels + * 1000 histogrammed bins. + */ + DLL_TESTHELPERS EventWorkspace_sptr CreateEventWorkspace(); + /** Create event workspace with: + * 50 pixels + * 100 histogrammed bins from 0.0 in steps of 1.0 + * 200 events; two in each bin, at time 0.5, 1.5, etc. + * PulseTime = 1 second, 2 seconds, etc. + */ + DLL_TESTHELPERS EventWorkspace_sptr CreateEventWorkspace2(); + /** Create event workspace + */ + DLL_TESTHELPERS EventWorkspace_sptr + CreateEventWorkspace(int numPixels, int numBins, int numEvents = 100, double x0=0.0, double binDelta=1.0, + int eventPattern = 1, int start_at_pixelID = 0); + /** Create event workspace + */ + DLL_TESTHELPERS EventWorkspace_sptr CreateGroupedEventWorkspace(std::vector< std::vector<int> > groups, + int numBins, double binDelta=1.0); + //not strictly creating a workspace, but really helpfull to see what one contains + DLL_TESTHELPERS void DisplayDataY(const MatrixWorkspace_sptr ws); + //not strictly creating a workspace, but really helpfull to see what one contains + DLL_TESTHELPERS void DisplayData(const MatrixWorkspace_sptr ws); + //not strictly creating a workspace, but really helpfull to see what one contains + DLL_TESTHELPERS void DisplayDataX(const MatrixWorkspace_sptr ws); + //not strictly creating a workspace, but really helpfull to see what one contains + DLL_TESTHELPERS void DisplayDataE(const MatrixWorkspace_sptr ws); + +}; + +#endif /*WORKSPACECREATIONHELPER_H_*/ diff --git a/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bef4059e154f1c950324801d5a83f38b570b52d7 --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp @@ -0,0 +1,311 @@ +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include "MantidTestHelpers/ComponentCreationHelper.h" + +namespace ComponentCreationHelper +{ + + //---------------------------------------------------------------------------------------------- + /** + * Create a capped cylinder object + */ + Object_sptr createCappedCylinder(double radius, double height, const V3D & baseCentre, const V3D & axis, const std::string & id) + { + std::ostringstream xml; + xml << "<cylinder id=\"" << id << "\">" + << "<centre-of-bottom-base x=\"" << baseCentre.X() << "\" y=\"" << baseCentre.Y() << "\" z=\"" << baseCentre.Z() << "\"/>" + << "<axis x=\"" << axis.X() << "\" y=\"" << axis.Y() << "\" z=\"" << axis.Z() << "\"/>" + << "<radius val=\"" << radius << "\" />" + << "<height val=\"" << height << "\" />" + << "</cylinder>"; + + ShapeFactory shapeMaker; + return shapeMaker.createShape(xml.str()); + } + + + //---------------------------------------------------------------------------------------------- + + /** + * Return the XML for a sphere. + */ + std::string sphereXML(double radius, const V3D & centre, const std::string & id) + { + std::ostringstream xml; + xml << "<sphere id=\"" << id << "\">" + << "<centre x=\"" << centre.X() << "\" y=\"" << centre.Y() << "\" z=\"" << centre.Z() << "\" />" + << "<radius val=\"" << radius << "\" />" + << "</sphere>"; + return xml.str(); + } + + /** + * Create a sphere object + */ + Object_sptr createSphere(double radius, const V3D & centre, const std::string & id) + { + ShapeFactory shapeMaker; + return shapeMaker.createShape(sphereXML(radius, centre, id)); + } + + + //---------------------------------------------------------------------------------------------- + /** Create a cuboid shape for your pixels */ + Object_sptr createCuboid(double x_side_length, double y_side_length, double z_side_length) + { + double szX = x_side_length; + double szY = (y_side_length == -1.0 ? szX : y_side_length); + double szZ = (z_side_length == -1.0 ? szX : z_side_length); + std::ostringstream xmlShapeStream; + xmlShapeStream + << " <cuboid id=\"detector-shape\"> " + << "<left-front-bottom-point x=\""<<szX<<"\" y=\""<<-szY<<"\" z=\""<<-szZ<<"\" /> " + << "<left-front-top-point x=\""<<szX<<"\" y=\""<<-szY<<"\" z=\""<<szZ<<"\" /> " + << "<left-back-bottom-point x=\""<<-szX<<"\" y=\""<<-szY<<"\" z=\""<<-szZ<<"\" /> " + << "<right-front-bottom-point x=\""<<szX<<"\" y=\""<<szY<<"\" z=\""<<-szZ<<"\" /> " + << "</cuboid>"; + + std::string xmlCuboidShape(xmlShapeStream.str()); + ShapeFactory shapeCreator; + Object_sptr cuboidShape = shapeCreator.createShape(xmlCuboidShape); + return cuboidShape; + } + + + //---------------------------------------------------------------------------------------------- + /** + * Create a component assembly at the origin made up of 4 cylindrical detectors + */ + boost::shared_ptr<CompAssembly> createTestAssemblyOfFourCylinders() + { + boost::shared_ptr<CompAssembly> bank = boost::shared_ptr<CompAssembly>(new CompAssembly("BankName")); + // One object + Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); + // Four object components + for( size_t i = 1; i < 5; ++i ) + { + ObjComponent * physicalPixel = new ObjComponent("pixel", pixelShape); + physicalPixel->setPos(static_cast<double>(i),0.0,0.0); + bank->add(physicalPixel); + } + + return bank; + } + + /** + * Create an object component that has a defined shape + */ + ObjComponent * createSingleObjectComponent() + { + Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); + return new ObjComponent("pixel", pixelShape); + } + + /** + * Create a hollow shell, i.e. the intersection of two spheres or radius r1 and r2 + */ + Object_sptr createHollowShell(double innerRadius, double outerRadius, const V3D & centre) + { + std::string wholeXML = + sphereXML(innerRadius, centre, "inner") + "\n" + + sphereXML(outerRadius, centre, "outer") + "\n" + + "<algebra val=\"(outer (# inner))\" />"; + + ShapeFactory shapeMaker; + return shapeMaker.createShape(wholeXML); + } + + //---------------------------------------------------------------------------------------------- + /** + * Create a detector group containing 5 detectors + */ + boost::shared_ptr<DetectorGroup> createDetectorGroupWith5CylindricalDetectors() + { + const int ndets = 5; + std::vector<boost::shared_ptr<IDetector> > groupMembers(ndets); + // One object + Object_sptr detShape = ComponentCreationHelper::createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); + for( int i = 0; i < ndets; ++i ) + { + std::ostringstream os; + os << "d" << i; + boost::shared_ptr<Detector> det(new Detector(os.str(), detShape, NULL)); + det->setID(i+1); + det->setPos((double)(i+1), 2.0, 2.0); + groupMembers[i] = det; + } + + return boost::shared_ptr<DetectorGroup>(new DetectorGroup(groupMembers, false)); + } + + + //---------------------------------------------------------------------------------------------- + /** + * Create a group of two monitors + */ + boost::shared_ptr<DetectorGroup> createGroupOfTwoMonitors() + { + const int ndets(2); + std::vector<boost::shared_ptr<IDetector> > groupMembers(ndets); + for( int i = 0; i < ndets; ++i ) + { + std::ostringstream os; + os << "m" << i; + boost::shared_ptr<Detector> det(new Detector(os.str(), NULL)); + det->setID(i+1); + det->setPos((double)(i+1), 2.0, 2.0); + det->markAsMonitor(); + groupMembers[i] = det; + } + return boost::shared_ptr<DetectorGroup>(new DetectorGroup(groupMembers, false)); + } + + + //---------------------------------------------------------------------------------------------- + /** + * Create an test instrument with n panels of 9 cylindrical detectors, a source and spherical sample shape. + * + * @param num_banks: number of 9-cylinder banks to create + * @param verbose: prints out the instrument after creation. + */ + IInstrument_sptr createTestInstrumentCylindrical(int num_banks, bool verbose) + { + boost::shared_ptr<Instrument> testInst(new Instrument("basic")); + + const double cylRadius(0.004); + const double cylHeight(0.0002); + // One object + Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(cylRadius, cylHeight, V3D(0.0,-cylHeight/2.0,0.0), V3D(0.,1.0,0.), "pixel-shape"); + + //Just increment pixel ID's + int pixelID = 1; + + for (int banknum=1; banknum <= num_banks; banknum++) + { + //Make a new bank + std::ostringstream bankname; + bankname << "bank" << banknum; + CompAssembly *bank = new CompAssembly(bankname.str()); + + // Four object components + for( int i = -1; i < 2; ++i ) + { + for( int j = -1; j < 2; ++j ) + { + std::ostringstream lexer; + lexer << "pixel-(" << j << "," << i << ")"; + Detector * physicalPixel = new Detector(lexer.str(), pixelShape, bank); + const double xpos = j*cylRadius*2.0; + const double ypos = i*cylHeight; + physicalPixel->setPos(xpos, ypos,0.0); + physicalPixel->setID(pixelID); + pixelID++; + bank->add(physicalPixel); + testInst->markAsDetector(physicalPixel); + } + } + + testInst->add(bank); + bank->setPos(V3D(0.0, 0.0, 5.0*banknum)); + } + + //Define a source component + ObjComponent *source = new ObjComponent("moderator", Object_sptr(new Object), testInst.get()); + source->setPos(V3D(0.0, 0.0, -10.)); + testInst->add(source); + testInst->markAsSource(source); + + // Define a sample as a simple sphere + Object_sptr sampleSphere = createSphere(0.001, V3D(0.0, 0.0, 0.0), "sample-shape"); + ObjComponent *sample = new ObjComponent("sample", sampleSphere, testInst.get()); + testInst->setPos(0.0, 0.0, 0.0); + testInst->add(sample); + testInst->markAsSamplePos(sample); + + if( verbose ) + { + std::cout << "\n\n=== Testing bank positions ==\n"; + const int nchilds = testInst->nelements(); + for(int i = 0; i < nchilds; ++i ) + { + boost::shared_ptr<IComponent> child = testInst->getChild(i); + std::cout << "Component " << i << " at pos " << child->getPos() << "\n"; + if( boost::shared_ptr<ICompAssembly> assem = boost::dynamic_pointer_cast<ICompAssembly>(child) ) + { + for(int j = 0; j < assem->nelements(); ++j ) + { + boost::shared_ptr<IComponent> comp = assem->getChild(j); + std::cout << "Child " << j << " at pos " << comp->getPos() << "\n"; + } + } + } + std::cout << "==================================\n"; + } + + return testInst; + } + + //---------------------------------------------------------------------------------------------- + /** + * Create an test instrument with n panels of rectangular detectors, pixels*pixels in size, a source and spherical sample shape. + * + * @param num_banks: number of 9-cylinder banks to create + * @param verbose: prints out the instrument after creation. + */ + IInstrument_sptr createTestInstrumentRectangular(int num_banks, int pixels) + { + boost::shared_ptr<Instrument> testInst(new Instrument("basic_rect")); + + const double cylRadius(0.004); + const double cylHeight(0.0002); + // One object + Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(cylRadius, cylHeight, V3D(0.0,-cylHeight/2.0,0.0), V3D(0.,1.0,0.), "pixel-shape"); + + //Just increment pixel ID's + int pixelID = 1; + + for (int banknum=1; banknum <= num_banks; banknum++) + { + //Make a new bank + std::ostringstream bankname; + bankname << "bank" << banknum; + + RectangularDetector * bank = new RectangularDetector(bankname.str()); + bank->initialize(pixelShape, + pixels, 0.0, cylRadius*2, + pixels, 0.0, cylRadius*2, + banknum*pixels*pixels, true, pixels); + + // Mark them all as detectors + for (int i=0; i < bank->nelements(); i++) + { + boost::shared_ptr<Geometry::Detector> detector = boost::dynamic_pointer_cast<Geometry::Detector>((*bank)[i]); + if (detector) + { + //Mark it as a detector (add to the instrument cache) + testInst->markAsDetector(detector.get()); + } + } + + testInst->add(bank); + bank->setPos(V3D(0.0, 0.0, 5.0*banknum)); + } + + //Define a source component + ObjComponent *source = new ObjComponent("moderator", Object_sptr(new Object), testInst.get()); + source->setPos(V3D(0.0, 0.0, -10.)); + testInst->add(source); + testInst->markAsSource(source); + + // Define a sample as a simple sphere + Object_sptr sampleSphere = createSphere(0.001, V3D(0.0, 0.0, 0.0), "sample-shape"); + ObjComponent *sample = new ObjComponent("sample", sampleSphere, testInst.get()); + testInst->setPos(0.0, 0.0, 0.0); + testInst->add(sample); + testInst->markAsSamplePos(sample); + + return testInst; + } +} + diff --git a/Code/Mantid/Framework/TestHelpers/src/TestChannel.cpp b/Code/Mantid/Framework/TestHelpers/src/TestChannel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a710ce799c5bc39e0cbda4e6a6d5bfa7116617c2 --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/src/TestChannel.cpp @@ -0,0 +1,36 @@ +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include "MantidTestHelpers/TestChannel.h" + +namespace Mantid +{ + + namespace TestHelpers + { + + TestChannel::TestChannel() + { + } + + TestChannel::~TestChannel() + { + } + + void TestChannel::log(const Poco::Message& msg) + { + _msgList.push_back(msg); + } + + TestChannel::MsgList& TestChannel::list() + { + return _msgList; + } + + void TestChannel::clear() + { + _msgList.clear(); + } + + } +} diff --git a/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..015e3a2ae1432be68bdba2d672038485754cf56c --- /dev/null +++ b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp @@ -0,0 +1,435 @@ +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +namespace WorkspaceCreationHelper +{ + + Workspace1D_sptr Create1DWorkspaceRand(int size) + { + MantidVecPtr x1,y1,e1; + x1.access().resize(size,1); + y1.access().resize(size); + std::generate(y1.access().begin(),y1.access().end(),rand); + e1.access().resize(size); + std::generate(e1.access().begin(),e1.access().end(),rand); + Workspace1D_sptr retVal(new Workspace1D); + retVal->initialize(1,size,size); + retVal->setX(x1); + retVal->setData(y1,e1); + return retVal; + } + + Workspace1D_sptr Create1DWorkspaceConstant(int size, double value, double error) + { + MantidVecPtr x1,y1,e1; + x1.access().resize(size,1); + y1.access().resize(size); + std::fill(y1.access().begin(), y1.access().end(), value); + e1.access().resize(size); + std::fill(y1.access().begin(), y1.access().end(), error); + Workspace1D_sptr retVal(new Workspace1D); + retVal->initialize(1,size,size); + retVal->setX(x1); + retVal->setData(y1,e1); + return retVal; + } + + Workspace1D_sptr Create1DWorkspaceFib(int size) + { + MantidVecPtr x1,y1,e1; + x1.access().resize(size,1); + y1.access().resize(size); + std::generate(y1.access().begin(),y1.access().end(),FibSeries<double>()); + e1.access().resize(size); + Workspace1D_sptr retVal(new Workspace1D); + retVal->initialize(1,size,size); + retVal->setX(x1); + retVal->setData(y1,e1); + return retVal; + } + Workspace2D_sptr Create2DWorkspace(int xlen, int ylen) + { + return Create2DWorkspaceBinned(xlen, ylen); + } + + Workspace2D_sptr Create2DWorkspace123(int xlen, int ylen,bool isHist, + const std::set<int> & maskedWorkspaceIndices) + { + MantidVecPtr x1,y1,e1; + x1.access().resize(isHist?xlen+1:xlen,1); + y1.access().resize(xlen,2); + e1.access().resize(xlen,3); + Workspace2D_sptr retVal(new Workspace2D); + retVal->initialize(ylen,isHist?xlen+1:xlen,xlen); + for (int i=0; i< ylen; i++) + { + retVal->setX(i,x1); + retVal->setData(i,y1,e1); + } + + retVal = maskSpectra(retVal, maskedWorkspaceIndices); + + return retVal; + } + + Workspace2D_sptr Create2DWorkspace154(int xlen, int ylen,bool isHist, + const std::set<int> & maskedWorkspaceIndices) + { + MantidVecPtr x1,y1,e1; + x1.access().resize(isHist?xlen+1:xlen,1); + y1.access().resize(xlen,5); + e1.access().resize(xlen,4); + Workspace2D_sptr retVal(new Workspace2D); + retVal->initialize(ylen,isHist?xlen+1:xlen,xlen); + for (int i=0; i< ylen; i++) + { + retVal->setX(i,x1); + retVal->setData(i,y1,e1); + } + + retVal = maskSpectra(retVal, maskedWorkspaceIndices); + + return retVal; + } + + Workspace2D_sptr maskSpectra(Workspace2D_sptr workspace, const std::set<int> & maskedWorkspaceIndices) + { + // We need detectors to be able to mask them. + workspace->setInstrument(boost::shared_ptr<Instrument>(new Instrument)); + boost::shared_ptr<Instrument> instrument = workspace->getBaseInstrument(); + + std::string xmlShape = "<sphere id=\"shape\"> "; + xmlShape += "<centre x=\"0.0\" y=\"0.0\" z=\"0.0\" /> " ; + xmlShape += "<radius val=\"0.05\" /> " ; + xmlShape += "</sphere>"; + xmlShape += "<algebra val=\"shape\" /> "; + + ShapeFactory sFactory; + boost::shared_ptr<Object> shape = sFactory.createShape(xmlShape); + + const int nhist(workspace->getNumberHistograms()); + + ParameterMap& pmap = workspace->instrumentParameters(); + for( int i = 0; i < nhist; ++i ) + { + workspace->getAxis(1)->spectraNo(i) = i; + } + workspace->mutableSpectraMap().populateSimple(0, nhist); + + for( int i = 0; i < nhist; ++i ) + { + Detector *det = new Detector("det",shape, NULL); + det->setPos(i,i+1,1); + det->setID(i); + instrument->add(det); + instrument->markAsDetector(det); + if ( maskedWorkspaceIndices.find(i) != maskedWorkspaceIndices.end() ) + { + pmap.addBool(det,"masked",true); + } + } + return workspace; + } + + /** Create a 2D workspace with this many histograms and bins. + * Filled with Y = 2.0 and E = sqrt(2.0)w + */ + Workspace2D_sptr Create2DWorkspaceBinned(int nhist, int nbins, double x0, double deltax) + { + MantidVecPtr x,y,e; + x.access().resize(nbins+1); + y.access().resize(nbins,2); + e.access().resize(nbins,sqrt(2.0)); + for (int i =0; i < nbins+1; ++i) + { + x.access()[i] = x0+i*deltax; + } + Workspace2D_sptr retVal(new Workspace2D); + retVal->initialize(nhist,nbins+1,nbins); + for (int i=0; i< nhist; i++) + { + retVal->setX(i,x); + retVal->setData(i,y,e); + retVal->getAxis(1)->setValue(i,i); + } + + return retVal; + } + + /** Create a 2D workspace with this many histograms and bins. The bins are assumed to be non-uniform and given by the input array + * Filled with Y = 2.0 and E = sqrt(2.0)w + */ + Workspace2D_sptr Create2DWorkspaceBinned(int nhist, const int numBoundaries, const double xBoundaries[]) + { + MantidVecPtr x,y,e; + const int numBins = numBoundaries - 1; + x.access().resize(numBoundaries); + y.access().resize(numBins,2); + e.access().resize(numBins,sqrt(2.0)); + for (int i = 0; i < numBoundaries; ++i) + { + x.access()[i] = xBoundaries[i]; + } + Workspace2D_sptr retVal(new Workspace2D); + retVal->initialize(nhist,numBins+1,numBins); + for (int i=0; i< nhist; i++) + { + retVal->setX(i,x); + retVal->setData(i,y,e); + } + + return retVal; + } + + + /** + * Create a test workspace with a fully defined instrument + * Each spectra will have a cylindrical detector defined 2*cylinder_radius away from the centre of the + * pervious. + * Data filled with: Y: 2.0, E: sqrt(2.0), X: nbins of width 1 starting at 0 + */ + Workspace2D_sptr create2DWorkspaceWithFullInstrument(int nhist, int nbins, bool includeMonitors) + { + Workspace2D_sptr space = Create2DWorkspaceBinned(nhist, nbins); + boost::shared_ptr<Instrument> testInst(new Instrument("testInst")); + space->setInstrument(testInst); + + // Create detectors for each spectra and set a simple mapping between pixel ID = spectrum number = index + const double pixelRadius(0.05); + Object_sptr pixelShape = + ComponentCreationHelper::createCappedCylinder(pixelRadius, 0.02, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); + + const double detXPos(5.0); + int ndets = nhist; + if( includeMonitors ) ndets -= 2; + for( int i = 0; i < ndets; ++i ) + { + std::ostringstream lexer; + lexer << "pixel-" << i << ")"; + Detector * physicalPixel = new Detector(lexer.str(), pixelShape, testInst.get()); + const double ypos = i*2.0*pixelRadius; + physicalPixel->setPos(detXPos, ypos,0.0); + physicalPixel->setID(i); + testInst->add(physicalPixel); + testInst->markAsDetector(physicalPixel); + } + + if( includeMonitors ) + { + Detector *monitor1 = new Detector("mon1", Object_sptr(), testInst.get()); + monitor1->setPos(-9.0,0.0,0.0); + monitor1->setID(ndets); + testInst->add(monitor1); + testInst->markAsMonitor(monitor1); + + Detector *monitor2 = new Detector("mon2", Object_sptr(), testInst.get()); + monitor2->setPos(-2.0,0.0,0.0); + monitor2->setID(ndets+1); + testInst->add(monitor2); + testInst->markAsMonitor(monitor2); + + space->mutableSpectraMap().populateSimple(0, ndets+2); + } + else + { + space->mutableSpectraMap().populateSimple(0, ndets); + } + + // Define a source and sample position + //Define a source component + ObjComponent *source = new ObjComponent("moderator", Object_sptr(), testInst.get()); + source->setPos(V3D(-20, 0.0, 0.0)); + testInst->add(source); + testInst->markAsSource(source); + + // Define a sample as a simple sphere + ObjComponent *sample = new ObjComponent("samplePos", Object_sptr(), testInst.get()); + testInst->setPos(0.0, 0.0, 0.0); + testInst->add(sample); + testInst->markAsSamplePos(sample); + + + return space; + } + + WorkspaceSingleValue_sptr CreateWorkspaceSingleValue(double value) + { + WorkspaceSingleValue_sptr retVal(new WorkspaceSingleValue(value,sqrt(value))); + return retVal; + } + + WorkspaceSingleValue_sptr CreateWorkspaceSingleValueWithError(double value, double error) + { + WorkspaceSingleValue_sptr retVal(new WorkspaceSingleValue(value, error)); + return retVal; + } + + /** Perform some finalization on event workspace stuff */ + void EventWorkspace_Finalize(EventWorkspace_sptr ew) + { + // get a proton charge + ew->mutableRun().integrateProtonCharge(); + } + + + /** Create event workspace with: + * 500 pixels + * 1000 histogrammed bins. + */ + EventWorkspace_sptr CreateEventWorkspace() + { + return CreateEventWorkspace(500,1001,100,1000); + } + + /** Create event workspace with: + * 50 pixels + * 100 histogrammed bins from 0.0 in steps of 1.0 + * 200 events; two in each bin, at time 0.5, 1.5, etc. + * PulseTime = 1 second, 2 seconds, etc. + */ + EventWorkspace_sptr CreateEventWorkspace2() + { + return CreateEventWorkspace(50, 100, 100, 0.0, 1.0, 2); + } + + /** Create event workspace + */ + EventWorkspace_sptr CreateEventWorkspace(int numPixels, + int numBins, int numEvents, double x0, double binDelta, + int eventPattern, int start_at_pixelID) + { + //add one to the number of bins as this is histogram + numBins++; + + EventWorkspace_sptr retVal(new EventWorkspace); + retVal->initialize(numPixels,1,1); + + //Make fake events + if (eventPattern) // 0 == no events + { + for (int pix= start_at_pixelID+0; pix < start_at_pixelID+numPixels; pix++) + { + for (int i=0; i<numEvents; i++) + { + if (eventPattern == 1) // 0, 1 diagonal pattern + retVal->getEventListAtPixelID(pix) += TofEvent((pix+i+0.5)*binDelta, Kernel::DateAndTime(i,0)); + else if (eventPattern == 2) // solid 2 + { + retVal->getEventListAtPixelID(pix) += TofEvent((i+0.5)*binDelta, Kernel::DateAndTime(i,0)); + retVal->getEventListAtPixelID(pix) += TofEvent((i+0.5)*binDelta, Kernel::DateAndTime(i,0)); + } + else if (eventPattern == 3) // solid 1 + { + retVal->getEventListAtPixelID(pix) += TofEvent((i+0.5)*binDelta, Kernel::DateAndTime(i,0)); + } + } + } + } + retVal->doneLoadingData(); + + //Create the x-axis for histogramming. + MantidVecPtr x1; + MantidVec& xRef = x1.access(); + xRef.resize(numBins); + for (int i = 0; i < numBins; ++i) + { + xRef[i] = x0+i*binDelta; + } + + //Set all the histograms at once. + retVal->setAllX(x1); + + return retVal; + } + + + /** Create event workspace + */ + EventWorkspace_sptr CreateGroupedEventWorkspace(std::vector< std::vector<int> > groups, + int numBins, double binDelta) + { + + EventWorkspace_sptr retVal(new EventWorkspace); + retVal->initialize(1,2,1); + + for (int g=0; g < groups.size(); g++) + { + std::vector<int> dets = groups[g]; + for (std::vector<int>::iterator it = dets.begin(); it != dets.end(); it++) + { + for (int i=0; i < numBins; i++) + retVal->getOrAddEventList(g) += TofEvent((i+0.5)*binDelta, 1); + retVal->getOrAddEventList(g).addDetectorID( *it ); + } + } + + retVal->doneAddingEventLists(); + + //Create the x-axis for histogramming. + MantidVecPtr x1; + MantidVec& xRef = x1.access(); + double x0=0; + xRef.resize(numBins); + for (int i = 0; i < numBins; ++i) + { + xRef[i] = x0+i*binDelta; + } + + //Set all the histograms at once. + retVal->setAllX(x1); + + return retVal; + } + + //not strictly creating a workspace, but really helpfull to see what one contains + void DisplayDataY(const MatrixWorkspace_sptr ws) + { + const int numHists = ws->getNumberHistograms(); + for (int i = 0; i < numHists; ++i) + { + std::cout << "Histogram " << i << " = "; + for (int j = 0; j < ws->blocksize(); ++j) + { + std::cout <<ws->readY(i)[j]<<" "; + } + std::cout<<std::endl; + } + } + void DisplayData(const MatrixWorkspace_sptr ws) + { + DisplayDataX(ws); + } + + //not strictly creating a workspace, but really helpfull to see what one contains + void DisplayDataX(const MatrixWorkspace_sptr ws) + { + const int numHists = ws->getNumberHistograms(); + for (int i = 0; i < numHists; ++i) + { + std::cout << "Histogram " << i << " = "; + for (int j = 0; j < ws->blocksize(); ++j) + { + std::cout <<ws->readX(i)[j]<<" "; + } + std::cout<<std::endl; + } + } + + //not strictly creating a workspace, but really helpfull to see what one contains + void DisplayDataE(const MatrixWorkspace_sptr ws) + { + const int numHists = ws->getNumberHistograms(); + for (int i = 0; i < numHists; ++i) + { + std::cout << "Histogram " << i << " = "; + for (int j = 0; j < ws->blocksize(); ++j) + { + std::cout <<ws->readE(i)[j]<<" "; + } + std::cout<<std::endl; + } + } + +}