Skip to content

Commit

Permalink
Re #6267. Add a validateInputs method and tests.
Browse files Browse the repository at this point in the history
Adds cross-checking of parameters, such as the log actually existing
in the given workspace and being of a valid type.
  • Loading branch information
RussellTaylor committed Dec 11, 2012
1 parent 5dd056d commit 86d622e
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 7 deletions.
Expand Up @@ -47,13 +47,14 @@ class DLLExport FilterByLogValue : public API::Algorithm
/// Algorithm's category for identification overriding a virtual method
virtual const std::string category() const { return "Events\\EventFiltering";}

std::map<std::string, std::string> validateInputs();

private:
/// Sets documentation strings for this algorithm
virtual void initDocs();
// Implement abstract Algorithm methods
void init();
void exec();

};

} // namespace Algorithms
Expand Down
38 changes: 34 additions & 4 deletions Code/Mantid/Framework/Algorithms/src/FilterByLogValue.cpp
Expand Up @@ -42,6 +42,7 @@ times of the pulses to be rejected. For example, this call will filter out veto
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/ITimeSeriesProperty.h"
#include "MantidKernel/ListValidator.h"
#include "MantidKernel/MandatoryValidator.h"

namespace Mantid
{
Expand Down Expand Up @@ -92,13 +93,13 @@ void FilterByLogValue::init()
new WorkspaceProperty<EventWorkspace>("OutputWorkspace","",Direction::Output),
"The name to use for the output workspace" );

declareProperty("LogName", "",
declareProperty("LogName", "", boost::make_shared<MandatoryValidator<std::string>>(),
"Name of the sample log to use to filter.\n"
"For example, the pulse charge is recorded in 'ProtonCharge'.");

declareProperty("MinimumValue", 0.0, "Minimum log value for which to keep events.");
declareProperty("MinimumValue", Mantid::EMPTY_DBL(), "Minimum log value for which to keep events.");

declareProperty("MaximumValue", 0.0, "Maximum log value for which to keep events.");
declareProperty("MaximumValue", Mantid::EMPTY_DBL(), "Maximum log value for which to keep events.");

auto min = boost::make_shared<BoundedValidator<double> >();
min->setLower(0.0);
Expand All @@ -122,6 +123,35 @@ void FilterByLogValue::init()

}

std::map<std::string, std::string> FilterByLogValue::validateInputs()
{
std::map<std::string, std::string> errors;

// Check that the log exists for the given input workspace
EventWorkspace_const_sptr inputWS = this->getProperty("InputWorkspace");
std::string logname = getPropertyValue("LogName");
try {
ITimeSeriesProperty * log = dynamic_cast<ITimeSeriesProperty*>( inputWS->run().getLogData(logname) );
if ( log == NULL )
{
errors["LogName"] = "'" + logname + "' is not a time-series log.";
return errors;
}
} catch ( Exception::NotFoundError& ) {
errors["LogName"] = "The log '" + logname + "' does not exist in the workspace '" + inputWS->name() + "'.";
return errors;
}

const double min = getProperty("MinimumValue");
const double max = getProperty("MaximumValue");
if ( !isEmpty(min) && !isEmpty(max) && (max < min) )
{
errors["MinimumValue"] = "MinimumValue must not be larger than MaximumValue";
errors["MaximumValue"] = "MinimumValue must not be larger than MaximumValue";
}

return errors;
}

//-----------------------------------------------------------------------
/** Executes the algorithm
Expand Down Expand Up @@ -155,7 +185,7 @@ void FilterByLogValue::exec()
// Now make the splitter vector
TimeSplitterType splitter;
//This'll throw an exception if the log doesn't exist. That is good.
Kernel::ITimeSeriesProperty * log = dynamic_cast<Kernel::ITimeSeriesProperty*>( inputWS->run().getLogData(logname) );
ITimeSeriesProperty * log = dynamic_cast<ITimeSeriesProperty*>( inputWS->run().getLogData(logname) );
if (log)
{
if (PulseFilter)
Expand Down
67 changes: 65 additions & 2 deletions Code/Mantid/Framework/Algorithms/test/FilterByLogValueTest.h
Expand Up @@ -32,9 +32,8 @@ class FilterByLogValueTest : public CxxTest::TestSuite
static FilterByLogValueTest *createSuite() { return new FilterByLogValueTest(); }
static void destroySuite( FilterByLogValueTest *suite ) { delete suite; }

FilterByLogValueTest()
FilterByLogValueTest() : inputWS("eventWS")
{
inputWS = "eventWS";
}


Expand Down Expand Up @@ -113,7 +112,71 @@ class FilterByLogValueTest : public CxxTest::TestSuite
AnalysisDataService::Instance().remove(inputWS);
}

void test_validators()
{
FilterByLogValue alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() );

// InputWorkspace has to be an EventWorkspace
TS_ASSERT_THROWS( alg.setProperty("InputWorkspace", WorkspaceCreationHelper::Create2DWorkspace(1,1)), std::invalid_argument );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", WorkspaceCreationHelper::CreateEventWorkspace()) );

// LogName must not be empty
TS_ASSERT_THROWS( alg.setProperty("LogName",""), std::invalid_argument );

// TimeTolerance cannot be negative
TS_ASSERT_THROWS( alg.setProperty("TimeTolerance", -0.1), std::invalid_argument );
// ... but it can be zero
TS_ASSERT_THROWS_NOTHING( alg.setProperty("TimeTolerance", 0.0) );

// LogBoundary must be one of "Centre" and "Left"
TS_ASSERT_THROWS( alg.setProperty("LogBoundary", ""), std::invalid_argument );
TS_ASSERT_THROWS( alg.setProperty("LogBoundary", "Middle"), std::invalid_argument );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("LogBoundary", "Left") );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("LogBoundary", "Centre") );
}

void test_validateInputs()
{
// Create and event workspace. We don't care what data is in it.
EventWorkspace_sptr ws = WorkspaceCreationHelper::CreateEventWorkspace();
// Add a single-number log
ws->mutableRun().addProperty("SingleValue",5);
// Add a time-series property
auto tsp = new TimeSeriesProperty<double>("TSP");
tsp->addValue(DateAndTime::getCurrentTime(),9.9);
ws->mutableRun().addLogData(tsp);

FilterByLogValue alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace",ws) );

// Check protest when non-existent log is set
TS_ASSERT_THROWS_NOTHING( alg.setProperty("LogName", "NotThere") );
auto errorMap = alg.validateInputs();
TS_ASSERT_EQUALS( errorMap.size(), 1);
TS_ASSERT_EQUALS( errorMap.begin()->first, "LogName" );

// Check protest when single-value log is set
TS_ASSERT_THROWS_NOTHING( alg.setProperty("LogName", "SingleValue") );
errorMap = alg.validateInputs();
TS_ASSERT_EQUALS( errorMap.size(), 1);
TS_ASSERT_EQUALS( errorMap.begin()->first, "LogName" );

// Check protest when tsp log given, but min value greate than max
TS_ASSERT_THROWS_NOTHING( alg.setProperty("LogName", "TSP") );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("MinimumValue", 2.0) );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("MaximumValue", 1.0) );
errorMap = alg.validateInputs();
TS_ASSERT_EQUALS( errorMap.size(), 2);
TS_ASSERT_EQUALS( errorMap.begin()->first, "MaximumValue" );
TS_ASSERT_EQUALS( errorMap.rbegin()->first, "MinimumValue" );

// Check it's happy when that's been remedied
TS_ASSERT_THROWS_NOTHING( alg.setProperty("MaximumValue", 3.0) );
errorMap = alg.validateInputs();
TS_ASSERT( errorMap.empty() );
}

/** Create a workspace with:
* events at times 0,1,2,...99
Expand Down

0 comments on commit 86d622e

Please sign in to comment.