Skip to content

Commit

Permalink
Added Min algorithm, and both Min and Max call Maxmin. Refs #4365
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreiSavici committed Dec 27, 2011
1 parent 47aeb94 commit a161291
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 89 deletions.
4 changes: 3 additions & 1 deletion Code/Mantid/Framework/Algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ set ( SRC_FILES
src/Max.cpp
src/MaxMin.cpp
src/MedianDetectorTest.cpp
src/MergeRuns.cpp
src/MergeRuns.cpp
src/Min.cpp
src/Minus.cpp
src/MonteCarloAbsorption.cpp
src/MultipleScatteringCylinderAbsorption.cpp
Expand Down Expand Up @@ -283,6 +284,7 @@ set ( INC_FILES
inc/MantidAlgorithms/MaxMin.h
inc/MantidAlgorithms/MedianDetectorTest.h
inc/MantidAlgorithms/MergeRuns.h
inc/MantidAlgorithms/Min.h
inc/MantidAlgorithms/Minus.h
inc/MantidAlgorithms/MonteCarloAbsorption.h
inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h
Expand Down
9 changes: 0 additions & 9 deletions Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Max.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,6 @@ class DLLExport Max : public API::Algorithm
void init();
void exec();

/// The value in X to start the search from
double m_MinRange;
/// The value in X to finish the search at
double m_MaxRange;
/// The spectrum to start the integration from
int m_MinSpec;
/// The spectrum to finish the integration at
int m_MaxSpec;

};

} // namespace Algorithm
Expand Down
78 changes: 78 additions & 0 deletions Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Min.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef MANTID_ALGORITHMS_MIN_H_
#define MANTID_ALGORITHMS_MIN_H_

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/Algorithm.h"

namespace Mantid
{
namespace Algorithms
{
/** Takes a 2D workspace as input and find the minimum in each 1D spectrum.
The algorithm creates a new 1D workspace containing all minima as well as their X boundaries
and error. This is used in particular for single crystal as a quick way to find strong peaks.
Required Properties:
<UL>
<LI> InputWorkspace - The name of the Workspace2D to take as input </LI>
<LI> OutputWorkspace - The name of the workspace in which to store the result </LI>
</UL>
Optional Properties (assume that you count from zero):
<UL>
<LI> Range_lower - The X value to search from (default min)</LI>
<LI> Range_upper - The X value to search to (default max)</LI>
<LI> StartSpectrum - Start spectrum number (default 0)</LI>
<LI> EndSpectrum - End spectrum number (default max)</LI>
</UL>
@author L C Chapon, ISIS, Rutherford Appleton Laboratory
@date 11/08/2009
Copyright &copy; 2007-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 Min : public API::Algorithm
{
public:
/// Default constructor
Min() : API::Algorithm() {};
/// Destructor
virtual ~Min() {};
/// Algorithm's name for identification overriding a virtual method
virtual const std::string name() const { return "Min";}
/// Algorithm's version for identification overriding a virtual method
virtual int version() const { return (1);}
/// Algorithm's category for identification overriding a virtual method
virtual const std::string category() const { return "Arithmetic";}

private:
void initDocs();
// Overridden Algorithm methods
void init();
void exec();

};

} // namespace Algorithm
} // namespace Mantid

#endif /*MANTID_ALGORITHMS_MIN_H_*/
100 changes: 21 additions & 79 deletions Code/Mantid/Framework/Algorithms/src/Max.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void Max::init()
"The name of the workspace in which to store the result");

declareProperty("RangeLower",EMPTY_DBL(),
"The X value to search from (default 0)");
"The X value to search from (default min)");
declareProperty("RangeUpper",EMPTY_DBL(),
"The X value to search to (default max)");
BoundedValidator<int> *mustBePositive = new BoundedValidator<int>();
Expand All @@ -61,87 +61,29 @@ void Max::init()
void Max::exec()
{
// Try and retrieve the optional properties
m_MinRange = getProperty("RangeLower");
m_MaxRange = getProperty("RangeUpper");
m_MinSpec = getProperty("StartWorkspaceIndex");
m_MaxSpec = getProperty("EndWorkspaceIndex");
double m_MinRange = getProperty("RangeLower");
double m_MaxRange = getProperty("RangeUpper");
int m_MinSpec = getProperty("StartWorkspaceIndex");
int m_MaxSpec = getProperty("EndWorkspaceIndex");


// Get the input workspace
MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

const int numberOfSpectra = static_cast<int>(localworkspace->getNumberHistograms());

// Check 'StartSpectrum' is in range 0-numberOfSpectra
if ( m_MinSpec > numberOfSpectra )
{
g_log.warning("StartSpectrum out of range! Set to 0.");
m_MinSpec = 0;
}
if ( isEmpty(m_MaxSpec) ) m_MaxSpec = numberOfSpectra-1;
if ( m_MaxSpec > numberOfSpectra-1 || m_MaxSpec < m_MinSpec )
{
g_log.warning("EndSpectrum out of range! Set to max detector number");
m_MaxSpec = numberOfSpectra;
}
if ( m_MinRange > m_MaxRange )
{
g_log.warning("Range_upper is less than Range_lower. Will integrate up to frame maximum.");
m_MaxRange = 0.0;
}

// Create the 1D workspace for the output
MatrixWorkspace_sptr outputWorkspace = API::WorkspaceFactory::Instance().create(localworkspace,m_MaxSpec-m_MinSpec+1,2,1);


Progress progress(this,0,1,(m_MaxSpec-m_MinSpec+1));
PARALLEL_FOR2(localworkspace,outputWorkspace)
// Loop over spectra
for (int i = m_MinSpec; i <= m_MaxSpec; ++i)
{
PARALLEL_START_INTERUPT_REGION
int newindex=i-m_MinSpec;
if (localworkspace->axes() > 1)
{
outputWorkspace->getAxis(1)->spectraNo(newindex) = localworkspace->getAxis(1)->spectraNo(i);
}

// Retrieve the spectrum into a vector
const MantidVec& X = localworkspace->readX(i);
const MantidVec& Y = localworkspace->readY(i);

// Find the range [min,max]
MantidVec::const_iterator lowit, highit;
if (m_MinRange == EMPTY_DBL()) lowit=X.begin();
else lowit=std::lower_bound(X.begin(),X.end(),m_MinRange);

if (m_MaxRange == EMPTY_DBL()) highit=X.end();
else highit=std::find_if(lowit,X.end(),std::bind2nd(std::greater<double>(),m_MaxRange));

// If range specified doesn't overlap with this spectrum then bail out
if ( lowit == X.end() || highit == X.begin() ) continue;

--highit; // Upper limit is the bin before, i.e. the last value smaller than MaxRange

MantidVec::difference_type distmin=std::distance(X.begin(),lowit);
MantidVec::difference_type distmax=std::distance(X.begin(),highit);

// Find the max element
MantidVec::const_iterator maxY=std::max_element(Y.begin()+distmin,Y.begin()+distmax);
MantidVec::difference_type d=std::distance(Y.begin(),maxY);
// X boundaries for the max element
outputWorkspace->dataX(newindex)[0]=*(X.begin()+d);
outputWorkspace->dataX(newindex)[1]=*(X.begin()+d+1); //This is safe since X is of dimension Y+1
outputWorkspace->dataY(newindex)[0]=*maxY;
progress.report();
PARALLEL_END_INTERUPT_REGION
}
PARALLEL_CHECK_INTERUPT_REGION

// Assign it to the output workspace property
setProperty("OutputWorkspace",outputWorkspace);

return;
MatrixWorkspace_sptr inworkspace = getProperty("InputWorkspace");


// sub-algorithme does all of the actual work - do not set the output workspace
IAlgorithm_sptr maxAlgo = createSubAlgorithm("MaxMin", 0., 1.);
maxAlgo->setProperty("InputWorkspace", inworkspace);
maxAlgo->setProperty("RangeLower", m_MinRange);
maxAlgo->setProperty("RangeUpper", m_MaxRange);
maxAlgo->setProperty("StartWorkspaceIndex", m_MinSpec);
maxAlgo->setProperty("EndWorkspaceIndex", m_MaxSpec);
maxAlgo->setProperty("ShowMin",false);
maxAlgo->execute();
// just grab the child's output workspace
MatrixWorkspace_sptr outputWS = maxAlgo->getProperty("OutputWorkspace");

this->setProperty("OutputWorkspace", outputWS);
}

} // namespace Algorithms
Expand Down
91 changes: 91 additions & 0 deletions Code/Mantid/Framework/Algorithms/src/Min.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*WIKI*
*WIKI*/
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAlgorithms/Min.h"
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidKernel/VectorHelper.h"
#include "MantidAPI/Progress.h"

namespace Mantid
{
namespace Algorithms
{

// Register the class into the algorithm factory
DECLARE_ALGORITHM(Min)

using namespace Kernel;
using namespace API;

/// Set the documentation strings
void Min::initDocs()
{
this->setWikiSummary("Takes a 2D workspace as input and find the minimum in each 1D spectrum. The algorithm creates a new 1D workspace containing all minima as well as their X boundaries and error. This is used in particular for single crystal as a quick way to find strong peaks.");
this->setOptionalMessage("Takes a 2D workspace as input and find the minimum in each 1D spectrum. The algorithm creates a new 1D workspace containing all minima as well as their X boundaries and error. This is used in particular for single crystal as a quick way to find strong peaks.");
}

/** Initialisation method.
*
*/
void Min::init()
{
declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input,new HistogramValidator<>),
"The name of the Workspace2D to take as input");
declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output),
"The name of the workspace in which to store the result");

declareProperty("RangeLower",EMPTY_DBL(),
"The X value to search from (default min)");
declareProperty("RangeUpper",EMPTY_DBL(),
"The X value to search to (default max)");
BoundedValidator<int> *mustBePositive = new BoundedValidator<int>();
mustBePositive->setLower(0);
declareProperty("StartWorkspaceIndex",0, mustBePositive,
"Start spectrum number (default 0)");
// As the property takes ownership of the validator pointer, have to take care to pass in a unique
// pointer to each property.
declareProperty("EndWorkspaceIndex",EMPTY_INT(), mustBePositive->clone(),
"End spectrum number (default max)");
}

/** Executes the algorithm
*
* @throw runtime_error Thrown if algorithm cannot execute
*/
void Min::exec()
{
// Try and retrieve the optional properties
double m_MinRange = getProperty("RangeLower");
double m_MaxRange = getProperty("RangeUpper");
int m_MinSpec = getProperty("StartWorkspaceIndex");
int m_MaxSpec = getProperty("EndWorkspaceIndex");


// Get the input workspace
MatrixWorkspace_sptr inworkspace = getProperty("InputWorkspace");


// sub-algorithme does all of the actual work - do not set the output workspace
IAlgorithm_sptr minAlgo = createSubAlgorithm("MaxMin", 0., 1.);
minAlgo->setProperty("InputWorkspace", inworkspace);
minAlgo->setProperty("RangeLower", m_MinRange);
minAlgo->setProperty("RangeUpper", m_MaxRange);
minAlgo->setProperty("StartWorkspaceIndex", m_MinSpec);
minAlgo->setProperty("EndWorkspaceIndex", m_MaxSpec);
minAlgo->setProperty("ShowMin",true);
minAlgo->execute();
// just grab the child's output workspace
MatrixWorkspace_sptr outputWS = minAlgo->getProperty("OutputWorkspace");

this->setProperty("OutputWorkspace", outputWS);

}

} // namespace Algorithms
} // namespace Mantid

0 comments on commit a161291

Please sign in to comment.