From 60562799dfb88c39ad915c9a516b28019642360a Mon Sep 17 00:00:00 2001
From: Wenduo Zhou <zhouw@ornl.gov>
Date: Fri, 27 Apr 2012 17:19:20 -0400
Subject: [PATCH] Continue to refactor events filtering. Refs #5056.

(1) Using GenerateEventsFilter() and FilterEvents() to refactor
FilterByTime.
(2) Clean the codes of GenerateEventsFilter and FilterEvents.
---
 .../Framework/Algorithms/CMakeLists.txt       |   5 +-
 .../inc/MantidAlgorithms/FilterByTime2.h      |  63 +++++++
 .../MantidAlgorithms/GenerateEventsFilter.h   |   1 -
 .../Algorithms/src/FilterByTime2.cpp          | 176 +++++++++++++++++
 .../Framework/Algorithms/src/FilterEvents.cpp |   4 +-
 .../Algorithms/src/GenerateEventsFilter.cpp   |  49 ++---
 .../Algorithms/test/FilterByTime2Test.h       | 178 ++++++++++++++++++
 7 files changed, 441 insertions(+), 35 deletions(-)
 create mode 100644 Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime2.h
 create mode 100644 Code/Mantid/Framework/Algorithms/src/FilterByTime2.cpp
 create mode 100644 Code/Mantid/Framework/Algorithms/test/FilterByTime2Test.h

diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt
index fdbfede482b..4b1840af276 100644
--- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt
+++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt
@@ -82,6 +82,7 @@ set ( SRC_FILES
 	src/FilterBadPulses.cpp
 	src/FilterByLogValue.cpp
 	src/FilterByTime.cpp
+	src/FilterByTime2.cpp
 	src/FilterEvents.cpp
 	src/FilterEventsHighFrequency.cpp
 	src/FindCenterOfMassPosition.cpp
@@ -277,6 +278,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/FilterBadPulses.h
 	inc/MantidAlgorithms/FilterByLogValue.h
 	inc/MantidAlgorithms/FilterByTime.h
+	inc/MantidAlgorithms/FilterByTime2.h
 	inc/MantidAlgorithms/FilterEvents.h
 	inc/MantidAlgorithms/FilterEventsHighFrequency.h
 	inc/MantidAlgorithms/FindCenterOfMassPosition.h
@@ -462,6 +464,7 @@ set ( TEST_FILES
 	test/FFTTest.h
 	test/FilterBadPulsesTest.h
 	test/FilterByLogValueTest.h
+	test/FilterByTime2Test.h
 	test/FilterByTimeTest.h
 	test/FilterEventsHighFrequencyTest.h
 	test/FilterEventsTest.h
@@ -539,8 +542,8 @@ set ( TEST_FILES
 	test/SmoothDataTest.h
 	test/SmoothNeighboursTest.h
 	test/SofQW2Test.h
+	test/SofQW3Test.h
 	test/SofQWTest.h
-  test/SofQW3Test.h
 	test/SolidAngleTest.h
 	test/SortEventsTest.h
 	test/SpatialGroupingTest.h
diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime2.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime2.h
new file mode 100644
index 00000000000..b9309a8d6b8
--- /dev/null
+++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime2.h
@@ -0,0 +1,63 @@
+#ifndef MANTID_ALGORITHMS_FILTERBYTIME2_H_
+#define MANTID_ALGORITHMS_FILTERBYTIME2_H_
+
+#include "MantidKernel/System.h"
+#include "MantidAPI/Algorithm.h"
+
+
+namespace Mantid
+{
+namespace Algorithms
+{
+
+  /** FilterByTime2 : TODO: DESCRIPTION
+    
+    @date 2012-04-25
+
+    Copyright &copy; 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 FilterByTime2 : public API::Algorithm
+  {
+  public:
+    FilterByTime2();
+    virtual ~FilterByTime2();
+
+    /// Algorithm's name for identification overriding a virtual method
+    virtual const std::string name() const { return "FilterByTime";};
+    /// Algorithm's version for identification overriding a virtual method
+    virtual int version() const { return 2;};
+    /// Algorithm's category for identification overriding a virtual method
+    virtual const std::string category() const { return "Events\\EventFiltering";}
+
+  private:
+    /// Sets documentation strings for this algorithm
+    virtual void initDocs();
+    // Implement abstract Algorithm methods
+    void init();
+    void exec();
+
+  };
+
+
+} // namespace Algorithms
+} // namespace Mantid
+
+#endif  /* MANTID_ALGORITHMS_FILTERBYTIME2_H_ */
diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
index 34131ce0543..937550c7223 100644
--- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
+++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
@@ -101,7 +101,6 @@ namespace Algorithms
     size_t searchValue(std::vector<double> dataranges, double value);
 
     DataObjects::EventWorkspace_const_sptr mEventWS;
-    // DataObjects::SplittersWorkspace_sptr mSplitters;
     API::ISplittersWorkspace_sptr mSplitters;
     API::ITableWorkspace_sptr mFilterInfoWS;
 
diff --git a/Code/Mantid/Framework/Algorithms/src/FilterByTime2.cpp b/Code/Mantid/Framework/Algorithms/src/FilterByTime2.cpp
new file mode 100644
index 00000000000..3f0d1456c95
--- /dev/null
+++ b/Code/Mantid/Framework/Algorithms/src/FilterByTime2.cpp
@@ -0,0 +1,176 @@
+#include "MantidAlgorithms/FilterByTime2.h"
+#include "MantidKernel/System.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidAPI/WorkspaceProperty.h"
+#include "MantidKernel/BoundedValidator.h"
+#include "MantidDataObjects/SplittersWorkspace.h"
+
+using namespace Mantid::Kernel;
+using namespace Mantid::API;
+
+namespace Mantid
+{
+namespace Algorithms
+{
+
+
+  //----------------------------------------------------------------------------------------------
+  /** Constructor
+   */
+  FilterByTime2::FilterByTime2()
+  {
+  }
+    
+  //----------------------------------------------------------------------------------------------
+  /** Destructor
+   */
+  FilterByTime2::~FilterByTime2()
+  {
+  }
+  
+  void FilterByTime2::initDocs()
+  {
+
+  }
+
+  //-----------------------------------------------------------------------
+  void FilterByTime2::init()
+  {
+    std::string commonHelp("\nYou can only specify the relative or absolute start/stop times, not both.");
+
+    declareProperty(
+      new WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace","",Direction::Input),
+      "An input event workspace" );
+
+    declareProperty(
+      new WorkspaceProperty<DataObjects::EventWorkspace>("OutputWorkspace","",Direction::Output),
+      "The name to use for the output workspace" );
+
+    auto min = boost::make_shared<BoundedValidator<double> >();
+    min->setLower(0.0);
+    declareProperty("StartTime", 0.0, min,
+        "The start time, in seconds, since the start of the run. Events before this time are filtered out. \nThe time of the first pulse (i.e. the first entry in the ProtonCharge sample log) is used as the zero. " + commonHelp);
+
+    declareProperty("StopTime", 0.0,
+        "The stop time, in seconds, since the start of the run. Events at or after this time are filtered out. \nThe time of the first pulse (i.e. the first entry in the ProtonCharge sample log) is used as the zero. " + commonHelp);
+
+    std::string absoluteHelp("Specify date and UTC time in ISO8601 format, e.g. 2010-09-14T04:20:12." + commonHelp);
+    declareProperty("AbsoluteStartTime", "",
+      "Absolute start time; events before this time are filtered out. " + absoluteHelp );
+
+    declareProperty("AbsoluteStopTime", "",
+      "Absolute stop time; events at of after this time are filtered out. " + absoluteHelp );
+
+  }
+
+  //-----------------------------------------------------------------------
+  /** Executes the algorithm
+   */
+  void FilterByTime2::exec()
+  {
+    DataObjects::EventWorkspace_const_sptr inWS = this->getProperty("InputWorkspace");
+    if (!inWS)
+    {
+      g_log.error() << "Input is not EventWorkspace" << std::endl;
+      throw std::invalid_argument("Input is not EventWorksapce");
+    }
+    else
+    {
+      g_log.debug() << "DB5244 InputWorkspace Name = " << inWS->getName() << std::endl;
+    }
+
+    double starttime = this->getProperty("StartTime");
+    double stoptime = this->getProperty("StopTime");
+    std::string absstarttime = this->getProperty("AbsoluteStartTime");
+    std::string absstoptime = this->getProperty("AbsoluteStopTime");
+
+    std::string start, stop;
+    if ( (absstarttime != "") && (absstoptime != "") && (starttime <= 0.0) && (stoptime <= 0.0) )
+    {
+      // Use the absolute string
+      start = absstarttime;
+      stop  = absstoptime;
+    }
+    else if ( (absstarttime != "" || absstoptime != "") && (starttime > 0.0 || stoptime > 0.0) )
+    {
+      throw std::invalid_argument("It is not allowed to provide both absolute time and relative time.");
+    }
+    else
+    {
+      // Use second
+      std::stringstream ss;
+      ss << starttime;
+      start = ss.str();
+      std::stringstream ss2;
+      ss2 << stoptime;
+      stop = ss2.str();
+    }
+
+    // 1. Generate Filters
+    g_log.debug() << "\nDB441: About to generate Filter.  StartTime = " << starttime <<
+        "  StopTime = " << stoptime << std::endl;
+
+    API::Algorithm_sptr genfilter = createSubAlgorithm("GenerateEventsFilter", 0.0, 20.0, true, 1);
+    genfilter->initialize();
+    genfilter->setPropertyValue("InputWorkspace", inWS->getName());
+    genfilter->setPropertyValue("OutputWorkspace", "FilterWS");
+    // genfilter->setPropertyValue("SplittersInformationWorkspace", "InfoWS");
+    genfilter->setProperty("StartTime", start);
+    genfilter->setProperty("StopTime", stop);
+    genfilter->setProperty("TimeType", "Seconds");
+
+    bool sucgen = genfilter->execute();
+    if (!sucgen)
+    {
+      g_log.error() << "Unable to generate event filters" << std::endl;
+      throw std::runtime_error("Unable to generate event filters");
+    }
+    else
+    {
+      g_log.debug() << "Filters are generated. " << std::endl;
+    }
+
+    DataObjects::SplittersWorkspace_sptr filterWS = genfilter->getProperty("OutputWorkspace");
+    if (!filterWS)
+    {
+      g_log.error() << "Unable to retrieve generated SplittersWorkspace object from AnalysisDataService." << std::endl;
+      throw std::runtime_error("Unable to retrieve Splittersworkspace. ");
+    }
+    // AnalysisDataService::Instance().addOrReplace("FilterWS", filterWS);
+
+    // 2. Filter events
+    g_log.debug() << "\nAbout to filter events. " << std::endl;
+
+    API::Algorithm_sptr filter = createSubAlgorithm("FilterEvents", 20.0, 100.0, true, 1);
+    filter->initialize();
+    filter->setPropertyValue("InputWorkspace", inWS->getName());
+    filter->setPropertyValue("OutputWorkspaceBaseName", "ResultWS");
+    // filter->setPropertyValue("InputSplittersWorkspace", "FilterWS");
+    filter->setProperty("InputSplittersWorkspace", filterWS);
+    filter->setProperty("FilterByPulseTime", true);
+
+    bool sucfilt = filter->execute();
+    if (!sucfilt)
+    {
+      g_log.error() << "Unable to filter events" << std::endl;
+      throw std::runtime_error("Unable to filter events");
+    }
+    else
+    {
+      g_log.debug() << "Filter events is successful. " << std::endl;
+    }
+
+    DataObjects::EventWorkspace_sptr optws = filter->getProperty("OutputWorkspace_0");
+
+    /*
+    DataObjects::EventWorkspace_sptr optws =
+        boost::dynamic_pointer_cast<DataObjects::EventWorkspace>(AnalysisDataService::Instance().retrieve("ResultWS_0"));
+     */
+
+    this->setProperty("OutputWorkspace", optws);
+
+  }
+
+
+} // namespace Mantid
+} // namespace Algorithms
diff --git a/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp b/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp
index 2c7a5e387b6..f20299c296d 100644
--- a/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp
+++ b/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp
@@ -142,7 +142,9 @@ namespace Algorithms
       this->declareProperty(new API::WorkspaceProperty<DataObjects::EventWorkspace>(parname.str(), wsname.str(), Direction::Output), "Output");
       this->setProperty(parname.str(), optws);
 
-      std::cout << "DB9141  Output Workspace:  Group = " << wsgroup << "  Property Name = " << wsname.str() << std::endl;
+      g_log.debug() << "DB9141  Output Workspace:  Group = " << wsgroup << "  Property Name = " << parname.str() <<
+          " Workspace name = " << wsname.str() <<
+          " with Number of events = " << optws->getNumberEvents() << std::endl;
     } // ENDFOR
 
 
diff --git a/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp b/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp
index 87f95df858b..669c52700e8 100644
--- a/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp
+++ b/Code/Mantid/Framework/Algorithms/src/GenerateEventsFilter.cpp
@@ -42,11 +42,11 @@ namespace Algorithms
 
     // 0. Input/Output Workspaces
     declareProperty(
-      new API::WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace", "Anonymous", Direction::InOut),
+      new API::WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace", "Anonymous", Direction::Input),
       "An input event workspace" );
 
     declareProperty(
-      new API::WorkspaceProperty<DataObjects::SplittersWorkspace>("OutputWorkspace", "", Direction::Output),
+      new API::WorkspaceProperty<DataObjects::SplittersWorkspace>("OutputWorkspace", "Splitters", Direction::Output),
       "The name to use for the output SplittersWorkspace object, i.e., the filter." );
 
     declareProperty(new API::WorkspaceProperty<API::ITableWorkspace>("SplittersInformationWorkspace", "SplitterInfo", Direction::Output),
@@ -124,8 +124,16 @@ namespace Algorithms
   {
     // 1. Get general input and output
     mEventWS = this->getProperty("InputWorkspace");
+    if (!mEventWS)
+    {
+      g_log.error() << "Error! GenerateEventsFilter does not get input EventWorkspace" << std::endl;
+      throw std::invalid_argument("Input workspace is not EventWorkspace.");
+    }
+
+    g_log.debug() << "DB9441 GenerateEventsFilter() Input Event WS = " << mEventWS->getName() << ", Events = "
+        << mEventWS->getNumberEvents() << std::endl;
     Kernel::DateAndTime runstart(mEventWS->run().getProperty("run_start")->value());
-    std::cout << "DB9441 Run Start = " << runstart << " / " << runstart.totalNanoseconds() << std::endl;
+    g_log.debug() << "DB9441 Run Start = " << runstart << " / " << runstart.totalNanoseconds() << std::endl;
 
 
     mSplitters =  boost::shared_ptr<DataObjects::SplittersWorkspace>(new DataObjects::SplittersWorkspace());
@@ -154,14 +162,6 @@ namespace Algorithms
       setFilterByLogValue(logname);
     }
 
-    /* FIXME Deletet this section before finalizing the code  *
-    for (size_t i = 0; i < mSplitters->getNumberSplitters(); ++i)
-    {
-      Kernel::SplittingInterval split = mSplitters->getSplitter(i);
-      std::cout << split.start().totalNanoseconds() << "\t\t" << split.stop().totalNanoseconds() << "\t\t" << split.index() << std::endl;
-    }
-    **********************************************************/
-
     this->setProperty("OutputWorkspace", mSplitters);
     this->setProperty("SplittersInformationWorkspace", mFilterInfoWS);
 
@@ -253,7 +253,7 @@ namespace Algorithms
       }
     }
 
-    std::cout << "DB8147 StartTime = " << mStartTime << ", StopTime = " << mStopTime << std::endl;
+    g_log.debug() << "DB8147 StartTime = " << mStartTime << ", StopTime = " << mStopTime << std::endl;
 
     return;
   }
@@ -324,13 +324,6 @@ namespace Algorithms
       throw std::invalid_argument("User specified log is not correct");
     }
 
-    /* FIXME  Delete This Section After Debugging
-    std::vector<Kernel::DateAndTime> times = mLog->timesAsVector();
-    std::vector<double> values = mLog->valuesAsVector();
-    for (size_t i = 0; i < times.size(); ++i)
-      std::cout << "DBOP " << times[i].totalNanoseconds() << "\t\t" << values[i] << std::endl;
-    **********************************************/
-
     double minValue = this->getProperty("MinimumLogValue");
     double maxValue = this->getProperty("MaximumLogValue");
     double deltaValue = this->getProperty("LogValueInterval");
@@ -454,14 +447,6 @@ namespace Algorithms
       ++index;
     } // ENDWHILE
 
-    /* FIXME Delete After Debugging *
-    for (size_t i = 0; i < valueranges.size(); ++i)
-    {
-      std::cout << "DBOP " << mlog->firstTime().totalNanoseconds() << "\t\t" << valueranges[i] << std::endl;
-      std::cout << "DBOP " << mlog->lastTime().totalNanoseconds() << "\t\t" << valueranges[i] << std::endl;
-    }
-    *********************************/
-
     // 3. Call
     Kernel::TimeSplitterType splitters;
     std::string logboundary = this->getProperty("LogBoundary");
@@ -727,7 +712,7 @@ namespace Algorithms
         if (correctdir)
         {
           size_t index = searchValue(valueranges, currValue);
-          std::cout << "DBOP Log Index " << i << " Data Range Index = " << index << "  WS Index = " << indexwsindexmap[index/2] << std::endl;
+          g_log.debug() << "DBOP Log Index " << i << " Data Range Index = " << index << "  WS Index = " << indexwsindexmap[index/2] << std::endl;
 
           if (index%2 == 0)
           {
@@ -766,17 +751,17 @@ namespace Algorithms
             }
 
             // c2) Fall out of interval
-            std::cout << "DBOP Log Index " << i << "  Falls Out b/c value range... " << std::endl;
+            g_log.debug() << "DBOP Log Index " << i << "  Falls Out b/c value range... " << std::endl;
           }
         } // ENDIF NO breakloop AND Correction Direction
         else
         {
-          std::cout << "DBOP Log Index " << i << " Falls out b/c out of wrong direction" << std::endl;
+          g_log.debug() << "DBOP Log Index " << i << " Falls out b/c out of wrong direction" << std::endl;
         }
       }
       else
       {
-        std::cout << "DBOP Log Index " << i << "  Falls Out b/c out of time range... " << std::endl;
+        g_log.debug() << "DBOP Log Index " << i << "  Falls Out b/c out of time range... " << std::endl;
       }
 
       // d) Create Splitter
@@ -790,7 +775,7 @@ namespace Algorithms
         {
           split.push_back( SplittingInterval(start, stop, lastindex) );
         }
-        std::cout << "DBOP ...  Add splitter " << split.size()-1 << ":  " << start.totalNanoseconds() << ", "
+        g_log.debug() << "DBOP ...  Add splitter " << split.size()-1 << ":  " << start.totalNanoseconds() << ", "
             << stop.totalNanoseconds() << " ... WSIndex = " << lastindex << std::endl;
 
         // reset
diff --git a/Code/Mantid/Framework/Algorithms/test/FilterByTime2Test.h b/Code/Mantid/Framework/Algorithms/test/FilterByTime2Test.h
new file mode 100644
index 00000000000..9946ffb339a
--- /dev/null
+++ b/Code/Mantid/Framework/Algorithms/test/FilterByTime2Test.h
@@ -0,0 +1,178 @@
+/*
+ * FilterByTimeTest.h
+ *
+ *  Created on: Sep 14, 2010
+ *      Author: janik
+ */
+
+#ifndef FILTERBYTIMETEST_H_
+#define FILTERBYTIMETEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAlgorithms/FilterByTime2.h"
+#include "MantidDataHandling/LoadEventPreNexus.h"
+#include "MantidKernel/DateAndTime.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include "MantidKernel/DateAndTime.h"
+
+using namespace Mantid::Algorithms;
+using namespace Mantid::DataHandling;
+using namespace Mantid::DataObjects;
+using namespace Mantid::Kernel;
+using namespace Mantid::API;
+
+class FilterByTime2Test : public CxxTest::TestSuite
+{
+public:
+  /** Setup for loading raw data */
+  void setUp_Event()
+  {
+    inputWS = "eventWS";
+    LoadEventPreNexus loader;
+    loader.initialize();
+    std::string eventfile( "CNCS_7860_neutron_event.dat" );
+    std::string pulsefile( "CNCS_7860_pulseid.dat" );
+    loader.setPropertyValue("EventFilename", eventfile);
+    loader.setPropertyValue("PulseidFilename", pulsefile);
+    loader.setPropertyValue("MappingFilename", "CNCS_TS_2008_08_18.dat");
+    loader.setPropertyValue("OutputWorkspace", inputWS);
+    loader.execute();
+    TS_ASSERT (loader.isExecuted() );
+
+  }
+
+
+  /*
+   * In this test, only a very simple event workspace is used
+   */
+  void NtestTooManyParams()
+  {
+    EventWorkspace_sptr ws = WorkspaceCreationHelper::CreateEventWorkspace(1,1);
+    AnalysisDataService::Instance().addOrReplace("eventWS", ws);
+
+    //Do the filtering now.
+    FilterByTime2 * alg = new FilterByTime2();
+    alg->initialize();
+    alg->setPropertyValue("InputWorkspace", "eventWS");
+    alg->setPropertyValue("OutputWorkspace", "out");
+    alg->setPropertyValue("StopTime", "120");
+    alg->setPropertyValue("AbsoluteStartTime", "2010");
+    alg->execute();
+    TS_ASSERT( !alg->isExecuted() );
+
+    alg = new FilterByTime2(); alg->initialize();
+    alg->setPropertyValue("InputWorkspace", "eventWS");
+    alg->setPropertyValue("OutputWorkspace", "out");
+    alg->setPropertyValue("StartTime", "60");
+    alg->setPropertyValue("StopTime", "120");
+    alg->setPropertyValue("AbsoluteStartTime", "2010");
+    alg->execute();
+    TS_ASSERT( !alg->isExecuted() );
+
+    alg = new FilterByTime2();
+    alg->initialize();
+    alg->setPropertyValue("InputWorkspace", "eventWS");
+    alg->setPropertyValue("OutputWorkspace", "out");
+    alg->setPropertyValue("StopTime", "120");
+    alg->setPropertyValue("AbsoluteStartTime", "2010");
+    alg->setPropertyValue("AbsoluteStopTime", "2010-03");
+    alg->execute();
+    TS_ASSERT( !alg->isExecuted() );
+
+    return;
+  }
+
+  void testExecEventWorkspace_relativeTime_and_absolute_time()
+  {
+    std::string outputWS;
+    this->setUp_Event();
+
+    //Retrieve Workspace
+    WS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(inputWS);
+    TS_ASSERT( WS ); //workspace is loaded
+
+    //Do the filtering now.
+    FilterByTime2 * alg = new FilterByTime2();
+    alg->initialize();
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("InputWorkspace", inputWS));
+    outputWS = "eventWS_relative";
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("OutputWorkspace", outputWS));
+    //Get 1 minute worth
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("StartTime", "60.46"));
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("StopTime", "120.46"));
+
+    alg->execute();
+    TS_ASSERT( alg->isExecuted() );
+
+    //Retrieve Workspace changed
+    EventWorkspace_sptr outWS;
+    outWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(outputWS);
+    TS_ASSERT( outWS ); //workspace is loaded
+
+    //Things that haven't changed
+    TS_ASSERT_EQUALS( outWS->blocksize(), WS->blocksize());
+    TS_ASSERT_EQUALS( outWS->getNumberHistograms(), WS->getNumberHistograms());
+    //Things that changed
+    TS_ASSERT_LESS_THAN( outWS->getNumberEvents(), WS->getNumberEvents() );
+
+    //Proton charge is lower
+    TS_ASSERT_LESS_THAN( outWS->run().getProtonCharge(), WS->run().getProtonCharge() );
+
+    //-------------- Absolute time filtering --------------------
+    alg = new FilterByTime2();
+    alg->initialize();
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("InputWorkspace", inputWS));
+    outputWS = "eventWS_absolute";
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("OutputWorkspace", outputWS));
+    //Get 1 minutes worth, starting at minute 1
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("AbsoluteStartTime", "2010-03-25T16:09:37.46"));
+    TS_ASSERT_THROWS_NOTHING(alg->setPropertyValue("AbsoluteStopTime", "2010-03-25T16:10:37.46"));
+    alg->execute();
+    TS_ASSERT( alg->isExecuted() );
+
+    EventWorkspace_sptr outWS2;
+    outWS2 = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(outputWS);
+    TS_ASSERT( outWS2 ); //workspace is loaded
+
+    //Things that haven't changed
+    TS_ASSERT_EQUALS( outWS2->blocksize(), WS->blocksize());
+    TS_ASSERT_EQUALS( outWS2->getNumberHistograms(), WS->getNumberHistograms());
+    //Things that changed
+    TS_ASSERT_LESS_THAN( outWS2->getNumberEvents(), WS->getNumberEvents() );
+    TS_ASSERT_LESS_THAN( outWS2->run().getProtonCharge(), WS->run().getProtonCharge() );
+
+    //------------------ Comparing both -----------------------
+    //Similar total number of events
+    TS_ASSERT_DELTA( outWS->getNumberEvents(), outWS2->getNumberEvents(), 10 );
+
+    int count = 0;
+    for (size_t i=0; i<outWS->getNumberHistograms(); i++)
+    {
+      double diff = fabs(double(outWS->getEventList(i).getNumberEvents() - outWS2->getEventList(i).getNumberEvents()));
+      //No more than 2 events difference because of rounding to 0.01 second
+      TS_ASSERT_LESS_THAN( diff, 3);
+      if (diff > 3) count++;
+      if (count > 50) break;
+    }
+
+    //Almost same proton charge
+    TS_ASSERT_DELTA( outWS->run().getProtonCharge(), outWS2->run().getProtonCharge(), 0.01 );
+
+
+  }
+
+
+
+private:
+  std::string inputWS;
+  EventWorkspace_sptr WS;
+
+
+};
+
+
+#endif /* FILTERBYTIMETEST_H_ */
+
+
-- 
GitLab