Skip to content

Commit

Permalink
refs #5626. Gets function from param file.
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenArnold committed Jul 19, 2012
1 parent 9ef93b8 commit 8254afc
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/Algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ set ( SRC_FILES
src/MuonAsymmetryCalc.cpp
src/MuonRemoveExpDecay.cpp
src/NormaliseByCurrent.cpp
src/NormaliseByDetector.cpp
src/NormaliseToMonitor.cpp
src/NormaliseToUnity.cpp
src/OneMinusExponentialCor.cpp
Expand Down Expand Up @@ -321,6 +322,7 @@ set ( INC_FILES
inc/MantidAlgorithms/MuonAsymmetryCalc.h
inc/MantidAlgorithms/MuonRemoveExpDecay.h
inc/MantidAlgorithms/NormaliseByCurrent.h
inc/MantidAlgorithms/NormaliseByDetector.h
inc/MantidAlgorithms/NormaliseToMonitor.h
inc/MantidAlgorithms/NormaliseToUnity.h
inc/MantidAlgorithms/OneMinusExponentialCor.h
Expand Down Expand Up @@ -500,6 +502,7 @@ set ( TEST_FILES
test/MuonAsymmetryCalcTest.h
test/MuonRemoveExpDecayTest.h
test/NormaliseByCurrentTest.h
test/NormaliseByDetectorTest.h
test/NormaliseToMonitorTest.h
test/OneMinusExponentialCorTest.h
test/PDFFTTest.h
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef MANTID_ALGORITHMS_NORMALISEBYDETECTOR_H_
#define MANTID_ALGORITHMS_NORMALISEBYDETECTOR_H_

#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"

namespace Mantid
{
namespace Algorithms
{

/** NormaliseByDetector : TODO: DESCRIPTION
@date 2012-07-17
Copyright © 2012 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 NormaliseByDetector : public API::Algorithm
{
public:
NormaliseByDetector();
virtual ~NormaliseByDetector();

virtual const std::string name() const;
virtual int version() const;
virtual const std::string category() const;

private:
virtual void initDocs();
void init();
void exec();


};


} // namespace Algorithms
} // namespace Mantid

#endif /* MANTID_ALGORITHMS_NORMALISEBYDETECTOR_H_ */
97 changes: 97 additions & 0 deletions Code/Mantid/Framework/Algorithms/src/NormaliseByDetector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*WIKI*
Normalise a workspace by the detector efficiency.
*WIKI*/

#include "MantidAlgorithms/NormaliseByDetector.h"
#include "MantidKernel/System.h"
#include "MantidAPI/FunctionFactory.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidGeometry/Instrument/ParameterMap.h"
#include "MantidGeometry/Instrument/Component.h"
#include "MantidGeometry/Instrument/DetectorGroup.h"
#include "MantidGeometry/Instrument/FitParameter.h"

using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;

namespace Mantid
{
namespace Algorithms
{

// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(NormaliseByDetector)



//----------------------------------------------------------------------------------------------
/** Constructor
*/
NormaliseByDetector::NormaliseByDetector()
{
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
NormaliseByDetector::~NormaliseByDetector()
{
}


//----------------------------------------------------------------------------------------------
/// Algorithm's name for identification. @see Algorithm::name
const std::string NormaliseByDetector::name() const { return "NormaliseByDetector";};

/// Algorithm's version for identification. @see Algorithm::version
int NormaliseByDetector::version() const { return 1;};

/// Algorithm's category for identification. @see Algorithm::category
const std::string NormaliseByDetector::category() const { return "General";}

//----------------------------------------------------------------------------------------------
/// Sets documentation strings for this algorithm
void NormaliseByDetector::initDocs()
{
this->setWikiSummary("Normalise the input workspace by the detector efficiency.");
this->setOptionalMessage("Normalise the input workspace by the detector efficiency.");
}

//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void NormaliseByDetector::init()
{
declareProperty(new WorkspaceProperty<MatrixWorkspace>("InputWorkspace","",Direction::Input), "An input workspace.");
declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace","",Direction::Output), "An output workspace.");
}

//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void NormaliseByDetector::exec()
{
MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");

const Geometry::ParameterMap& paramMap = inWS->instrumentParameters();

for(size_t wsIndex = 0; wsIndex < inWS->getNumberHistograms(); ++wsIndex)
{
Geometry::IDetector_const_sptr det = inWS->getDetector( wsIndex );
const std::string type = "fitting";
Geometry::Parameter_sptr fittingParam = paramMap.getRecursiveByType(&(*det), type);
if(fittingParam == NULL)
{
std::stringstream stream;
stream << det->getName() << " and all of it's parent components, have no fitting type parameters. This algorithm cannot be run without fitting parameters.";
this->g_log.warning(stream.str());
throw std::invalid_argument(stream.str());
}
}

setProperty("OutputWorkspace", inWS); //HACK
}

} // namespace Mantid
} // namespace Algorithms
140 changes: 140 additions & 0 deletions Code/Mantid/Framework/Algorithms/test/NormaliseByDetectorTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#ifndef MANTID_ALGORITHMS_NORMALISEBYDETECTORTEST_H_
#define MANTID_ALGORITHMS_NORMALISEBYDETECTORTEST_H_

#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
#include "MantidDataHandling/LoadEmptyInstrument.h"
#include "MantidDataHandling/LoadParameterFile.h"
#include <iostream>
#include <iomanip>
#include <fstream>

#include "MantidAlgorithms/NormaliseByDetector.h"

using namespace Mantid;
using namespace Mantid::Algorithms;
using namespace Mantid::API;
using namespace Mantid::DataHandling;

class NormaliseByDetectorTest : public CxxTest::TestSuite
{

private:

MatrixWorkspace_sptr create_empty_instrument_with_no_fitting_functions()
{
const std::string instrumentWorkspace = "InstrumentWorkspace";
LoadEmptyInstrument loadAlg;
loadAlg.initialize();
loadAlg.setPropertyValue("Filename", "POLREF_Definition.xml");
loadAlg.setPropertyValue("OutputWorkspace", instrumentWorkspace);
loadAlg.execute();
return AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(instrumentWorkspace);
}

MatrixWorkspace_sptr create_empty_instrument_with_fitting_functions()
{
class FileObject
{
public:

/// Create a simple input file.
FileObject(const std::string& fileContents, const std::string& filename) : m_filename(filename)
{
m_file.open (filename.c_str());
m_file << fileContents;
m_file.close();
}

std::string getFileName() const
{
return m_filename;
}

/// Free up resources.
~FileObject()
{
m_file.close();
if( remove( m_filename.c_str() ) != 0 )
throw std::runtime_error("cannot remove " + m_filename);
}

private:
const std::string m_filename;
std::ofstream m_file;
// Following methods keeps us from being able to put objects of this type on the heap.
void *operator new(size_t);
void *operator new[](size_t);
};

// Create a parameter file, with a root equation that will apply to all detectors.
const std::string parameterFileContents = std::string("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n") +
"<parameter-file instrument = \"POLREF\" date = \"2012-01-31T00:00:00\">\n" +
"<component-link name=\"POLREF\">\n" +
"<parameter name=\"LinearBackground:A0\" type=\"fitting\">\n" +
" <formula eq=\"1.0\" result-unit=\"TOF\"/>\n" +
" <fixed />\n" +
"</parameter>\n" +
"<parameter name=\"LinearBackground:A1\" type=\"fitting\">\n" +
" <formula eq=\"2.0\" result-unit=\"TOF\"/>\n" +
" <fixed />\n" +
"</parameter>\n" +
"</component-link>\n" +
"</parameter-file>\n";

FileObject file(parameterFileContents, "POLREF_Parameters.xml");
MatrixWorkspace_sptr ws = create_empty_instrument_with_no_fitting_functions();

LoadParameterFile loadParameterAlg;
loadParameterAlg.setRethrows(true);
loadParameterAlg.initialize();
loadParameterAlg.setPropertyValue("Filename", file.getFileName());
loadParameterAlg.setProperty("Workspace", ws);
loadParameterAlg.execute();
return ws;
}

public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static NormaliseByDetectorTest *createSuite() { return new NormaliseByDetectorTest(); }
static void destroySuite( NormaliseByDetectorTest *suite ) { delete suite; }


void test_Init()
{
NormaliseByDetector alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}

void test_throws_when_no_fit_function_on_detector_tree()
{
MatrixWorkspace_sptr inputWS = create_empty_instrument_with_no_fitting_functions();

NormaliseByDetector alg;
alg.setRethrows(true);
alg.initialize();
alg.setPropertyValue("OutputWorkspace", "out");
alg.setProperty("InputWorkspace", inputWS);
TS_ASSERT_THROWS(alg.execute(), std::invalid_argument);
}

void test_applies_instrument_function_to_child_detectors()
{
MatrixWorkspace_sptr inputWS = create_empty_instrument_with_fitting_functions();
NormaliseByDetector alg;
alg.setRethrows(true);
alg.initialize();
alg.setPropertyValue("OutputWorkspace", "out");
alg.setProperty("InputWorkspace", inputWS);
TSM_ASSERT_THROWS_NOTHING("Instrument wide, fitting function applied. Should not throw.", alg.execute());
}



};


#endif /* MANTID_ALGORITHMS_NORMALISEBYDETECTORTEST_H_ */
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ namespace Geometry
boost::shared_ptr<Parameter> get(const IComponent* comp,const std::string& name,
const std::string & type = "")const;
/// Finds the parameter in the map via the parameter type.
boost::shared_ptr<Parameter> ParameterMap::getByType(const IComponent* comp, const std::string& type) const;
boost::shared_ptr<Parameter> getByType(const IComponent* comp, const std::string& type) const;
/// Use get() recursively to see if can find param in all parents of comp.
boost::shared_ptr<Parameter> getRecursive(const IComponent* comp, const char * name) const;
/// Use get() recursively to see if can find param in all parents of comp and given type
Expand Down

0 comments on commit 8254afc

Please sign in to comment.