Skip to content
Snippets Groups Projects
Commit fb98618b authored by Savici, Andrei T.'s avatar Savici, Andrei T.
Browse files

Algorithm to copy sample info between compatible workspaces. Refs #3484

parent be0ea0c2
No related branches found
No related tags found
No related merge requests found
...@@ -26,6 +26,7 @@ set ( SRC_FILES ...@@ -26,6 +26,7 @@ set ( SRC_FILES
src/ConvertToMatrixWorkspace.cpp src/ConvertToMatrixWorkspace.cpp
src/ConvertToPointData.cpp src/ConvertToPointData.cpp
src/ConvertUnits.cpp src/ConvertUnits.cpp
src/CopySample.cpp
src/CorrectKiKf.cpp src/CorrectKiKf.cpp
src/CorrectToFile.cpp src/CorrectToFile.cpp
src/CreateCalFileByNames.cpp src/CreateCalFileByNames.cpp
...@@ -144,7 +145,7 @@ set ( SRC_FILES ...@@ -144,7 +145,7 @@ set ( SRC_FILES
src/SumNeighbours.cpp src/SumNeighbours.cpp
src/SumRowColumn.cpp src/SumRowColumn.cpp
src/SumSpectra.cpp src/SumSpectra.cpp
src/TOFSANSResolution.cpp src/TOFSANSResolution.cpp
src/Transpose.cpp src/Transpose.cpp
src/UnGroupWorkspaces.cpp src/UnGroupWorkspaces.cpp
src/UnaryOperation.cpp src/UnaryOperation.cpp
...@@ -183,6 +184,7 @@ set ( INC_FILES ...@@ -183,6 +184,7 @@ set ( INC_FILES
inc/MantidAlgorithms/ConvertToMatrixWorkspace.h inc/MantidAlgorithms/ConvertToMatrixWorkspace.h
inc/MantidAlgorithms/ConvertToPointData.h inc/MantidAlgorithms/ConvertToPointData.h
inc/MantidAlgorithms/ConvertUnits.h inc/MantidAlgorithms/ConvertUnits.h
inc/MantidAlgorithms/CopySample.h
inc/MantidAlgorithms/CorrectKiKf.h inc/MantidAlgorithms/CorrectKiKf.h
inc/MantidAlgorithms/CorrectToFile.h inc/MantidAlgorithms/CorrectToFile.h
inc/MantidAlgorithms/CreateCalFileByNames.h inc/MantidAlgorithms/CreateCalFileByNames.h
...@@ -302,7 +304,7 @@ set ( INC_FILES ...@@ -302,7 +304,7 @@ set ( INC_FILES
inc/MantidAlgorithms/SumNeighbours.h inc/MantidAlgorithms/SumNeighbours.h
inc/MantidAlgorithms/SumRowColumn.h inc/MantidAlgorithms/SumRowColumn.h
inc/MantidAlgorithms/SumSpectra.h inc/MantidAlgorithms/SumSpectra.h
inc/MantidAlgorithms/TOFSANSResolution.h inc/MantidAlgorithms/TOFSANSResolution.h
inc/MantidAlgorithms/Transpose.h inc/MantidAlgorithms/Transpose.h
inc/MantidAlgorithms/UnGroupWorkspaces.h inc/MantidAlgorithms/UnGroupWorkspaces.h
inc/MantidAlgorithms/UnaryOperation.h inc/MantidAlgorithms/UnaryOperation.h
...@@ -340,6 +342,7 @@ set ( TEST_FILES ...@@ -340,6 +342,7 @@ set ( TEST_FILES
test/ConvertToMatrixWorkspaceTest.h test/ConvertToMatrixWorkspaceTest.h
test/ConvertToPointDataTest.h test/ConvertToPointDataTest.h
test/ConvertUnitsTest.h test/ConvertUnitsTest.h
test/CopySampleTest.h
test/CorrectKiKfTest.h test/CorrectKiKfTest.h
test/CorrectToFileTest.h test/CorrectToFileTest.h
test/CreateCalFileByNamesTest.h test/CreateCalFileByNamesTest.h
......
#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_ */
#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
#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_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment