Skip to content

Commit

Permalink
Cherry-pick fixes from feature/9335_gen_filter_int_log into next
Browse files Browse the repository at this point in the history
Changes:

    Refs #9335.  Enabled to output vector splitter for integer log.

    A new unit test for the new feature is added as well.
    (cherry picked from commit 673223e)

    Refs #9335. Enabled to split with single log data range to matrix.

    A unit test related is added too.
    (cherry picked from commit d8ce3de)

    Re #9335. Fixed a bug in TimeSeriesProperty.
    (cherry picked from commit 80dba5a)
  • Loading branch information
wdzhou authored and martyngigg committed Aug 21, 2014
1 parent 67ee877 commit be4e572
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 29 deletions.
Expand Up @@ -94,9 +94,9 @@ namespace Algorithms
void processMultipleValueFilters(double minvalue, double valueinterval, double maxvalue,
bool filterincrease, bool filterdecrease);

void makeFilterByValue(Kernel::TimeSplitterType& split, double min, double max, double TimeTolerance, bool centre,
bool filterIncrease, bool filterDecrease, Kernel::DateAndTime startTime, Kernel::DateAndTime stopTime,
int wsindex);
void makeFilterBySingleValue(double min, double max, double TimeTolerance, bool centre,
bool filterIncrease, bool filterDecrease, Kernel::DateAndTime startTime, Kernel::DateAndTime stopTime,
int wsindex);

/// Make multiple-log-value filters in serial
void makeMultipleFiltersByValues(std::map<size_t, int> indexwsindexmap, std::vector<double> logvalueranges, bool centre,
Expand Down
78 changes: 56 additions & 22 deletions Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp
Expand Up @@ -454,9 +454,15 @@ namespace Algorithms

// Clear duplicate value
if (m_dblLog)
{
g_log.debug("Attempting to remove duplicates in double series log.");
m_dblLog->eliminateDuplicates();
}
else
{
g_log.debug("Attempting to remove duplicates in integer series log.");
m_intLog->eliminateDuplicates();
}

// Process input properties related to filter with log value
double minvalue = this->getProperty("MinimumLogValue");
Expand Down Expand Up @@ -523,6 +529,13 @@ namespace Algorithms
<< " is larger than maximum log value " << maxvalue;
throw runtime_error(errmsg.str());
}
else
{
g_log.debug() << "Filter by log value: min = " << minvalue << ", max = " << maxvalue
<< ", process single value? = " << toProcessSingleValueFilter
<< ", delta value = " << deltaValue << "\n";
}


// Filter double value log
if (toProcessSingleValueFilter)
Expand Down Expand Up @@ -567,15 +580,8 @@ namespace Algorithms

// Split along log
DateAndTime runendtime = m_dataWS->run().endTime();
processIntegerValueFilter(minvaluei, maxvaluei, filterIncrease, filterDecrease, runendtime);

if (m_forFastLog)
{
throw runtime_error("It is supported to generate FastLog for integer timeseries log yet. ");
}
else
{
processIntegerValueFilter(minvaluei, maxvaluei, filterIncrease, filterDecrease, runendtime);
}
} // ENDIFELSE: Double/Integer Log

g_log.information() << "Minimum value = " << minvalue << ", " << "maximum value = "
Expand All @@ -594,27 +600,40 @@ namespace Algorithms
void GenerateEventsFilter::processSingleValueFilter(double minvalue, double maxvalue,
bool filterincrease, bool filterdecrease)
{
// 1. Validity & value
// Get parameters time-tolerance and log-boundary
double timetolerance = this->getProperty("TimeTolerance");
int64_t timetolerance_ns = static_cast<int64_t>(timetolerance*m_timeUnitConvertFactorToNS);

std::string logboundary = this->getProperty("LogBoundary");
transform(logboundary.begin(), logboundary.end(), logboundary.begin(), ::tolower);

// 2. Generate filter
std::vector<Kernel::SplittingInterval> splitters;
// Generate filter
// std::vector<Kernel::SplittingInterval> splitters;
int wsindex = 0;
makeFilterBySingleValue(minvalue, maxvalue, static_cast<double>(timetolerance_ns)*1.0E-9,
logboundary.compare("centre")==0,
filterincrease, filterdecrease, m_startTime, m_stopTime, wsindex);


#if 0
makeFilterByValue(splitters, minvalue, maxvalue, static_cast<double>(timetolerance_ns)*1.0E-9,
logboundary.compare("centre")==0,
filterincrease, filterdecrease, m_startTime, m_stopTime, wsindex);
logboundary.compare("centre")==0,
filterincrease, filterdecrease, m_startTime, m_stopTime, wsindex);

// 3. Add to output
if (!m_splitWS)
throw std::runtime_error("m_splitWS has not been initialized yet.");

for (size_t isp = 0; isp < splitters.size(); isp ++)
{
m_splitWS->addSplitter(splitters[isp]);
}
#endif

// Create information table workspace
if (!m_filterInfoWS)
throw runtime_error("m_filterInfoWS has not been initialized.");

// 4. Add information
API::TableRow row = m_filterInfoWS->appendRow();
std::stringstream ss;
ss << "Log " << m_dblLog->name() << " From " << minvalue << " To " << maxvalue << " Value-change-direction ";
Expand Down Expand Up @@ -760,7 +779,7 @@ namespace Algorithms
* SINGLE log values >= min and < max. Creates SplittingInterval's where
* times match the log values, and going to index==0.
*
* @param split :: Splitter that will be filled.
*(removed) split :: Splitter that will be filled.
* @param min :: Min value.
* @param max :: Max value.
* @param TimeTolerance :: Offset added to times in seconds.
Expand All @@ -771,18 +790,22 @@ namespace Algorithms
* @param stopTime :: Stop time.
* @param wsindex :: Workspace index.
*/
void GenerateEventsFilter::makeFilterByValue(TimeSplitterType &split, double min, double max, double TimeTolerance,
bool centre, bool filterIncrease, bool filterDecrease,
DateAndTime startTime, Kernel::DateAndTime stopTime, int wsindex)
void GenerateEventsFilter::makeFilterBySingleValue(double min, double max, double TimeTolerance,
bool centre, bool filterIncrease, bool filterDecrease,
DateAndTime startTime, Kernel::DateAndTime stopTime, int wsindex)
{
// 1. Do nothing if the log is empty.
// Do nothing if the log is empty.
if (m_dblLog->size() == 0)
{
g_log.warning() << "There is no entry in this property " << this->name() << "\n";
return;
}

// 2. Do the rest
// Clear splitters in vector format
m_vecSplitterGroup.clear();
m_vecSplitterTime.clear();

// Initialize control parameters
bool lastGood = false;
bool isGood = false;;
time_duration tol = DateAndTime::durationFromSeconds( TimeTolerance );
Expand All @@ -791,6 +814,7 @@ namespace Algorithms
DateAndTime start, stop;

size_t progslot = 0;
string info("");

for (int i = 0; i < m_dblLog->size(); i ++)
{
Expand Down Expand Up @@ -850,7 +874,11 @@ namespace Algorithms
{
stop = t;
}
#if 0
split.push_back( SplittingInterval(start, stop, wsindex) );
#else
addNewTimeFilterSplitter(start, stop, wsindex, info);
#endif

//Reset the number of good ones, for next time
numgood = 0;
Expand All @@ -876,7 +904,10 @@ namespace Algorithms
stop = t - tol;
else
stop = t;
#if 0
split.push_back( SplittingInterval(start, stop, wsindex) );
#endif
addNewTimeFilterSplitter(start, stop, wsindex, info);
numgood = 0;
}

Expand Down Expand Up @@ -1606,8 +1637,11 @@ namespace Algorithms
}

// Information
API::TableRow row = m_filterInfoWS->appendRow();
row << wsindex << info;
if (info.size() > 0)
{
API::TableRow row = m_filterInfoWS->appendRow();
row << wsindex << info;
}

return;
}
Expand Down
112 changes: 108 additions & 4 deletions Code/Mantid/Framework/Algorithms/test/GenerateEventsFilterTest.h
Expand Up @@ -683,10 +683,9 @@ class GenerateEventsFilterTest : public CxxTest::TestSuite
AnalysisDataService::Instance().remove("InfoWS04B");
AnalysisDataService::Instance().remove("Splitters04C");
AnalysisDataService::Instance().remove("InfoWS04C");
}

// TS_ASSERT_EQUALS(1, 100);

}

//----------------------------------------------------------------------------------------------
/** Generate filter by log values in increasing
Expand All @@ -695,8 +694,6 @@ class GenerateEventsFilterTest : public CxxTest::TestSuite
*/
void test_genMultipleLogValuesFilterMatrixSplitterParallel()
{
std::cout << "\n==== Test Multiple Log Value Filter (Matrix Splitter Parallel) ====\n" << std::endl;

// Create input
DataObjects::EventWorkspace_sptr eventWS = createEventWorkspace();
AnalysisDataService::Instance().addOrReplace("TestEventWS04B", eventWS);
Expand Down Expand Up @@ -783,6 +780,113 @@ class GenerateEventsFilterTest : public CxxTest::TestSuite

}

//----------------------------------------------------------------------------------------------
/** Generate filter by log values in 'FastLog' mode only 1 interval
*/
void test_genSingleleLogValuesFilterMatrixSplitter()
{
std::cout << "\n==== Test Single Log Value Filter (Matrix Splitter) ====\n" << "\n";

// Create input
DataObjects::EventWorkspace_sptr eventWS = createEventWorkspace();
AnalysisDataService::Instance().addOrReplace("TestEventWS09", eventWS);

// Init and set property
GenerateEventsFilter alg;
alg.initialize();

TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", "TestEventWS09"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "Splitters09"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("InformationWorkspace", "InfoWS09"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("FastLog", true));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogName", "FastSineLog"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("MinimumLogValue", "-1.0"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("MaximumLogValue", "1.0"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogValueTolerance", 0.05));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("FilterLogValueByChangingDirection", "Both"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("TimeTolerance", 1.0E-8));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogBoundary", "Centre"));

// Running and get result
TS_ASSERT_THROWS_NOTHING(alg.execute());
TS_ASSERT(alg.isExecuted());

// Check output workspace
MatrixWorkspace_sptr splittersws =
boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("Splitters09"));
TS_ASSERT(splittersws);
if (splittersws)
TS_ASSERT(splittersws->readX(0).size() >= 2);

DataObjects::TableWorkspace_const_sptr infows =
boost::dynamic_pointer_cast<DataObjects::TableWorkspace>(AnalysisDataService::Instance().retrieve("InfoWS09"));
TS_ASSERT(infows);


// Clean
AnalysisDataService::Instance().remove("TestEventWS09");
AnalysisDataService::Instance().remove("Splitters09");
AnalysisDataService::Instance().remove("InfoWS09");
}


//----------------------------------------------------------------------------------------------
/** Generate filter by integer log values in increasing in matrix workspace
* (1) No time tolerance
* (2) Just one
*/
void test_genMultipleIntLogValuesFilterMatrixSplitter()
{
std::cout << "\n==== Test Multiple Integer Log Value Filter (Matrix Splitter) ====\n" << std::endl;

// Create input
DataObjects::EventWorkspace_sptr eventWS = createEventWorkspaceIntLog();
AnalysisDataService::Instance().addOrReplace("TestEventWS09", eventWS);

// Init and set property
GenerateEventsFilter alg;
alg.initialize();

TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", "TestEventWS09"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "Splitters09"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("InformationWorkspace", "InfoWS09"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("FastLog", true));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogName", "DummyIntLog"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("MinimumLogValue", static_cast<double>(1)));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("MaximumLogValue", static_cast<double>(10)));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogValueInterval", static_cast<double>(1)));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("UnitOfTime", "Seconds"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("FilterLogValueByChangingDirection", "Both"));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("TimeTolerance", 0.05));
TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogBoundary", "Centre"));

// Running and get result
TS_ASSERT_THROWS_NOTHING(alg.execute());
TS_ASSERT(alg.isExecuted());

// Check output workspace
MatrixWorkspace_sptr splittersws =
boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("Splitters09"));
TS_ASSERT(splittersws);

DataObjects::TableWorkspace_const_sptr infows =
boost::dynamic_pointer_cast<DataObjects::TableWorkspace>(AnalysisDataService::Instance().retrieve("InfoWS09"));
TS_ASSERT(infows);

if (!splittersws || !infows)
return;

TS_ASSERT_EQUALS(splittersws->readY(0).size(), 10);

int64_t factor = static_cast<int64_t>(1.0E9+0.5);
TS_ASSERT_DELTA(splittersws->readX(0)[0], static_cast<double>(11*factor-5*factor/100), 0.000001);

TS_ASSERT_DELTA(splittersws->readY(0)[0], 0.0, 0.00001);
TS_ASSERT_DELTA(splittersws->readY(0)[1], 1.0, 0.00001);

}


//----------------------------------------------------------------------------------------------
/** Convert the splitters stored in a matrix workspace to a vector of SplittingInterval objects
*/
Expand Down
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp
Expand Up @@ -1786,6 +1786,9 @@ namespace Mantid
++ vit;
}

// 2.5 Re-count values
countSize();

// 3. Finish
g_log.warning() << "Log " << this->name() << " has " << numremoved << " entries removed due to duplicated time. " << "\n";

Expand Down

0 comments on commit be4e572

Please sign in to comment.