FilterEvents-v1.rst 11.6 KB
Newer Older
1
2
3
4
.. algorithm::

.. summary::

5
.. relatedalgorithms::
6
7
8
9
10
11

.. properties::

Description
-----------

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
This algorithm filters events from a single :ref:`EventWorkspace` to
one or multiple :ref:`EventWorkspaces <EventWorkspace>` according to
the ``SplittersWorkspace`` property. The :ref:`EventFiltering` concept
page has a detailed introduction to event filtering.

Specifying the splitting strategy
---------------------------------

The ``SplittersWorkspace`` describes much of the information for
splitting the ``InputWorkspace`` into the various output
workspaces. It can have one of three types

+--------------------------------------------------------------+-------------+----------+
| workspace class                                              | units       | rel/abs  |
+==============================================================+=============+==========+
| :ref:`MatrixWorkspace <MatrixWorkspace>`                     | seconds     | either   |
+--------------------------------------------------------------+-------------+----------+
| :class:`SplittersWorkspace <mantid.api.ISplittersWorkspace>` | nanoseconds | absolute |
+--------------------------------------------------------------+-------------+----------+
| :ref:`TableWorkspace <Table Workspaces>`                     | seconds     | either   |
+--------------------------------------------------------------+-------------+----------+

Whether the values in :ref:`MatrixWorkspace <MatrixWorkspace>` and
:ref:`TableWorkspace <Table Workspaces>` is treated as relative or
absolute time is dependent on the value of ``RelativeTime``. In the
case of ``RelativeTime=True``, the time is relative to the start of
the run (in the ``ws.run()['run_start']``) or, if specified, the
``FilterStartTime``. In the case of ``RelativeTime=False``, the times
are relative to the :class:`GPS epoch <mantid.kernel.DateAndTime>`.

Both :ref:`TableWorkspace <Table Workspaces>` and
:class:`SplittersWorkspace <mantid.api.ISplittersWorkspace>` have 3
44
columns, ``start``, ``stop``, and ``target`` which should be a float,
45
46
47
48
49
50
51
52
53
54
float, and string. The :ref:`event filtering <EventFiltering>` concept
page has details on creating the :ref:`TableWorkspace <Table
Workspaces>` by hand.

If the ``SplittersWorkspace`` is a :ref:`MatrixWorkspace
<MatrixWorkspace>`, it must have a single spectrum with the x-value is
the time boundaries and the y-value is the workspace group index.

The optional ``InformationWorkspace`` is a :ref:`TableWorkspace <Table
Workspaces>` for information of splitters.
55
56

Unfiltered Events
57
-----------------
58
59

Some events are not inside any splitters. They are put to a workspace
60
61
62
name ended with ``_unfiltered``. If
``OutputWorkspaceIndexedFrom1=True``, then this workspace will not be
created.
63

Mathieu Doucet's avatar
Mathieu Doucet committed
64
Using FilterEvents with fast-changing logs
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
------------------------------------------

There are a few parameters to consider when the log filtering is
expected to produce a large splitter table. An example of such a case
would be a data file for which the events need to be split according
to a log with two or more states changing in the kHz range. To reduce
the filtering time, one may do the following:

- Make sure the ``SplitterWorkspace`` input is a :ref:`MatrixWorkspace
  <MatrixWorkspace>`. Such a workspace can be produced by using the
  ``FastLog = True`` option when calling :ref:`GenerateEventsFilter
  <algm-GenerateEventsFilter>`.
- Choose the logs to split. Filtering the logs can take a substantial
  amount of time. To save time, you may want to split only the logs
  you will need for analysis. To do so, set ``ExcludeSpecifiedLogs =
  False`` and list the logs you need in
  ``TimeSeriesPropertyLogs``. For example, if we only need to know the
  accumulated proton charge for each filtered workspace, we would set
  ``TimeSeriesPropertyLogs = proton_charge``.

Correcting time neutron was at the sample
#########################################

When filtering fast logs, the time to filter by is the time that the
neutron was at the sample. This can be specified using the
``CorrectionToSample`` parameter. Either the user specifies the
correction parameter for every pixel, or one is calculated. The
correction parameters are applied as

.. math::

   TOF_{sample} = TOF_{detector} * scale[detectorID] + shift[detectorID]

and stored in the ``OutputTOFCorrectionWorkspace``.

* ``CorrectionToSample="None"`` applies no correction
* ``CorrectionToSample="Elastic"`` applies :math:`shift = 0` with
  :math:`scale = L1/(L1+L2)` for detectors and :math:`scale = L1/L_{monitor}`
  for monitors
* ``CorrectionToSample="Direct"`` applies :math:`scale = 0` and
  :math:`shift = L1 / \sqrt{2 E_{fix} / m_n}`.  The value supplied in
  ``IncidentEnergy`` will override the value found in the workspace's
  value of ``Ei``.
* ``CorrectionToSample="Indirect"`` applies :math:`scale = 1` and
  :math:`shift = -1 * L2 / \sqrt{2 E_{fix} / m_n}` for detectors. For
  monitors, uses the same corrections as ``Elastic``.

* ``CorrectionToSample="Customized"`` applies the correction supplied
  in the ``DetectorTOFCorrectionWorkspace``.
Mathieu Doucet's avatar
Mathieu Doucet committed
114
115


116
Difference from FilterByLogValue
117
118
119
120
121
122
123
124
125
--------------------------------

In :ref:`FilterByLogValue <algm-FilterByLogValue>`,
``EventList.splitByTime()`` is used. In FilterEvents, it only uses
this when ``FilterByPulse=True``. Otherwise,
``EventList.splitByFullTime()`` is used. The difference between
``splitByTime`` and ``splitByFullTime`` is that ``splitByTime``
filters events by pulse time, and ``splitByFullTime`` considers both
pulse time and TOF.
126

Zhou, Wenduo's avatar
Zhou, Wenduo committed
127
128
129
Usage
-----

130
**Example - Filtering event without correction on TOF**
Zhou, Wenduo's avatar
Zhou, Wenduo committed
131
132
133
134

.. testcode:: FilterEventNoCorrection

    ws = Load(Filename='CNCS_7860_event.nxs')
135
    splitws, infows = GenerateEventsFilter(InputWorkspace=ws, UnitOfTime='Nanoseconds', LogName='SampleTemp',
Zhou, Wenduo's avatar
Zhou, Wenduo committed
136
            MinimumLogValue=279.9,  MaximumLogValue=279.98, LogValueInterval=0.01)
137

Zhou, Wenduo's avatar
Zhou, Wenduo committed
138
    FilterEvents(InputWorkspace=ws, SplitterWorkspace=splitws, InformationWorkspace=infows,
139
            OutputWorkspaceBaseName='tempsplitws',  GroupWorkspaces=True,
Zhou, Wenduo's avatar
Zhou, Wenduo committed
140
141
142
            FilterByPulseTime = False, OutputWorkspaceIndexedFrom1 = False,
            CorrectionToSample = "None", SpectrumWithoutDetector = "Skip", SplitSampleLogs = False,
            OutputTOFCorrectionWorkspace='mock')
143

Zhou, Wenduo's avatar
Zhou, Wenduo committed
144
145
146
    # Print result
    wsgroup = mtd["tempsplitws"]
    wsnames = wsgroup.getNames()
147
    for name in sorted(wsnames):
Zhou, Wenduo's avatar
Zhou, Wenduo committed
148
        tmpws = mtd[name]
149
        print("workspace %s has %d events" % (name, tmpws.getNumberEvents()))
Zhou, Wenduo's avatar
Zhou, Wenduo committed
150
151
152
153
154
155
156
157
158
159
160
161
162
163


Output:

.. testoutput:: FilterEventNoCorrection

    workspace tempsplitws_0 has 124 events
    workspace tempsplitws_1 has 16915 events
    workspace tempsplitws_2 has 10009 events
    workspace tempsplitws_3 has 6962 events
    workspace tempsplitws_4 has 22520 events
    workspace tempsplitws_5 has 5133 events
    workspace tempsplitws_unfiltered has 50603 events

164
165
166
167
**Example - Filtering event by a user-generated TableWorkspace**

.. testcode:: FilterEventNoCorrection

Peterson, Peter's avatar
Peterson, Peter committed
168
    import numpy as np
169
170
171
172
173
174
175
176
177
178
179
180
181
    ws = Load(Filename='CNCS_7860_event.nxs')

    # create TableWorkspace
    split_table_ws = CreateEmptyTableWorkspace()
    split_table_ws.addColumn('float', 'start')
    split_table_ws.addColumn('float', 'stop')
    split_table_ws.addColumn('str', 'target')

    split_table_ws.addRow([0., 100., 'a'])
    split_table_ws.addRow([200., 300., 'b'])
    split_table_ws.addRow([400., 600., 'c'])
    split_table_ws.addRow([600., 650., 'b'])

182
    # filter events
183
184
185
186
    FilterEvents(InputWorkspace=ws, SplitterWorkspace=split_table_ws,
            OutputWorkspaceBaseName='tempsplitws3',  GroupWorkspaces=True,
            FilterByPulseTime = False, OutputWorkspaceIndexedFrom1 = False,
            CorrectionToSample = "None", SpectrumWithoutDetector = "Skip", SplitSampleLogs = False,
187
188
            OutputTOFCorrectionWorkspace='mock',
            RelativeTime=True)
189
190
191
192
193
194

    # Print result
    wsgroup = mtd["tempsplitws3"]
    wsnames = wsgroup.getNames()
    for name in sorted(wsnames):
        tmpws = mtd[name]
195
        print("workspace %s has %d events" % (name, tmpws.getNumberEvents()))
196
        split_log = tmpws.run().getProperty('splitter')
197
198
199
        entry_0 = np.datetime_as_string(split_log.times[0].astype(np.dtype('M8[s]')), timezone='UTC')
        entry_1 = np.datetime_as_string(split_log.times[1].astype(np.dtype('M8[s]')), timezone='UTC')
        print('event splitter log: entry 0 and entry 1 are {0} and {1}.'.format(entry_0, entry_1))
200
201
202
203
204
205


Output:

.. testoutput:: FilterEventNoCorrection

206
    workspace tempsplitws3_a has 77580 events
207
    event splitter log: entry 0 and entry 1 are 2010-03-25T16:08:37Z and 2010-03-25T16:10:17Z.
208
    workspace tempsplitws3_b has 0 events
209
    event splitter log: entry 0 and entry 1 are 2010-03-25T16:08:37Z and 2010-03-25T16:11:57Z.
210
    workspace tempsplitws3_c has 0 events
211
    event splitter log: entry 0 and entry 1 are 2010-03-25T16:08:37Z and 2010-03-25T16:15:17Z.
212
    workspace tempsplitws3_unfiltered has 34686 events
213
    event splitter log: entry 0 and entry 1 are 2010-03-25T16:08:37Z and 2010-03-25T16:10:17Z.
214

Zhou, Wenduo's avatar
Zhou, Wenduo committed
215

216
**Example - Filtering event by pulse time**
Zhou, Wenduo's avatar
Zhou, Wenduo committed
217
218
219
220

.. testcode:: FilterEventByPulseTime

    ws = Load(Filename='CNCS_7860_event.nxs')
221
    splitws, infows = GenerateEventsFilter(InputWorkspace=ws, UnitOfTime='Nanoseconds', LogName='SampleTemp',
Zhou, Wenduo's avatar
Zhou, Wenduo committed
222
            MinimumLogValue=279.9,  MaximumLogValue=279.98, LogValueInterval=0.01)
223
224
225

    FilterEvents(InputWorkspace=ws,
        SplitterWorkspace=splitws,
Zhou, Wenduo's avatar
Zhou, Wenduo committed
226
        InformationWorkspace=infows,
227
228
229
        OutputWorkspaceBaseName='tempsplitws',
        GroupWorkspaces=True,
        FilterByPulseTime = True,
Zhou, Wenduo's avatar
Zhou, Wenduo committed
230
        OutputWorkspaceIndexedFrom1 = True,
231
232
        CorrectionToSample = "None",
        SpectrumWithoutDetector = "Skip",
Zhou, Wenduo's avatar
Zhou, Wenduo committed
233
        SplitSampleLogs = False,
234
        OutputTOFCorrectionWorkspace='mock')
Zhou, Wenduo's avatar
Zhou, Wenduo committed
235
236
237
238

    # Print result
    wsgroup = mtd["tempsplitws"]
    wsnames = wsgroup.getNames()
239
    for name in sorted(wsnames):
Zhou, Wenduo's avatar
Zhou, Wenduo committed
240
        tmpws = mtd[name]
241
        print("workspace %s has %d events" % (name, tmpws.getNumberEvents()))
Zhou, Wenduo's avatar
Zhou, Wenduo committed
242
243
244
245
246
247
248
249
250
251
252
253
254
255


Output:

.. testoutput:: FilterEventByPulseTime

    workspace tempsplitws_1 has 123 events
    workspace tempsplitws_2 has 16951 events
    workspace tempsplitws_3 has 9972 events
    workspace tempsplitws_4 has 7019 events
    workspace tempsplitws_5 has 22529 events
    workspace tempsplitws_6 has 5067 events


256
**Example - Filtering event with correction on TOF**
Zhou, Wenduo's avatar
Zhou, Wenduo committed
257
258
259
260

.. testcode:: FilterEventTOFCorrection

    ws = Load(Filename='CNCS_7860_event.nxs')
261
    splitws, infows = GenerateEventsFilter(InputWorkspace=ws, UnitOfTime='Nanoseconds', LogName='SampleTemp',
Zhou, Wenduo's avatar
Zhou, Wenduo committed
262
263
264
            MinimumLogValue=279.9,  MaximumLogValue=279.98, LogValueInterval=0.01)

    FilterEvents(InputWorkspace=ws, SplitterWorkspace=splitws, InformationWorkspace=infows,
265
266
267
        OutputWorkspaceBaseName='tempsplitws',
        GroupWorkspaces=True,
        FilterByPulseTime = False,
Zhou, Wenduo's avatar
Zhou, Wenduo committed
268
        OutputWorkspaceIndexedFrom1 = False,
269
        CorrectionToSample = "Direct",
Zhou, Wenduo's avatar
Zhou, Wenduo committed
270
        IncidentEnergy=3,
271
        SpectrumWithoutDetector = "Skip",
Zhou, Wenduo's avatar
Zhou, Wenduo committed
272
273
        SplitSampleLogs = False,
        OutputTOFCorrectionWorkspace='mock')
274

Zhou, Wenduo's avatar
Zhou, Wenduo committed
275
276
277
    # Print result
    wsgroup = mtd["tempsplitws"]
    wsnames = wsgroup.getNames()
278
    for name in sorted(wsnames):
Zhou, Wenduo's avatar
Zhou, Wenduo committed
279
        tmpws = mtd[name]
280
        print("workspace %s has %d events" % (name, tmpws.getNumberEvents()))
Zhou, Wenduo's avatar
Zhou, Wenduo committed
281
282
283
284
285
286


Output:

.. testoutput:: FilterEventTOFCorrection

Zhou, Wenduo's avatar
Zhou, Wenduo committed
287
288
289
290
291
292
293
    workspace tempsplitws_0 has 123 events
    workspace tempsplitws_1 has 16951 events
    workspace tempsplitws_2 has 9972 events
    workspace tempsplitws_3 has 7019 events
    workspace tempsplitws_4 has 22514 events
    workspace tempsplitws_5 has 5082 events
    workspace tempsplitws_unfiltered has 50605 events
Zhou, Wenduo's avatar
Zhou, Wenduo committed
294

295
.. categories::
296
297

.. sourcelink::
298
299
300
    :h: Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h
    :cpp: Framework/Algorithms/src/FilterEvents.cpp
    :py: None