1#!/usr/bin/env python3
2
3"""Implementation of reduce_dimensionalities utility function."""
4
5from collections import defaultdict
6from itertools import chain
7
8def reduce_dimensionalities(result, param_list):
9 """Reduce dimensionality of some parameters.
10
11 This is because it's possible other packets may use the same parameters as us
12 but in a more deeply nested structure, meaning parameters that are scalar or 1-d
13 arrays in this packet might be 1-d or 2-d or higher dimensionality in the TS XML
14 file (i.e. the FieldInfo) object. But this gives results that may not be wanted
15 so we adjust the structure before it gets into the database."""
16 # first measure the number of dimensions of each parameter in this packetdef
17 dimensionalities = defaultdict(int)
18 active_groups = []
19 for p in chain(param_list.params, param_list.dynamic_params):
20 if p.field_info is None:
21 # spacer param
22 continue
23
24 if p.field_info.name in dimensionalities:
25 # handle static single dimensional groups of parameters
26 # will break under some circumstances, like a static array inside a
27 # dynamic array
28 dimensionalities[p.field_info.name] = 1
29
30 else:
31 dimensionalities[p.field_info.name] = len(active_groups)
32
33 active_groups = [i - 1 for i in active_groups if i != 1]
34 if p.group_size is not None:
35 active_groups.append(p.group_size)
36
37 # logger.debug('dimensionalities', dimensionalities)
38
39 def dimensionality(val):
40 """compute the current number of dimensions of structure `val`."""
41 result = 0
42 v = val
43 while isinstance(v, list):
44 result += 1
45 if len(v) > 0:
46 v = v[0]
47 else:
48 v = None
49
50 # logger.debug('dimensionality of',val,'is',result)
51 return result
52
53 # now check for items in `result` that have too many dimensions and reduce them
54 for name in result.keys():
55 while dimensionality(result[name]) > dimensionalities[name]:
56 result[name] = result[name][0]