Test Failed
Pull Request — master (#934)
by
unknown
04:09
created

GatherStats.nOutput_datasets()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
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
"""
16
.. module:: comparison
17
   :platform: Unix
18
   :synopsis: A plugin to compare two datasets, given as input datasets, and print the RMSD between the two.
19
              The data is unchanged.
20
21
.. moduleauthor:: Jacob Williamson <[email protected]>
22
"""
23
24
from savu.plugins.utils import register_plugin
25
from savu.plugins.plugin import Plugin
26
from savu.plugins.driver.cpu_plugin import CpuPlugin
27
from savu.core.iterate_plugin_group_utils import enable_iterative_loop, \
28
    check_if_end_plugin_in_iterate_group, setup_extra_plugin_data_padding
29
30
import os
31
import h5py as h5
32
33
# This decorator is required for the configurator to recognise the plugin
34
@register_plugin
35
class GatherStats(Plugin, CpuPlugin):
36
37
    def __init__(self):
38
        super(GatherStats, self).__init__("GatherStats")
39
40
    def nInput_datasets(self):
41
        return 1
42
43
44
    def nOutput_datasets(self):
45
        return 0
46
47
    def nClone_datasets(self):
48
        if check_if_end_plugin_in_iterate_group(self.exp):
49
            return 1
50
        else:
51
            return 0
52
53
54
    @enable_iterative_loop
55
    def setup(self):
56
57
        in_dataset, out_dataset = self.get_datasets()
58
        self.stats_obj.calc_stats = False
59
        self.stats_obj.set_stats_key(["max", "min", "mean", "mean_std_dev", "median_std_dev", "zeros", "zeros%",
60
                                       "range_used"])
61
        in_pData, out_pData = self.get_plugin_datasets()
62
63
        # Each plugin dataset must call this method and define the data access
64
        # pattern and number of frames required.
65
        for i in range(len(in_pData)):
66
            in_pData[i].plugin_data_setup(self.parameters['pattern'], 'single')
67
68
        # All dataset information can be accessed via the Data and PluginData
69
        # instances
70
71
72
    def pre_process(self):
73
        # This method is called once before any processing has begun.
74
        # Access parameters from the doc string in the parameters dictionary
75
        # e.g. self.parameters['example']
76
        in_datasets = self.get_in_datasets()
77
78
    def process_frames(self, data):
79
        self.stats_obj.set_slice_stats(data, pad=False)
80
        return None
81
82
    def post_process(self):
83
        slice_stats = self.stats_obj.stats
84
        comm = self.get_communicator()
85
        combined_stats = self.stats_obj._combine_mpi_stats(slice_stats, comm=comm)
86
87
        volume_stats = self.stats_obj.calc_volume_stats(combined_stats)
88
        if self.exp.meta_data.get("pre_run"):
89
90
            self._generate_warnings(volume_stats)
91
            self.exp.meta_data.set("pre_run_stats", volume_stats)
92
93
            folder = self.exp.meta_data['out_path']
94
            fname = self.exp.meta_data.get('datafile_name') + '_pre_run.nxs'
95
            filename = os.path.join(folder, fname)
96
            stats_array = self.stats_obj._dict_to_array(volume_stats)
97
            if comm.rank == 0:
98
                with h5.File(filename, "a") as h5file:
99
                    fsplit = self.exp.meta_data["data_path"].split("/")
100
                    fsplit[-1] = ""
101
                    stats_path = "/".join(fsplit)
102
                    stats_group = h5file.require_group(stats_path)
103
                    dataset = stats_group.create_dataset("stats", shape=stats_array.shape, dtype=stats_array.dtype)
104
                    dataset[::] = stats_array[::]
105
                    dataset.attrs.create("stats_key", list(self.stats_obj.stats_key))
106
107
    def _generate_warnings(self, volume_stats):
108
        warnings = []
109
        if volume_stats["zeros%"] > 10:
110
            warnings.append(f"Percentage of data points that are 0s is {volume_stats['zeros%']}")
111
        if volume_stats["range_used"] < 2:
112
            warnings.append(f"Only {volume_stats['range_used']}% of the possible range of the datatype (\
113
{self.stats_obj.stats['dtype']}) has been used. The datatype used, {self.stats_obj.stats['dtype']} can go from \
114
{self.stats_obj.stats['possible_min']} to {self.stats_obj.stats['possible_max']}")
115
        self.exp.meta_data.set("warnings", warnings)
116