diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index 3b76484a6707b347abcd280556e681f392adf9bb..3a51c8f0a456467f573069d4a5749834f7a89c11 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -26,6 +26,7 @@ set ( SRC_FILES src/ConvertToMatrixWorkspace.cpp src/ConvertToPointData.cpp src/ConvertUnits.cpp + src/CopySample.cpp src/CorrectKiKf.cpp src/CorrectToFile.cpp src/CreateCalFileByNames.cpp @@ -144,7 +145,7 @@ set ( SRC_FILES src/SumNeighbours.cpp src/SumRowColumn.cpp src/SumSpectra.cpp - src/TOFSANSResolution.cpp + src/TOFSANSResolution.cpp src/Transpose.cpp src/UnGroupWorkspaces.cpp src/UnaryOperation.cpp @@ -183,6 +184,7 @@ set ( INC_FILES inc/MantidAlgorithms/ConvertToMatrixWorkspace.h inc/MantidAlgorithms/ConvertToPointData.h inc/MantidAlgorithms/ConvertUnits.h + inc/MantidAlgorithms/CopySample.h inc/MantidAlgorithms/CorrectKiKf.h inc/MantidAlgorithms/CorrectToFile.h inc/MantidAlgorithms/CreateCalFileByNames.h @@ -302,7 +304,7 @@ set ( INC_FILES inc/MantidAlgorithms/SumNeighbours.h inc/MantidAlgorithms/SumRowColumn.h inc/MantidAlgorithms/SumSpectra.h - inc/MantidAlgorithms/TOFSANSResolution.h + inc/MantidAlgorithms/TOFSANSResolution.h inc/MantidAlgorithms/Transpose.h inc/MantidAlgorithms/UnGroupWorkspaces.h inc/MantidAlgorithms/UnaryOperation.h @@ -340,6 +342,7 @@ set ( TEST_FILES test/ConvertToMatrixWorkspaceTest.h test/ConvertToPointDataTest.h test/ConvertUnitsTest.h + test/CopySampleTest.h test/CorrectKiKfTest.h test/CorrectToFileTest.h test/CreateCalFileByNamesTest.h diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h new file mode 100644 index 0000000000000000000000000000000000000000..c6f9b43fd795223a7b987f4a7b58d331bac4cd04 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h @@ -0,0 +1,69 @@ +#ifndef MANTID_ALGORITHMS_COPYSAMPLE_H_ +#define MANTID_ALGORITHMS_COPYSAMPLE_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidAPI/Sample.h" + +namespace Mantid +{ +namespace Algorithms +{ + + /** CopySample : Algorithm to copy some/all the sample information from one workspace to another + + @author Andrei Savici, ORNL + @date 2011-08-11 + + 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 CopySample : public API::Algorithm + { + public: + CopySample(); + ~CopySample(); + + /// Algorithm's name for identification + virtual const std::string name() const { return "CopySample";}; + /// Algorithm's version for identification + virtual int version() const { return 1;}; + /// Algorithm's category for identification + virtual const std::string category() const { return "General";} + + private: + /// Sets documentation strings for this algorithm + virtual void initDocs(); + /// Initialise the properties + void init(); + /// Run the algorithm + void exec(); + /// Function to copy information from one sample to another + void copyParameters(API::Sample& from,API::Sample& to,bool nameFlag,bool materialFlag, bool environmentFlag, bool shapeFlag,bool latticeFlag); + + + + }; + + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_COPYSAMPLE_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/src/CopySample.cpp b/Code/Mantid/Framework/Algorithms/src/CopySample.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1e99dc820779228e661c79ef7f500ba3051e5767 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/CopySample.cpp @@ -0,0 +1,148 @@ +#include "MantidAlgorithms/CopySample.h" +#include "MantidKernel/System.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/SampleEnvironment.h" + +namespace Mantid +{ +namespace Algorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(CopySample) + + using namespace Mantid::Kernel; + using namespace Mantid::API; + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + CopySample::CopySample() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + CopySample::~CopySample() + { + } + + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void CopySample::initDocs() + { + this->setWikiSummary("Copy some/all the sample information from one workspace to another."); + this->setOptionalMessage("Copy some/all the sample information from one workspace to another."); + this->setWikiDescription("The algorithm copies some/all the sample information from one workspace to another." + "For MD workspaces, if no input sample number is specified, or not found, it will copy the" + "first sample. For MD workspaces, if no output sample number is specified, it will copy to all samples, "); + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void CopySample::init() + { + declareProperty(new WorkspaceProperty<Workspace>("InputWorkspace","",Direction::Input), "An input workspace from wich to copy sample information."); + declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace","",Direction::InOut), "An output workspace to wich to copy sample information.."); + declareProperty(new PropertyWithValue<bool>("CopyName",true,Direction::Input),"Copies the name of the sample" ); + declareProperty(new PropertyWithValue<bool>("CopyMaterial",true,Direction::Input),"Copies the material of the sample" ); + declareProperty(new PropertyWithValue<bool>("CopyEnvironment",true,Direction::Input),"" ); + declareProperty(new PropertyWithValue<bool>("CopyShape",true,Direction::Input),"" ); + declareProperty(new PropertyWithValue<bool>("CopyLattice",true,Direction::Input),"" ); + declareProperty(new PropertyWithValue<int>("MDInputSampleNumber",0,Direction::Input),"The number of the sample to be copied from, for an MD workspace (starting from 0)" ); + declareProperty(new PropertyWithValue<int>("MDOutputSampleNumber",EMPTY_INT(),Direction::Input),"The number of the sample to be copied to for an MD workspace (starting from 0). No number, or negative number, means that it will copy to all samples" ); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void CopySample::exec() + { + Workspace_sptr inWS=this->getProperty("InputWorkspace"); + Workspace_sptr outWS=this->getProperty("OutputWorkspace"); + + Sample sample; + //get input sample + IMDEventWorkspace_const_sptr inMDWS=boost::dynamic_pointer_cast<const IMDEventWorkspace>(inWS); + if (inMDWS != NULL) //it is an MD workspace + { + int inputSampleNumber=getProperty("MDInputSampleNumber"); + if (inputSampleNumber<0) + { + g_log.warning()<<"Number less then 0. Will use sample number 0 instead\n"; + inputSampleNumber=0; + } + if (static_cast<uint16_t>(inputSampleNumber)>(inMDWS->getNumExperimentInfo()-1)) + { + g_log.warning()<<"Number greater than the number of last sample in the workspace ("<<(inMDWS->getNumExperimentInfo()-1)<<"). Will use sample number 0 instead\n"; + inputSampleNumber=0; + } + sample=inMDWS->getExperimentInfo(static_cast<uint16_t>(inputSampleNumber))->sample(); + } + else //peaks workspace or matrix workspace + { + ExperimentInfo_sptr ei=boost::dynamic_pointer_cast<ExperimentInfo>(inWS); + if (!ei) throw std::invalid_argument("Wrong type of input workspace"); + sample=ei->sample(); + } + + bool copyName=getProperty("CopyName"); + bool copyMaterial=getProperty("CopyMaterial"); + bool copyEnvironment=getProperty("CopyEnvironment"); + bool copyShape=getProperty("CopyShape"); + bool copyLattice=getProperty("CopyLattice"); + + //Sample copy; + + IMDEventWorkspace_sptr outMDWS=boost::dynamic_pointer_cast<IMDEventWorkspace>(outWS); + if (outMDWS != NULL) + { + int outputSampleNumber=getProperty("MDOutputSampleNumber"); + if ((outputSampleNumber!=EMPTY_INT()) || (outputSampleNumber<0)) //copy to all samples + { + for(uint16_t i=0;i<outMDWS->getNumExperimentInfo();i++) + copyParameters(sample,outMDWS->getExperimentInfo(i)->mutableSample(),copyName,copyMaterial,copyEnvironment,copyShape,copyLattice); + } + else //copy to a single sample + { + if (static_cast<uint16_t>(outputSampleNumber)>(outMDWS->getNumExperimentInfo()-1)) + { + g_log.warning()<<"Number greater than the number of last sample in the workspace ("<<(outMDWS->getNumExperimentInfo()-1)<<"). Will use sample number 0 instead\n"; + outputSampleNumber=0; + } + copyParameters(sample,outMDWS->getExperimentInfo(static_cast<uint16_t>(outputSampleNumber))->mutableSample(),copyName,copyMaterial,copyEnvironment,copyShape,copyLattice); + } + } + else //peaks workspace or matrix workspace + { + ExperimentInfo_sptr ei=boost::dynamic_pointer_cast<ExperimentInfo>(outWS); + if (!ei) throw std::invalid_argument("Wrong type of output workspace"); + copyParameters(sample,ei->mutableSample(),copyName,copyMaterial,copyEnvironment,copyShape,copyLattice); + } + this->setProperty("OutputWorkspace",outWS); + } + + void CopySample::copyParameters(Sample& from,Sample& to,bool nameFlag,bool materialFlag, bool environmentFlag, bool shapeFlag,bool latticeFlag) + { + if (nameFlag) to.setName(from.getName()); + if (materialFlag) to.setMaterial(from.getMaterial()); + if (environmentFlag) to.setEnvironment(new SampleEnvironment(from.getEnvironment())); + if (shapeFlag) + { + to.setShape(from.getShape()); + to.setGeometryFlag(from.getGeometryFlag()); + to.setHeight(from.getHeight()); + to.setThickness(from.getThickness()); + to.setWidth(from.getWidth()); + } + if ((latticeFlag) && from.hasOrientedLattice()) to.setOrientedLattice(new OrientedLattice(from.getOrientedLattice())); + } + + +} // namespace Mantid +} // namespace Algorithms + diff --git a/Code/Mantid/Framework/Algorithms/test/CopySampleTest.h b/Code/Mantid/Framework/Algorithms/test/CopySampleTest.h new file mode 100644 index 0000000000000000000000000000000000000000..6ce1b263b9f67aa0ff8e804616f958ac1784afc3 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/CopySampleTest.h @@ -0,0 +1,177 @@ +#ifndef MANTID_ALGORITHMS_COPYSAMPLETEST_H_ +#define MANTID_ALGORITHMS_COPYSAMPLETEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidAlgorithms/CopySample.h" +#include "MantidDataObjects/WorkspaceSingleValue.h" +#include "MantidKernel/NeutronAtom.h" +#include "MantidAPI/Sample.h" +#include "MantidAPI/SampleEnvironment.h" +#include "MantidGeometry/Crystal/OrientedLattice.h" +#include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidGeometry/Instrument/ObjComponent.h" +#include "MantidGeometry/Objects/Object.h" + +using namespace Mantid; +using namespace Mantid::Algorithms; +using namespace Mantid::API; +using namespace Mantid::DataObjects; +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class CopySampleTest : public CxxTest::TestSuite +{ +public: + + + void test_Init() + { + CopySample alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + 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()); + } + ObjComponent * createSingleObjectComponent() + { + Object_sptr pixelShape = createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); + return new ObjComponent("pixel", pixelShape); + } + + Sample createsample() + { + Sample sample; + sample.setName("test"); + const std::string envName("TestKit"); + SampleEnvironment *kit = new SampleEnvironment(envName); + kit->add(createSingleObjectComponent()); + sample.setEnvironment(kit); + OrientedLattice *latt = new OrientedLattice(1.0,2.0,3.0, 90, 90, 90); + sample.setOrientedLattice(latt); + Material *vanBlock = new Material("vanBlock", Mantid::PhysicalConstants::getNeutronAtom(23, 0), 0.072); + sample.setMaterial(*vanBlock); + Object_sptr shape_sptr = + createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl"); + sample.setShape(*shape_sptr); + return sample; + } + + void test_exec_all() + { + WorkspaceSingleValue_sptr ws1(new WorkspaceSingleValue(1,1)); + WorkspaceSingleValue_sptr ws2(new WorkspaceSingleValue(4,2)); + Sample s=createsample(); + ws1->mutableSample()=s; + + // Name of the output workspace. + std::string inWSName("CopySampleTest_InputWS"); + std::string outWSName("CopySampleTest_OutputWS"); + AnalysisDataService::Instance().add(inWSName, ws1); + AnalysisDataService::Instance().add(outWSName, ws2); + + CopySample alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", inWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyName", "1") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyMaterial", "1") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyEnvironment", "1") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyShape", "1") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyLattice", "1") ); + + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. + MatrixWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(outWSName)) ); + TS_ASSERT(ws); + if (!ws) return; + + // Check the results + Sample copy=ws->mutableSample(); + TS_ASSERT_EQUALS(copy.getName(),"test" ); + TS_ASSERT_EQUALS(copy.getOrientedLattice().c(), 3.0); + TS_ASSERT_EQUALS(copy.getEnvironment().getName(), "TestKit"); + TS_ASSERT_EQUALS(copy.getEnvironment().nelements(), 1); + TS_ASSERT_DELTA(copy.getMaterial().cohScatterXSection(2.1), 0.0184, 1e-02); + TS_ASSERT_EQUALS(copy.getShape().getName(),s.getShape().getName()); + + // Remove workspace from the data service. + AnalysisDataService::Instance().remove(inWSName); + AnalysisDataService::Instance().remove(outWSName); + } + + + void test_exec_some() + { + WorkspaceSingleValue_sptr ws1(new WorkspaceSingleValue(1,1)); + WorkspaceSingleValue_sptr ws2(new WorkspaceSingleValue(4,2)); + Sample s=createsample(); + ws1->mutableSample()=s; + + // Name of the output workspace. + std::string inWSName("CopySampleTest_InputWS"); + std::string outWSName("CopySampleTest_OutputWS"); + AnalysisDataService::Instance().add(inWSName, ws1); + AnalysisDataService::Instance().add(outWSName, ws2); + + CopySample alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", inWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyName", "0") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyMaterial", "1") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyEnvironment", "1") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyShape", "0") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("CopyLattice", "0") ); + + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. + MatrixWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(outWSName)) ); + TS_ASSERT(ws); + if (!ws) return; + + // Check the results + Sample copy=ws->mutableSample(); + TS_ASSERT_DIFFERS(copy.getName(),"test" ); + TS_ASSERT(!copy.hasOrientedLattice()); + TS_ASSERT_EQUALS(copy.getEnvironment().getName(), "TestKit"); + TS_ASSERT_EQUALS(copy.getEnvironment().nelements(), 1); + TS_ASSERT_DELTA(copy.getMaterial().cohScatterXSection(2.1), 0.0184, 1e-02); + TS_ASSERT_DIFFERS(copy.getShape().getName(),s.getShape().getName()); + + // Remove workspace from the data service. + AnalysisDataService::Instance().remove(inWSName); + AnalysisDataService::Instance().remove(outWSName); + } + void test_MDcopy() + { + } + + +}; + + +#endif /* MANTID_ALGORITHMS_COPYSAMPLETEST_H_ */ +