Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
mantidproject
mantid
Commits
8504a86f
Commit
8504a86f
authored
Dec 07, 2015
by
Zhou, Wenduo
Browse files
Refs #14554. Implemented the new features along with change of doc.
parent
52e2587b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h
View file @
8504a86f
...
...
@@ -81,7 +81,7 @@ private:
void
exec
();
/// Process user input properties
void
processProperties
();
void
process
Algorithm
Properties
();
void
processSplittersWorkspace
();
...
...
@@ -171,6 +171,11 @@ private:
EVENTFILTERSKIP
m_specSkipType
;
/// Vector for skip information
std
::
vector
<
bool
>
m_vecSkip
;
// Flag to have relative time in splitters workspace
bool
m_isSplittersRelativeTime
;
// Starting time for starting time of event filters
Kernel
::
DateAndTime
m_filterStartTime
;
};
}
// namespace Algorithms
...
...
Framework/Algorithms/src/FilterEvents.cpp
View file @
8504a86f
...
...
@@ -43,7 +43,7 @@ FilterEvents::FilterEvents()
m_hasInfoWS
(),
m_progress
(
0.
),
m_outputWSNameBase
(),
m_toGroupWS
(
false
),
m_vecSplitterTime
(),
m_vecSplitterGroup
(),
m_splitSampleLogs
(
false
),
m_useDBSpectrum
(
false
),
m_dbWSIndex
(
-
1
),
m_tofCorrType
(),
m_specSkipType
(),
m_vecSkip
()
{}
m_specSkipType
(),
m_vecSkip
()
,
m_isSplittersRelativeTime
(
false
),
m_filterStartTime
(
0
)
{}
//----------------------------------------------------------------------------------------------
/** Destructor
...
...
@@ -142,6 +142,11 @@ void FilterEvents::init() {
new
ArrayProperty
<
string
>
(
"OutputWorkspaceNames"
,
Direction
::
Output
),
"List of output workspaces names"
);
declareProperty
(
"RelativeTime"
,
false
,
"Flag to indicate that in the input Matrix splitting workspace,"
"the time indicated by X-vector is relative to either run start time or some indicted time."
);
declareProperty
(
"FilterStartTime"
,
""
,
"Start time for splitters that can be parsed to DateAndTime."
);
return
;
}
...
...
@@ -150,7 +155,7 @@ void FilterEvents::init() {
*/
void
FilterEvents
::
exec
()
{
// Process algorithm properties
processProperties
();
process
Algorithm
Properties
();
// Examine workspace for detectors
examineEventWS
();
...
...
@@ -221,7 +226,7 @@ void FilterEvents::exec() {
//----------------------------------------------------------------------------------------------
/** Process input properties
*/
void
FilterEvents
::
processProperties
()
{
void
FilterEvents
::
process
Algorithm
Properties
()
{
m_eventWS
=
this
->
getProperty
(
"InputWorkspace"
);
if
(
!
m_eventWS
)
{
stringstream
errss
;
...
...
@@ -305,6 +310,35 @@ void FilterEvents::processProperties() {
else
m_useDBSpectrum
=
true
;
// Splitters are given relative time
m_isSplittersRelativeTime
=
getProperty
(
"RelativeTime"
);
if
(
m_isSplittersRelativeTime
)
{
// Using relative time
std
::
string
start_time_str
=
getProperty
(
"FilterStartTime"
);
if
(
start_time_str
.
size
()
>
0
)
{
// User specifies the filter starting time
Kernel
::
DateAndTime
temp_shift_time
(
start_time_str
);
m_filterStartTime
=
temp_shift_time
;
}
else
{
// Retrieve filter starting time from property run_start as default
if
(
m_eventWS
->
run
().
hasProperty
(
"run_start"
))
{
Kernel
::
DateAndTime
temp_shift_time
(
m_eventWS
->
run
().
getProperty
(
"run_start"
)
->
value
());
m_filterStartTime
=
temp_shift_time
;
}
else
{
throw
std
::
runtime_error
(
"Input event workspace does not have property run_start. "
"User does not specifiy filter start time."
"Splitters cannot be in reltive time."
);
}
}
}
return
;
}
...
...
@@ -372,8 +406,12 @@ void FilterEvents::examineEventWS() {
}
//----------------------------------------------------------------------------------------------
/** Convert SplitterWorkspace object to TimeSplitterType (sorted vector)
* and create a map for all workspace group number
/** Purpose:
* Convert SplitterWorkspace object to TimeSplitterType (sorted vector)
* and create a map for all workspace group number
* Requirements:
* Gaurantees
* @brief FilterEvents::processSplittersWorkspace
*/
void
FilterEvents
::
processSplittersWorkspace
()
{
// 1. Init data structure
...
...
@@ -416,15 +454,25 @@ void FilterEvents::processSplittersWorkspace() {
//----------------------------------------------------------------------------------------------
/**
*/
* @brief FilterEvents::processMatrixSplitterWorkspace
* Purpose:
* Convert the splitters in matrix workspace to a vector of splitters
* Requirements:
* m_matrixSplitterWS has valid value
* vecX's size must be one larger than and that of vecY of m_matrixSplitterWS
* Guarantees
* Splitters stored in m_matrixSpliterWS are transformed to
* m_vecSplitterTime and m_workGroupIndexes, which are of same size
*/
void
FilterEvents
::
processMatrixSplitterWorkspace
()
{
// Check input workspace validity
assert
(
m_matrixSplitterWS
);
const
MantidVec
&
vecX
=
m_matrixSplitterWS
->
readX
(
0
);
const
MantidVec
&
vecY
=
m_matrixSplitterWS
->
readY
(
0
);
size_t
sizex
=
vecX
.
size
();
size_t
sizey
=
vecY
.
size
();
if
(
sizex
-
sizey
!=
1
)
throw
runtime_error
(
"Size must be N and N-1."
);
assert
(
sizex
-
sizey
==
1
);
// Assign vectors for time comparison
m_vecSplitterTime
.
assign
(
vecX
.
size
(),
0
);
...
...
@@ -434,6 +482,14 @@ void FilterEvents::processMatrixSplitterWorkspace() {
for
(
size_t
i
=
0
;
i
<
sizex
;
++
i
)
{
m_vecSplitterTime
[
i
]
=
static_cast
<
int64_t
>
(
vecX
[
i
]);
}
// shift the splitters' time if applied
if
(
m_isSplittersRelativeTime
)
{
int64_t
time_shift_ns
=
m_filterStartTime
.
totalNanoseconds
();
for
(
size_t
i
=
0
;
i
<
sizex
;
++
i
)
m_vecSplitterTime
[
i
]
+=
time_shift_ns
;
}
for
(
size_t
i
=
0
;
i
<
sizey
;
++
i
)
{
m_vecSplitterGroup
[
i
]
=
static_cast
<
int
>
(
vecY
[
i
]);
m_workGroupIndexes
.
insert
(
m_vecSplitterGroup
[
i
]);
...
...
Framework/Algorithms/test/FilterEventsTest.h
View file @
8504a86f
...
...
@@ -538,7 +538,102 @@ public:
return
;
}
//----------------------------------------------------------------------------------------------
/** Filter events without any correction and test for splitters in MatrixWorkspace format
* and the time given for splitters is relative
* 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_FilterRelativeTime
()
{
// 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
(
"Test10"
,
inpWS
);
API
::
MatrixWorkspace_sptr
splws
=
createMatrixSplitter
(
0
,
pulsedt
,
tofdt
);
AnalysisDataService
::
Instance
().
addOrReplace
(
"Splitter10"
,
splws
);
FilterEvents
filter
;
filter
.
initialize
();
// Set properties
filter
.
setProperty
(
"InputWorkspace"
,
"Test10"
);
filter
.
setProperty
(
"OutputWorkspaceBaseName"
,
"FilteredWS10"
);
filter
.
setProperty
(
"SplitterWorkspace"
,
"Splitter10"
);
filter
.
setProperty
(
"RelativeTime"
,
true
);
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
(
"FilteredWS10_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
(
"FilteredWS10_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
(
"FilteredWS10_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"
);
std
::
vector
<
std
::
string
>
outputwsnames
=
filter
.
getProperty
(
"OutputWorkspaceNames"
);
for
(
size_t
i
=
0
;
i
<
outputwsnames
.
size
();
++
i
)
{
std
::
cout
<<
"Output workspace "
<<
i
<<
": "
<<
outputwsnames
[
i
]
<<
"
\n
"
;
AnalysisDataService
::
Instance
().
remove
(
outputwsnames
[
i
]);
}
return
;
}
//----------------------------------------------------------------------------------------------
/** Create an EventWorkspace. This workspace has
* @param runstart_i64 : absolute run start time in int64_t format with unit
...
...
@@ -791,6 +886,61 @@ public:
return
splitterws
;
}
//----------------------------------------------------------------------------------------------
/** Create a Splitter for output
* Region:
* 0: pulse 0: 0 ~ 3+
* 1: pulse 0: 3+ ~ pulse 1: 9+
* 2: from pulse 2: 0 ~ 6+
* -1: from pulse 2: 6+ ~ 9+
* @brief createMatrixSplitter
* @param runstart_i64 : absolute run start time in int64_t format with unit nanosecond
* @param pulsedt: pulse length in int64_t format with unit nanosecond
* @param tofdt: time interval between 2 adjacent event in same pulse in
* int64_t format of unit nanosecond
* @return
*/
API
::
MatrixWorkspace_sptr
createMatrixSplitter
(
int64_t
runstart_i64
,
int64_t
pulsedt
,
int64_t
tofdt
)
{
// Create vectors for the splitters
std
::
vector
<
int64_t
>
time_vec
;
std
::
vector
<
int
>
index_vec
;
time_vec
.
push_back
(
runstart_i64
);
// Splitter 0: 0 ~ 3+ (first pulse)
int64_t
t1
=
runstart_i64
+
tofdt
*
3
+
tofdt
/
2
;
time_vec
.
push_back
(
t1
);
index_vec
.
push_back
(
0
);
// Splitter 1: 3+ ~ 9+ (second pulse)
int64_t
t2
=
runstart_i64
+
pulsedt
+
tofdt
*
9
+
tofdt
/
2
;
time_vec
.
push_back
(
t2
);
index_vec
.
push_back
(
1
);
// Splitter 2 and so on: from 3rd pulse, 0 ~ 6+
for
(
size_t
i
=
2
;
i
<
5
;
i
++
)
{
int64_t
newT
=
runstart_i64
+
i
*
pulsedt
+
6
*
tofdt
+
tofdt
/
2
;
time_vec
.
push_back
(
newT
);
index_vec
.
push_back
(
2
);
}
// Create the workspace and set it
size_t
size_x
=
time_vec
.
size
();
size_t
size_y
=
index_vec
.
size
();
TS_ASSERT
(
size_x
-
size_y
==
1
);
MatrixWorkspace_sptr
splitterws
=
boost
::
dynamic_pointer_cast
<
MatrixWorkspace
>
(
WorkspaceFactory
::
Instance
().
create
(
"Workspace2D"
,
1
,
size_x
,
size_y
));
for
(
size_t
ix
=
0
;
ix
<
size_x
;
++
ix
)
splitterws
->
dataX
(
0
)[
ix
]
=
static_cast
<
double
>
(
time_vec
[
ix
]);
for
(
size_t
iy
=
0
;
iy
<
size_y
;
++
iy
)
splitterws
->
dataY
(
0
)[
iy
]
=
static_cast
<
double
>
(
index_vec
[
iy
]);
return
splitterws
;
}
//----------------------------------------------------------------------------------------------
/** Create a Splitter for fast fequency log for output
* The splitter is within every pulse. 2 groups of splitters are created.
...
...
docs/source/algorithms/FilterEvents-v1.rst
View file @
8504a86f
...
...
@@ -15,8 +15,31 @@ This algorithm filters events from an
`SplittersWorkspace <http://www.mantidproject.org/SplittersWorkspace>`_ containing a series of
splitters (i.e., `SplittingIntervals <http://www.mantidproject.org/SplittingInterval>`_).
Out
put
In
put
s
######
Algorithm *FilterEvents* takes 2 mandatory input Workspaces and 1 optional Workspace.
One of mandatory workspace is the EventWorkspace where the events are filtered from.
The other mandatory workspace is workspace containing splitters.
It can be either a MatrixWorkspace or a SplittersWorkspace.
The optional workspace is a TableWorkspace for information of splitters.
Algorithm *GenerateEventsFilter* creates both the splitters' workspace and splitter information workspace.
Splitters in relative time
==========================
As the splitters' workspace is in format of MatrixWorkspace,
its time, i.e., the value in X vector, can be relative time.
Property *RelativeTime* flags that the splitters' time is relative.
Property *FilterStartTime* specifies the starting time of the filter.
Or the shift of time of the splitters.
If it is not specified, then the algorithm will search for sample log *run_start*.
Outputs
#######
The output will be one or multiple workspaces according to the number of
index in splitters. The output workspace name is the combination of
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment