xboa
_gaussian_smoothing.py
Go to the documentation of this file.
1 # This file is a part of xboa
2 #
3 # xboa is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # xboa is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with xboa in the doc folder. If not, see
15 # <http://www.gnu.org/licenses/>.
16 
17 """Gaussian smoothing module - expect to import from smoothing module directly
18 """
19 
20 import math
21 
22 class GaussianSmoothing(object):
23  """
24  Gaussian smoothing class applies a smoothing by summing nearby data and
25  weighting according to a truncated Gaussian distribution.
26 
27  The Smoothing function has two parameters
28  - sigma (float) controls the width of the Gaussian distribution
29  - range_ (int) controls the truncation of the Gaussian. Only data points
30  within range_ of the principle data point will be added into the smoothed
31  value of the principle data point.
32  - boundary
33 
34  Smoothing near to the boundaries is performed using whatever data is
35  available. Normalisation at the boundaries can be handled in either of two
36  ways
37  - if adjust_boundary_normalisation is True, normalisation is performed using
38  the sum of available weights (so if we are on the boundary, the
39  normalisation factor is increased and we get larger weightings).
40  - if adjust_boundary_normalisation is False, every smoothed element gets the
41  same weighting.
42  """
43  def __init__(self, sigma, range_, adjust_boundary_normalisation):
44  """
45  Initialise the smoothing
46  - sigma (float) width of the Gaussian distribution
47  - range_ (int) truncation distance applied to the Gaussian distribution
48  - adjust_boundary_normalisation (bool) set to true to adjust the
49  normalisation factor near to the edge of the data array due to the
50  fact there are fewer elements in the smoothing
51  """
52  self.sigma = sigma
53  self.range_ = range_
54  two_sig_sq = 2.*sigma**2
55  self._weights = [math.exp(-i**2./two_sig_sq) \
56  for i in range(-self.range_, self.range_+1)]
57  self.norm = None
58  if not adjust_boundary_normalisation:
59  self.norm = sum(self._weights)
60 
61  def smooth(self, signal):
62  """Smooth the signal"""
63  signal_out = [self._smooth_one(signal, i) for i in range(len(signal))]
64  return signal_out
65 
66  def _smooth_one(self, signal, i):
67  """Smooth the point in signal at index i"""
68  s_0 = max(0, i-self.range_)
69  s_1 = min(len(signal), i+self.range_+1)
70  sigs = [signal[s_index] for s_index in range(s_0, s_1)]
71 
72  w_0 = s_0 - i + self.range_
73  w_1 = s_1 - i + self.range_
74  assert(w_1-w_0 == s_1 - s_0)
75  weights = [self._weights[w_index] for w_index in range(w_0, w_1)]
76 
77  if self.norm == None: # variable normalisation factor
78  this_norm = sum(weights)
79  else: # fixed normalisation factor
80  this_norm = self.norm
81  weighted = [weights[j]*sigs[j]/this_norm for j in range(s_1-s_0)]
82  smoothed = sum(weighted)
83  return smoothed
84 
Gaussian smoothing class applies a smoothing by summing nearby data and weighting according to a trun...