1
2 """
3 Data limits for high dynamic range data.
4
5 Limits() is a class for collecting combined limits on multiple sets of data.
6
7 limits(x,dv=0) returns floor,ceiling for a single dataset.
8 """
9
10 from copy import copy
11 from numpy import inf
12
14 """
15 Return data limits (floor, ceiling), where floor is the minimum
16 significant value (1/2-sigma away from zero) and ceiling is the
17 maximum absolute value. If dv=0, then floor is the minimum
18 non-zero absolute value.
19 """
20 L = Limits(v,dv=dv)
21 return L.floor,L.ceiling
22
24 """
25 Collect data limits, used for selecting ranges in colour maps for example.
26
27 A Limits() object has the following attributes::
28
29 ceiling - the maximum absolute data value
30 floor - 1/2 the min absolute value at least 1/2-sigma away from zero
31 min - the minimum data value
32 max - the maximum data value
33
34 The limits are collected by adding data sets to a limits object::
35
36 L = Limits()
37 for f in frames:
38 L.add(f, dv=sqrt(f))
39
40 Alternatively you can use the union operator::
41
42 L = Limits()
43 for f in frames:
44 L |= Limits(f, dv=sqrt(f))
45
46 The computed attributes are robust against values all identically
47 zero, returning instead a ceiling of 1 and a floor of 1/2. Other
48 situations may still cause problems such as infinities in the
49 data (infinite limits are hard to represent in a colour scale) or
50 all data being identical but non-zero (in which case floor==ceiling).
51
52 Regarding the choice of floor, the main goal of limits is to
53 avoid insignificant numbers on the log scale. The simplest algorithm
54 is to test v-dv > 0, which is to say that we are asking for 1-sigma
55 significance. However, it is useful to distinguish pixels with a
56 single count from those with zero counts on a 2-D detector,
57 but 1 +/- 1 would fail this test. Changing the test to v-dv >= 0
58 also includes points with 0 +/- 0, which we definitely want to
59 exclude. So instead we change the test to 1/2-sigma, which
60 catches 1 +/- 1 and skips 0 +/- 0.
61 """
62 _floor = inf
63 _ceiling = -inf
64 _min = inf
65 _max = -inf
74 floor = property(_getfloor)
75 ceiling = property(_getceiling)
76 min = property(_getmin)
77 max = property(_getmax)
78
80 if len(args) == 1:
81 self.add(*args,**kw)
82 elif len(args) > 1:
83 raise TypeError, "Limits() tokes 0 or 1 argument"
84
85 - def add(self, v, dv=0):
100
106
108 retval = copy(self)
109 retval |= L
110 return retval
111