Skip to content

Commit 0c3d52d

Browse files
authored
Merge pull request #677 from DiamondLightSource/nics_working_branch
adds iterative plugin templates
2 parents 9d0f148 + 4d73e9a commit 0c3d52d

File tree

4 files changed

+354
-0
lines changed

4 files changed

+354
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright 2014 Diamond Light Source Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""
15+
.. module:: iterative_plugin
16+
:platform: Unix
17+
:synopsis: Iterative plugin example
18+
.. moduleauthor:: Nicola Wadeson <[email protected]>
19+
"""
20+
21+
import numpy as np
22+
23+
from savu.plugins.utils import register_plugin
24+
from savu.plugins.filters.base_filter import BaseFilter
25+
from savu.plugins.driver.iterative_plugin import IterativePlugin
26+
27+
28+
@register_plugin
29+
class TestingIterativePlugin(BaseFilter, IterativePlugin):
30+
"""
31+
A plugin to test the iterative plugin driver
32+
33+
:u*param nIterations: Number of iterations. Default: 10.
34+
35+
"""
36+
37+
def __init__(self):
38+
super(TestingIterativePlugin, self).__init__("TestingIterativePlugin")
39+
40+
def pre_process(self):
41+
self.set_iterations(self.parameters['nIterations'])
42+
43+
def process_frames(self, data):
44+
# A random example function
45+
if self.get_iteration() == 0:
46+
return np.zeros(data[0].shape, dtype=np.float32)
47+
return data[1] + np.ones(data[0].shape, dtype=np.float32)*10
48+
49+
def post_process(self):
50+
# option here to break out of the iterations
51+
#self.set_processing_complete()
52+
pass
53+
54+
def setup(self):
55+
# set up the output dataset that is created by the plugin
56+
in_dataset, out_dataset = self.get_datasets()
57+
58+
in_pData, out_pData = self.get_plugin_datasets()
59+
in_pData[0].plugin_data_setup('SINOGRAM', 'single')
60+
61+
# Cloned datasets are at the end of the out_dataset list
62+
out_dataset[0].create_dataset(in_dataset[0])
63+
64+
# What is a cloned dataset?
65+
# Since each dataset in Savu has its own backing hdf5 file, a dataset
66+
# cannot be used for input and output at the same time. So, in the
67+
# case of iterative plugins, if a dataset is used as output and then
68+
# as input on the next iteration, the subsequent output must be a
69+
# different file.
70+
# A cloned dataset is a copy of another dataset but with a different
71+
# backing file. It doesn't have a name, is not accessible as a dataset
72+
# in the framework and is only used in alternation with another
73+
# dataset to allow it to be used as both input and output
74+
# simultaneously.
75+
76+
# This is a cloned dataset (of out_dataset[0])
77+
self.create_clone(out_dataset[1], out_dataset[0])
78+
79+
out_pData[0].plugin_data_setup('SINOGRAM', 'single')
80+
out_pData[1].plugin_data_setup('SINOGRAM', 'single')
81+
82+
# input and output datasets for the first iteration
83+
self.set_iteration_datasets(0, [in_dataset[0]], [out_dataset[0]])
84+
# input and output datasets for subsequent iterations
85+
self.set_iteration_datasets(1, [in_dataset[0], out_dataset[0]],
86+
[out_dataset[1]])
87+
# out_dataset[0] and out_dataset[1] will continue to alternate for
88+
# all remaining iterations i.e. output becomes input and input becomes
89+
# output.
90+
91+
# total number of output datasets
92+
def nOutput_datasets(self):
93+
return 2
94+
95+
# total number of output datasets that are clones
96+
def nClone_datasets(self):
97+
return 1
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Copyright 2014 Diamond Light Source Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""
15+
.. module:: testing_iterative_plugin2
16+
:platform: Unix
17+
:synopsis: Iterative plugin example
18+
.. moduleauthor:: Nicola Wadeson <[email protected]>
19+
"""
20+
21+
import numpy as np
22+
23+
from savu.plugins.utils import register_plugin
24+
from savu.plugins.filters.base_filter import BaseFilter
25+
from savu.plugins.driver.iterative_plugin import IterativePlugin
26+
27+
28+
@register_plugin
29+
class TestingIterativePlugin2(BaseFilter, IterativePlugin):
30+
"""
31+
A plugin to test the iterative plugin driver
32+
"""
33+
34+
def __init__(self):
35+
super(TestingIterativePlugin2, self).\
36+
__init__("TestingIterativePlugin2")
37+
38+
def pre_process(self):
39+
self.set_iterations(3)
40+
41+
def process_frames(self, data):
42+
if self.get_iteration() == 0:
43+
return data[0]
44+
return data[0]
45+
46+
def post_process(self):
47+
# option here to break out of the iterations
48+
# self.set_processing_complete()
49+
pass
50+
51+
def setup(self):
52+
self.exp.log(self.name + " Start")
53+
54+
# set up the output dataset that is created by the plugin
55+
in_dataset, out_dataset = self.get_datasets()
56+
57+
in_pData, out_pData = self.get_plugin_datasets()
58+
in_pData[0].plugin_data_setup('SINOGRAM', 'single')
59+
60+
out_dataset[0].create_dataset(in_dataset[0])
61+
self.clone_dataset(out_dataset[1], out_dataset[0])
62+
63+
out_pData[0].plugin_data_setup('SINOGRAM', 'single')
64+
out_pData[1].plugin_data_setup('SINOGRAM', 'single')
65+
66+
# try replacing input dataset with the output dataset
67+
self.set_iteration_datasets(0, [in_dataset[0]], [out_dataset[0]])
68+
self.set_iteration_datasets(1, [out_dataset[0]], [out_dataset[1]])
69+
70+
self.exp.log(self.name + " End")
71+
72+
def nOutput_datasets(self):
73+
return 2
74+
75+
def nClone_datasets(self):
76+
return 1
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Copyright 2014 Diamond Light Source Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""
15+
.. module:: testing_iterative_plugin3
16+
:platform: Unix
17+
:synopsis: Iterative plugin example
18+
.. moduleauthor:: Nicola Wadeson <[email protected]>
19+
"""
20+
21+
from savu.plugins.utils import register_plugin
22+
from savu.plugins.filters.base_filter import BaseFilter
23+
from savu.plugins.driver.iterative_plugin import IterativePlugin
24+
25+
26+
@register_plugin
27+
class TestingIterativePlugin3(BaseFilter, IterativePlugin):
28+
"""
29+
A plugin to test the iterative plugin driver
30+
"""
31+
32+
def __init__(self):
33+
super(TestingIterativePlugin3, self).\
34+
__init__("TestingIterativePlugin3")
35+
36+
def pre_process(self):
37+
self.set_iterations(3)
38+
39+
def process_frames(self, data):
40+
return [data[0], data[0]]
41+
42+
def post_process(self):
43+
# option here to break out of the iterations
44+
# self.set_processing_complete()
45+
pass
46+
47+
def setup(self):
48+
self.exp.log(self.name + " Start")
49+
50+
# set up the output dataset that is created by the plugin
51+
in_dataset, out_dataset = self.get_datasets()
52+
53+
in_pData, out_pData = self.get_plugin_datasets()
54+
in_pData[0].plugin_data_setup('SINOGRAM', self.get_max_frames())
55+
56+
# these are the datasets with names
57+
out_dataset[0].create_dataset(in_dataset[0])
58+
out_dataset[1].create_dataset(in_dataset[0])
59+
# these are the clones
60+
out_dataset[2].create_dataset(out_dataset[0])
61+
out_dataset[3].create_dataset(out_dataset[1])
62+
63+
out_pData[0].plugin_data_setup('SINOGRAM', 'single')
64+
out_pData[1].plugin_data_setup('SINOGRAM', 'single')
65+
out_pData[2].plugin_data_setup('SINOGRAM', 'single')
66+
out_pData[3].plugin_data_setup('SINOGRAM', 'single')
67+
68+
# try replacing input dataset with the output dataset
69+
dIn = [in_dataset[0]]
70+
dOut = [out_dataset[0], out_dataset[1]]
71+
self.set_iteration_datasets(0, dIn, dOut)
72+
73+
dIn = [out_dataset[0], out_dataset[0], out_dataset[1]]
74+
dOut = [out_dataset[2], out_dataset[3]]
75+
self.set_iteration_datasets(1, dIn, dOut)
76+
77+
# cloned datasets used as alternating datasets?
78+
self.set_alternating_datasets(out_dataset[0], out_dataset[2])
79+
self.set_alternating_datasets(out_dataset[1], out_dataset[3])
80+
81+
self.exp.log(self.name + " End")
82+
83+
def nOutput_datasets(self):
84+
return 4
85+
86+
def nClone_datasets(self):
87+
return 2
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Copyright 2014 Diamond Light Source Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""
15+
.. module:: testing_iterative_plugin4
16+
:platform: Unix
17+
:synopsis: Iterative plugin example
18+
.. moduleauthor:: Nicola Wadeson <[email protected]>
19+
"""
20+
21+
from savu.plugins.utils import register_plugin
22+
from savu.plugins.filters.base_filter import BaseFilter
23+
from savu.plugins.driver.iterative_plugin import IterativePlugin
24+
25+
26+
@register_plugin
27+
class TestingIterativePlugin4(BaseFilter, IterativePlugin):
28+
"""
29+
A plugin to test the iterative plugin driver - switching between sinograms
30+
and projections on each iteration.
31+
"""
32+
33+
def __init__(self):
34+
super(TestingIterativePlugin4, self).\
35+
__init__("TestingIterativePlugin4")
36+
37+
def pre_process(self):
38+
self.set_iterations(3)
39+
40+
def process_frames(self, data):
41+
return data[0]
42+
43+
def post_process(self):
44+
# option here to break out of the iterations
45+
# self.set_processing_complete()
46+
pass
47+
48+
def setup(self):
49+
# set up the output dataset that is created by the plugin
50+
in_dataset, out_dataset = self.get_datasets()
51+
52+
in_pData, out_pData = self.get_plugin_datasets()
53+
in_pData[0].plugin_data_setup('SINOGRAM', 'single')
54+
55+
out_dataset[0].create_dataset(in_dataset[0])
56+
# Clone and set as alternating dataset - should I actually do this here?
57+
self.clone_dataset(out_dataset[1], out_dataset[0])
58+
59+
# HOw to set more than one pattern associated with a plugin
60+
out_pData[0].plugin_data_setup('SINOGRAM', 'single') # set first pattern
61+
out_pData[1].plugin_data_setup('PROJECTION', 'single') # set first pattern
62+
63+
# Do I need two plugin data objects? When should I set this?
64+
65+
# try replacing input dataset with the output dataset *****option to change the pattern on each iteration?
66+
# option to set any number of patterns one after another
67+
self.set_iteration_datasets(0, [in_dataset[0]], [out_dataset[0]], pattern='SINOGRAM') # Add option for pattern to be a dictionary with different pattern for each dataset
68+
self.set_iteration_datasets(1, [out_dataset[0]], [out_dataset[1]], pattern='PROJECTION') # PROJECTION
69+
# out_dataset[0] and out_dataset[1] will continue to alternate for the
70+
# remaining iterations
71+
self.set_alternating_patterns(['SINOGRAM', 'PROJECTION']) # or explicitly add it as above or a combination of both
72+
# it could be that the first two iterations have the same pattern and the remainder alternate
73+
74+
# alternatively to above you could just have
75+
# self.set_iteration_datasets(0, [in_dataset[0]], [out_dataset[0]])
76+
# self.set_iteration_datasets(1, [out_dataset[0]], [out_dataset[1]])
77+
# self.set_alternating_patterns(['SINOGRAM', 'PROJECTION']) # what if there is more than on pattern - this should also be a dictionary
78+
79+
# So, to set different patterns there are two ways
80+
# first way is to add 'pattern' key word to set_iteration_datasets function call
81+
# second way is to pass a list of patterns to set_alternating_patterns function call
82+
# in either case, each entry can be a list of a dictionary
83+
# if a list apply to all datasets
84+
# if a dictionary, they should be {dataset: pattern} key value pairs
85+
86+
# Now I just have to make this work - can I just create an extra pluginData object for each dataset and alternate between those?
87+
# Or will I have to calculate mfp/mft every time?
88+
# Don't forget to call "finalise_datasets" or whatever the function is (usually called after the setup method)
89+
90+
def nOutput_datasets(self):
91+
return 2
92+
93+
def nClone_datasets(self):
94+
return 1

0 commit comments

Comments
 (0)