Class: CTioga2::Data::DataColumn

Inherits:
Object
  • Object
show all
Defined in:
lib/ctioga2/data/datacolumn.rb

Overview

This class holds one column, possibly with error bars.

todo a way to concatenate two DataColumns

todo a way to easily access the by “lines”

Constant Summary collapse

ColumnSpecsRE =
/|min|max|err|rerr/i

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(values, min = nil, max = nil) ⇒ DataColumn

todo a dup !



44
45
46
47
48
# File 'lib/ctioga2/data/datacolumn.rb', line 44

def initialize(values, min = nil, max = nil)
  @values = values
  @min_values = min
  @max_values = max
end

Instance Attribute Details

#max_valuesObject

A Dvector holding maximal values



36
37
38
# File 'lib/ctioga2/data/datacolumn.rb', line 36

def max_values
  @max_values
end

#min_valuesObject

A Dvector holding minimal values



33
34
35
# File 'lib/ctioga2/data/datacolumn.rb', line 33

def min_values
  @min_values
end

#valuesObject

A Dvector holding “real” values



30
31
32
# File 'lib/ctioga2/data/datacolumn.rb', line 30

def values
  @values
end

Class Method Details

.create(number, with_errors = false) ⇒ Object

Creates a DataColumn object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ctioga2/data/datacolumn.rb', line 51

def self.create(number, with_errors = false)
  a = Dobjects::Dvector.new(number, NaN::NaN)
  if with_errors
    b = Dobjects::Dvector.new(number, NaN::NaN)
    c = Dobjects::Dvector.new(number, NaN::NaN)
  else
    b = nil
    c = nil
  end
  return self.new(a, b, c)
end

.from_hash(spec) ⇒ Object

Creates and returns a DataColumn object according to the spec. See #from_hash for more information.



245
246
247
248
249
# File 'lib/ctioga2/data/datacolumn.rb', line 245

def self.from_hash(spec)
  a = DataColumn.new(nil)
  a.from_hash(spec)
  return a
end

Instance Method Details

#<<(column) ⇒ Object

Concatenates with another DataColumn, making sure the errors and such are not lost.



168
169
170
171
172
173
174
175
176
177
# File 'lib/ctioga2/data/datacolumn.rb', line 168

def <<(column)
  # If there are error bars, wew make sure we concatenate all of them
  if has_errors? || column.has_errors?
    self.ensure_has_errors
    column.ensure_has_errors
    @min_values.concat(column.min_values)
    @max_values.concat(column.max_values)
  end
  @values.concat(column.values)
end

#applyObject

Yields all the vectors in turn to apply a given transformation.



66
67
68
69
70
# File 'lib/ctioga2/data/datacolumn.rb', line 66

def apply
  for v in all_vectors
    yield v if v
  end
end

#average_over(istart, iend, itgt, mode = :avg) ⇒ Object

Averages over the given indices, and puts the result at the target index.

Different averaging modes are available.



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/ctioga2/data/datacolumn.rb', line 336

def average_over(istart, iend, itgt, mode = :avg)
  case mode
  when :avg
    # Stupidly average over all the values
    for v in all_vectors
      if v
        av = Utils::average_vector(v, istart, iend)
        v[itgt] = av[0]
      end
    end
  when :stddev
    # Ignore errors, and set them from the standard deviation
    @min_values ||= @values.dup
    @max_values ||= @values.dup

    av = Utils::average_vector(@values, istart, iend, 2)
    @values[itgt] = av[0]
    stddev = (av[1] - av[0]**2)**0.5
    @min_values[itgt] = av[0] - stddev
    @max_values[itgt] = av[0] + stddev
  end
end

#bin(min, max, nb, normalize = false) ⇒ Object

Bins the values of the columns into nb bins between min and max. Values outside that range are not taken into account. If total number of samples.

It returns [xv, yv], where xv are the centers of the bins, and yv the counts

Does not take into account the error columns.



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/ctioga2/data/datacolumn.rb', line 303

def bin(min, max, nb, normalize = false)
  total = @values.size*1.0
  xv = Dobjects::Dvector.new(nb)
  yv = Dobjects::Dvector.new(nb)

  0.upto(nb-1) do |i|
    xv[i] = min + (max-min)*(i+0.5)/nb
    yv[i] = 0
  end
  
  for v in @values
    idx = (v-min)/(max-min)
    if idx > 1.0 or idx < 0
      next
    end
    idx = (idx*nb).to_i
    if idx == nb
      idx = nb-1          # case v = max
    end
    yv[idx] += 1
  end

  if normalize
    yv *= (1.0/total)
  end

  return [xv, yv]
end

#column_names(base, expand = false) ⇒ Object

Column names. base is used as a base for the names. If expand is on, always return all the names.



96
97
98
99
100
101
102
# File 'lib/ctioga2/data/datacolumn.rb', line 96

def column_names(base, expand = false)
  if expand || has_errors?
    return [base, "#{base}min", "#{base}max"]
  else
    return [base]
  end
end

#convolve!(kernel, middle = nil) ⇒ Object



279
280
281
282
283
284
285
# File 'lib/ctioga2/data/datacolumn.rb', line 279

def convolve!(kernel, middle = nil)
  middle ||= kernel.size/2
  # We smooth everything, stupidly?
  for v in all_vectors
    v.replace(v.convolve(kernel,middle)) if v
  end
end

#ensure_has_errorsObject

Creates dummy errors (ie, min_values = max_values = values) if the datacolumn does not currently have one.



159
160
161
162
163
164
# File 'lib/ctioga2/data/datacolumn.rb', line 159

def ensure_has_errors
  if ! has_errors?
    @min_values = @values.dup
    @max_values = @values.dup
  end
end

#from_hash(spec) ⇒ Object

This function sets the value of the DataColumn object according to a hash: spec => vector. spec can be any of:

  • ‘value’, ‘values’ or ” : the #values

  • ‘min’ : #min

  • ‘max’ : #max

  • ‘err’ : absolute error: min is value - error, max is value +

    error
    


214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/ctioga2/data/datacolumn.rb', line 214

def from_hash(spec)
  s = spec.dup
  @values = spec['value'] || spec['values'] || 
    spec[''] 
  if ! @values
    raise "Need a 'value' specification"
  end
  for k in ['value', 'values', '']
    s.delete(k)
  end
  for key in s.keys
    case key
    when /^min$/i
      @min_values = s[key]
    when /^max$/i
      @max_values = s[key]
    when /^err$/i
      @min_values = @values - s[key]
      @max_values = @values + s[key]
    when /^rerr$/i
      @min_values = @values *(1 - s[key])
      @max_values = @values *(1 + s[key])
    else
      raise "Unkown key: #{key}"
    end
  end
end

#has_errors?Boolean

Whether there are error bars.

Returns:

  • (Boolean)


90
91
92
# File 'lib/ctioga2/data/datacolumn.rb', line 90

def has_errors?
  return (@min_values && @max_values)
end

#maxObject

Returns the maximum value of all vectors held in this column



266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/ctioga2/data/datacolumn.rb', line 266

def max
  m = @values.max
  for v in [@min_values, @max_values]
    if v
      m1 = v.max
      if m1 > m           # This also works if m1 is NaN
        m = m1
      end
    end
  end
  return m
end

#minObject

Returns the minimum value of all vectors held in this column



252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/ctioga2/data/datacolumn.rb', line 252

def min
  m = @values.min
  for v in [@min_values, @max_values]
    if v
      m1 = v.min
      if m1 < m           # This also works if m1 is NaN
        m = m1
      end
    end
  end
  return m
end

#push_values(value, min = nil, max = nil) ⇒ Object

TODO:

This isn’t very efficient. Does it really matter ?

Appends the given values at the end of the DataColumn



153
154
155
# File 'lib/ctioga2/data/datacolumn.rb', line 153

def push_values(value, min=nil, max=nil)
  set_values_at(@values.size, value, min, max)
end

#reindex(idx_vector) ⇒ Object

Sorts the values according to the index vector given.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/ctioga2/data/datacolumn.rb', line 73

def reindex(idx_vector)
  for v in all_vectors
    # This is slow !
    # Code should be written in C on the dvector side.
    #
    # Or we could use Function.sort, though this is not very
    # elegant nor efficient. (but it would be memory-efficient,
    # though).
    next unless v
    w = Dobjects::Dvector.new(idx_vector.size) do |i|
      v[idx_vector[i]]
    end
    v.replace(w)
  end
end

#resize!(new_size) ⇒ Object

Resize all the columns to the given size.



288
289
290
291
292
# File 'lib/ctioga2/data/datacolumn.rb', line 288

def resize!(new_size)
  for v in all_vectors
    v.resize(new_size) if v
  end
end

#set_values_at(i, value, min = nil, max = nil) ⇒ Object

Sets the values at the given index



141
142
143
144
145
146
147
148
# File 'lib/ctioga2/data/datacolumn.rb', line 141

def set_values_at(i, value, min = nil, max = nil)
  @values[i] = value
  if min && max
    ensure_has_errors
    @min_values[i] = min
    @max_vaklues[i] = max
  end
end

#sizeObject

Returns the number of elements.



136
137
138
# File 'lib/ctioga2/data/datacolumn.rb', line 136

def size
  return @values.size
end

#trim!(nb) ⇒ Object

Only keeps every n points in the DataColumn



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/ctioga2/data/datacolumn.rb', line 180

def trim!(nb)
  nb = nb.to_i
  if nb < 2
    return
  end

  new_vects = []
  for v in all_vectors
    if v
      new_values = Dobjects::Dvector.new
      i = 0
      for val in v
        if (i % nb) == 0
          new_values << val
        end
        i+=1
      end
      new_vects << new_values
    else
      new_vects << nil
    end
  end
  set_vectors(new_vects)
end

#values_at(i, with_errors = false, expand_nil = true) ⇒ Object

Values at the given index.

If with_errors is false, only [value] is returned.

If with_errors is true, then, non-existent values are expanded to nil if expand_nil is true or to value if not.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/ctioga2/data/datacolumn.rb', line 110

def values_at(i, with_errors = false, expand_nil = true)
  if ! with_errors 
    return [@values[i]]
  end
  if has_errors?
    return [@values[i], @min_values[i], @max_values[i]]
  else
    if expand_nil
      return [@values[i], nil, nil]
    else
      return [@values[i], @values[i], @values[i]]
    end
  end
end

#vectorsObject

Vectors: all values if there are error bars, or only the #value one if there isn’t.



127
128
129
130
131
132
133
# File 'lib/ctioga2/data/datacolumn.rb', line 127

def vectors
  if has_errors?
    return [@values, @min_values, @max_values]
  else
    return [@values]
  end
end