diff --git a/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp b/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp index a9fd59dc4cef0ba82b08e425a234f6b583ec24fd..d131dfc22a75f848ec52e586fff113a0d13903f4 100644 --- a/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp +++ b/Code/Mantid/Framework/Algorithms/src/FilterEvents.cpp @@ -57,8 +57,8 @@ namespace Algorithms } void FilterEvents::initDocs() - { - + { + setWikiSummary("Filter events from an [[EventWorkspace]] to one or multiple [[EventWorkspace]]s according to a series of splitters."); } //---------------------------------------------------------------------------------------------- @@ -66,8 +66,6 @@ namespace Algorithms */ void FilterEvents::init() { - this->setWikiSummary("Filter events from an [[EventWorkspace]] to one or multiple [[EventWorkspace]]s according to a series of splitters."); - declareProperty( new API::WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace","",Direction::Input), "An input event workspace" ); @@ -91,6 +89,10 @@ namespace Algorithms this->declareProperty("GroupWorkspaces", false, "Option to group all the output workspaces. Group name will be OutputWorkspaceBaseName."); + declareProperty("OutputWorkspaceIndexedFrom1", false, "If selected, the minimum output workspace is indexed from 1 and continuous. "); + + declareProperty("NumberOutputWS", 0, "Number of output output workspace splitted. ", Direction::Output); + return; } @@ -246,26 +248,48 @@ namespace Algorithms } } + // Determine the minimum group index number + int minwsgroup = INT_MAX; + for (set<int>::iterator groupit = m_workGroupIndexes.begin(); groupit != m_workGroupIndexes.end(); ++groupit) + { + int wsgroup = *groupit; + if (wsgroup < minwsgroup && wsgroup >= 0) + minwsgroup = wsgroup; + } + g_log.debug() << "[DB] Min WS Group = " << minwsgroup << "\n"; + + bool from1 = getProperty("OutputWorkspaceIndexedFrom1"); + int delta_wsindex = 0; + if (from1) + { + delta_wsindex = 1-minwsgroup; + } + // Set up new workspaces std::set<int>::iterator groupit; + int numoutputws = 0; for (groupit = m_workGroupIndexes.begin(); groupit != m_workGroupIndexes.end(); ++groupit) { - // 1. Get workspace name + // Generate new workspace name + bool add2output = true; int wsgroup = *groupit; std::stringstream wsname; if (wsgroup >= 0) - wsname << outputwsnamebase << "_" << wsgroup; + wsname << outputwsnamebase << "_" << (wsgroup+delta_wsindex); else + { wsname << outputwsnamebase << "_unfiltered"; - std::stringstream parname; - parname << "OutputWorkspace_" << wsgroup; + if (from1) + add2output = false; + } - // 2. Generate one of the output workspaces & Copy geometry over. But we don't copy the data. + // Generate one of the output workspaces & Copy geometry over. But we don't copy the data. DataObjects::EventWorkspace_sptr optws = boost::dynamic_pointer_cast<DataObjects::EventWorkspace>( - API::WorkspaceFactory::Instance().create("EventWorkspace", m_eventWS->getNumberHistograms(), 2, 1)); + API::WorkspaceFactory::Instance().create("EventWorkspace", m_eventWS->getNumberHistograms(), 2, 1)); API::WorkspaceFactory::Instance().initializeFromParent(m_eventWS, optws, false); + m_outputWS.insert(std::make_pair(wsgroup, optws)); - // Add information + // Add information, including title and comment, to output workspace if (mWithInfo) { std::string info; @@ -290,21 +314,31 @@ namespace Algorithms optws->setTitle(info); } - // 3. Set to map - m_outputWS.insert(std::make_pair(wsgroup, optws)); + // Add to output properties. There shouldn't be any workspace (non-unfiltered) skipped from group index + if (add2output) + { + // Generate output property name + std::stringstream propertyname; + propertyname << "OutputWorkspace_" << wsgroup; + + // Inserted this pair to map + m_wsNames.push_back(wsname.str()); - // 4. Set to output workspace - this->declareProperty(new API::WorkspaceProperty<DataObjects::EventWorkspace>( - parname.str(), wsname.str(), Direction::Output), "Output"); - this->setProperty(parname.str(), optws); - m_wsNames.push_back(wsname.str()); - AnalysisDataService::Instance().addOrReplace(wsname.str(), optws); + // Set (property) to output workspace and set to ADS + declareProperty(new API::WorkspaceProperty<DataObjects::EventWorkspace>( + propertyname.str(), wsname.str(), Direction::Output), "Output"); + setProperty(propertyname.str(), optws); + AnalysisDataService::Instance().addOrReplace(wsname.str(), optws); - g_log.debug() << "DB9141 Output Workspace: Group = " << wsgroup << " Property Name = " << parname.str() << - " Workspace name = " << wsname.str() << - " with Number of events = " << optws->getNumberEvents() << std::endl; + ++ numoutputws; + + g_log.debug() << "DB9141 Output Workspace: Group = " << wsgroup << " Property Name = " << propertyname.str() << + " Workspace name = " << wsname.str() << + " with Number of events = " << optws->getNumberEvents() << std::endl; + } } // ENDFOR + setProperty("NumberOutputWS", numoutputws); return; } @@ -419,7 +453,7 @@ namespace Algorithms std::map<int, DataObjects::EventWorkspace_sptr>::iterator wsiter; // Loop over the histograms (detector spectra) to do split from 1 event list to N event list - g_log.information() << "[FilterEvents F1206] Number of spectra = " << numberOfSpectra << ".\n"; + g_log.debug() << "Number of spectra in input/source EventWorkspace = " << numberOfSpectra << ".\n"; // FIXME Make it parallel // PARALLEL_FOR_NO_WSP_CHECK() diff --git a/Code/Mantid/Framework/Algorithms/test/FilterEventsTest.h b/Code/Mantid/Framework/Algorithms/test/FilterEventsTest.h index c931c26c4df58da9e30e3213f2684f4d7c69306b..917b7da14d0bb8c2dbdde728f802bbc6700ddc82 100644 --- a/Code/Mantid/Framework/Algorithms/test/FilterEventsTest.h +++ b/Code/Mantid/Framework/Algorithms/test/FilterEventsTest.h @@ -117,6 +117,9 @@ public: TS_ASSERT(filter.isExecuted()); // 4. Get output + int numsplittedws = filter.getProperty("NumberOutputWS"); + TS_ASSERT_EQUALS(numsplittedws, 4); + // 4.1 Workspace group 0 DataObjects::EventWorkspace_sptr filteredws0 = boost::dynamic_pointer_cast <DataObjects::EventWorkspace>(AnalysisDataService::Instance().retrieve("FilteredWS01_0")); @@ -150,6 +153,7 @@ public: // 5. Clean up AnalysisDataService::Instance().remove("Test02"); AnalysisDataService::Instance().remove("Splitter02"); + AnalysisDataService::Instance().remove("FilteredWS01_unfiltered"); AnalysisDataService::Instance().remove("FilteredWS01_0"); AnalysisDataService::Instance().remove("FilteredWS01_1"); AnalysisDataService::Instance().remove("FilteredWS01_2"); @@ -157,6 +161,90 @@ public: return; } + //---------------------------------------------------------------------------------------------- + /** Filter events without any correction and test for user-specified workspace starting value + * Event workspace: + * (1) 10 detectors + * (2) Run starts @ 20000000000 seconds + * (3) Pulse length = 100*1000*1000 seconds + * (4) Within one pulse, two consecutive events/neutrons is apart for 10*1000*1000 seconds + * (5) "Experiment": 5 pulse times. 10 events in each pulse + * + * In this test + * (1) Leave correction table workspace empty + * (2) Count events in each output including "-1", the excluded/unselected events + */ + void test_FilterWOCorrection2() + { + // Create EventWorkspace and SplittersWorkspace + int64_t runstart_i64 = 20000000000; + int64_t pulsedt = 100*1000*1000; + int64_t tofdt = 10*1000*1000; + size_t numpulses = 5; + + DataObjects::EventWorkspace_sptr inpWS = createEventWorkspace(runstart_i64, pulsedt, tofdt, numpulses); + AnalysisDataService::Instance().addOrReplace("Test02", inpWS); + + DataObjects::SplittersWorkspace_sptr splws = createSplitter(runstart_i64, pulsedt, tofdt); + AnalysisDataService::Instance().addOrReplace("Splitter02", splws); + + FilterEvents filter; + filter.initialize(); + + // Set properties + filter.setProperty("InputWorkspace", "Test02"); + filter.setProperty("OutputWorkspaceBaseName", "FilteredWS01"); + filter.setProperty("SplitterWorkspace", "Splitter02"); + filter.setProperty("OutputWorkspaceIndexedFrom1", true); + + // Execute + TS_ASSERT_THROWS_NOTHING(filter.execute()); + TS_ASSERT(filter.isExecuted()); + + // Get output + int numsplittedws = filter.getProperty("NumberOutputWS"); + TS_ASSERT_EQUALS(numsplittedws, 3); + + // 4.1 Workspace group 0 + DataObjects::EventWorkspace_sptr filteredws0 = boost::dynamic_pointer_cast + <DataObjects::EventWorkspace>(AnalysisDataService::Instance().retrieve("FilteredWS01_1")); + TS_ASSERT(filteredws0); + TS_ASSERT_EQUALS(filteredws0->getNumberHistograms(), 10); + TS_ASSERT_EQUALS(filteredws0->getEventList(0).getNumberEvents(), 4); + + // 4.2 Workspace group 1 + DataObjects::EventWorkspace_sptr filteredws1 = boost::dynamic_pointer_cast + <DataObjects::EventWorkspace>(AnalysisDataService::Instance().retrieve("FilteredWS01_2")); + TS_ASSERT(filteredws1); + TS_ASSERT_EQUALS(filteredws1->getEventList(1).getNumberEvents(), 16); + + // 4.3 Workspace group 2 + DataObjects::EventWorkspace_sptr filteredws2 = boost::dynamic_pointer_cast + <DataObjects::EventWorkspace>(AnalysisDataService::Instance().retrieve("FilteredWS01_3")); + TS_ASSERT(filteredws2); + TS_ASSERT_EQUALS(filteredws2->getEventList(1).getNumberEvents(), 21); + + DataObjects::EventList elist3 = filteredws2->getEventList(3); + elist3.sortPulseTimeTOF(); + + DataObjects::TofEvent eventmin = elist3.getEvent(0); + TS_ASSERT_EQUALS(eventmin.pulseTime().totalNanoseconds(), runstart_i64+pulsedt*2); + TS_ASSERT_DELTA(eventmin.tof(), 0, 1.0E-4); + + DataObjects::TofEvent eventmax = elist3.getEvent(20); + TS_ASSERT_EQUALS(eventmax.pulseTime().totalNanoseconds(), runstart_i64+pulsedt*4); + TS_ASSERT_DELTA(eventmax.tof(), static_cast<double>(tofdt*6/1000), 1.0E-4); + + // 5. Clean up + AnalysisDataService::Instance().remove("Test02"); + AnalysisDataService::Instance().remove("Splitter02"); + AnalysisDataService::Instance().remove("FilteredWS01_1"); + AnalysisDataService::Instance().remove("FilteredWS01_2"); + AnalysisDataService::Instance().remove("FilteredWS01_3"); + + return; + } + //---------------------------------------------------------------------------------------------- /** Filter test with TOF correction */