Module: DataLayerProcessorNoiseRemoval

Included in:
DataLayerProcessor
Defined in:
lib/technical_graph/data_layer_processor_noise_removal.rb

Constant Summary collapse

DEFAULT_NOISE_REMOVAL_LEVEL =
3
DEFAULT_NOISE_REMOVAL_WINDOW_SIZE =
10
NOISE_COEFF =
1000
NOISE_POWER_COEFF =
8

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#noise_removalObject

Returns the value of attribute noise_removal.



20
21
22
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 20

def noise_removal
  @noise_removal
end

#noise_removal_levelObject

Returns the value of attribute noise_removal_level.



20
21
22
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 20

def noise_removal_level
  @noise_removal_level
end

#noise_removal_window_sizeObject

Returns the value of attribute noise_removal_window_size.



20
21
22
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 20

def noise_removal_window_size
  @noise_removal_window_size
end

#noise_thresholdObject

Returns the value of attribute noise_threshold.



20
21
22
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 20

def noise_threshold
  @noise_threshold
end

Instance Method Details

#calc_avg_derivative(i_from, i_to) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 87

def calc_avg_derivative(i_from, i_to)
  part_array = data.clone_partial_w_fill(i_from, i_to)
  derivatives = Array.new
  (1...part_array.size).each do |i|
    x_len = (part_array[i].x - part_array[i - 1].x).abs
    y_len = (part_array[i].y - part_array[i - 1].y).abs
    derivatives << (x_len / y_len).abs if x_len.abs > 0
  end
  avg_der = derivatives.float_mean
  return avg_der
end

#noise?(i) ⇒ Boolean

Check if data at index is noisy

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 57

def noise?(i)
  i_from = noise_removal_window_from(i)
  i_to = noise_removal_window_to(i)


  # y_mean = part_array.collect { |p| p.y }.float_mean
  # # another algorithm
  # noise_strength = (data[i].y - y_mean).abs / y_mean
  # return noise_strength_enough?(noise_strength)

  # calc. avg 'derivative'
  avg_der = calc_avg_derivative(i_from, i_to)
  current_der = calc_avg_derivative(i-1, i+1)

  # safety
  return false if avg_der == 0 or current_der == 0

  begin
    current_level = Math.log((current_der / avg_der) ** NOISE_POWER_COEFF).abs
  rescue Errno::EDOM
    # can not calculate logarithm
    return false
  rescue Errno::ERANGE
    # can not calculate logarithm
    return false
  end
  logger.debug "noise removal, avg der #{avg_der}, current #{current_der}, current lev #{current_level}, threshold #{noise_threshold}"
  return current_level > noise_threshold
end

#noise_removal_initialize(options) ⇒ Object



12
13
14
15
16
17
18
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 12

def noise_removal_initialize(options)
  @noise_removal = options[:noise_removal] == true
  @noise_removal_level = options[:noise_removal_level] || DEFAULT_NOISE_REMOVAL_LEVEL
  @noise_removal_window_size = options[:noise_removal_window_size] || DEFAULT_NOISE_REMOVAL_WINDOW_SIZE

  @noise_threshold = Math.log(NOISE_COEFF / @noise_removal_level)
end

#noise_removal_processObject

Smooth values



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 23

def noise_removal_process
  return if noise_removal == false

  t = Time.now
  new_data = Array.new

  @noises_removed_count = 0

  logger.debug "Noise removal started"

  (0...data.size).each do |i|
    if not noise?(i)
      new_data << data[i]
    else
      @noises_removed_count += 1
    end
  end

  logger.debug "Noise removal completed, removed #{@noises_removed_count}"
  logger.debug " TIME COST #{Time.now - t}"

  @data = new_data
  return new_data
end

#noise_removal_window_from(i) ⇒ Object



48
49
50
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 48

def noise_removal_window_from(i)
  return i - (noise_removal_window_size.to_f / 2.0).ceil
end

#noise_removal_window_to(i) ⇒ Object



52
53
54
# File 'lib/technical_graph/data_layer_processor_noise_removal.rb', line 52

def noise_removal_window_to(i)
  return i + (noise_removal_window_size.to_f / 2.0).ceil
end