class TimeArray::TimeArray

Attributes

start_time[R]
unit[R]
v[R]

Public Class Methods

new(start_time, values=Vector.new, options={}) click to toggle source
# File lib/time_array/time_array.rb, line 23
def initialize(start_time, values=Vector.new, options={})
  manage_options options
  set_start_time start_time
  set_values     values      
end

Public Instance Methods

*(vec) click to toggle source
# File lib/time_array/time_array.rb, line 182
def *(vec)
  oper(vec, :*)
end
+(vec) click to toggle source
# File lib/time_array/time_array.rb, line 174
def +(vec)
  oper(vec, :+)
end
-(vec) click to toggle source
# File lib/time_array/time_array.rb, line 178
def -(vec)
  oper(vec, :-)
end
/(vec) click to toggle source
# File lib/time_array/time_array.rb, line 186
def /(vec)
  oper(vec, :/)
end
align_with(other_array) click to toggle source
# File lib/time_array/time_array.rb, line 138
def align_with(other_array)
  # @start_time    = other_array.start_time if @start_time.nil? # ====
  return self if empty?
  return clear_data if other_array.empty?
    
  
  new_start_time = [start_time, other_array.start_time].max
  new_end_time   = [end_time,   other_array.end_time].min

  if end_time.nil? || other_array.end_time.nil? || new_start_time>new_end_time
    clear_data
  else
    @v = @v[((new_start_time-start_time)/3600).to_i, 1+((new_end_time-new_start_time)/3600).to_i]
  end
  @start_time = new_start_time
  self      
end
aligned_with?(other_array) click to toggle source
# File lib/time_array/time_array.rb, line 134
def aligned_with?(other_array)
  self.start_time==other_array.start_time && @v.size==other_array.size
end
all_to(new_value) click to toggle source

Set array values to the given new value

# File lib/time_array/time_array.rb, line 43
def all_to(new_value)
  @v = Vector.new(@v.size, new_value)
  self
end
avg(options = {}) click to toggle source

Get the average of values

# File lib/time_array/time_array.rb, line 88
def avg(options = {})
  c = count(options)
  return nil if c.zero? # if the array is empty will be returned nil
  sum(options) / c
end
clear_data() click to toggle source
# File lib/time_array/time_array.rb, line 128
def clear_data
  raise NilStartTimeError if @start_time.nil?
  @v = Vector.new
  self
end
clone() click to toggle source
# File lib/time_array/time_array.rb, line 38
def clone
  TimeArray.new(@start_time, (@v.clone rescue Vector.new), zone: Time.zone.name)
end
compact() click to toggle source

Will return a Compact object, a compacted version of values compact.gu gives the greatest_unit, compact.v gives the values array

# File lib/time_array/time_array.rb, line 216
def compact
  gu = greatest_unit
  puts "gu: #{gu.inspect}"
  return Compact.new(@v, gu) if gu==:hour
  i, st, v = 0, @start_time, []
  while i<@v.size
    v << @v[i]
    next_st = st+1.send(gu)
    h = (next_st-st)/3600
    i = i+h.to_i
    st = next_st
  end
  Compact.new(v, gu)
end
count(options = {}) click to toggle source

Count the values

# File lib/time_array/time_array.rb, line 77
def count(options = {})
  if options[:values]
    raise ArgumentError, "Option not recognized" if !%w(positive negative non_positive non_negative non_zero zero all).include?(options[:values].to_s)
    @v.send("count_"+options[:values].to_s)
  else
    @v.count_all
  end
end
each(&block) click to toggle source

Iterates each hour, the elements are the values of array time_array.each do |value|

value

end

# File lib/time_array/time_array.rb, line 333
def each(&block)
  @v.each &block
end
each_with_time(&block) click to toggle source

Iterates each hour, the elements are TimeAndValue objects time_array.each_with_time do |el|

e.time
e.value

end

# File lib/time_array/time_array.rb, line 356
def each_with_time(&block)
  arr = @v.map.with_index{|v, i| TimeAndValue.new(@start_time+i.hours, v)}
  arr.each(&block)
end
empty?() click to toggle source

def xy_array(options={}) # for the moment has been left out

# File lib/time_array/time_array.rb, line 118
def empty?
  @v.nil? || @v.empty?
end
end_time() click to toggle source

Return the time assiociated with the last value

# File lib/time_array/time_array.rb, line 123
def end_time
  return nil if empty?
  @start_time + (@v.size-1).hours
end
execute(&block) click to toggle source

execute the block (likely a calculation) on each vector element. and return a new time_array obj

# File lib/time_array/time_array.rb, line 324
def execute(&block)
  v = @v.map &block
  TimeArray.new(@start_time, v, zone: Time.zone.name)
end
first_values(number) click to toggle source
# File lib/time_array/time_array.rb, line 194
def first_values(number)
  @v[0,number]
end
greatest_unit() click to toggle source

Find the greatest unit time. If the values are contant along the month, the greatest unit is :month

# File lib/time_array/time_array.rb, line 235
def greatest_unit
  v = @v.first
  unit = Unit::YEAR # Unit::ETERNITY
  each_with_time do |el|

    # el.time
    # el.value
    if v!=el.value
      if el.time.year_changed? and unit>Unit::YEAR
        unit = Unit::YEAR
      else
        if el.time.month_changed? and unit>Unit::MONTH
          unit = Unit::MONTH
        else
          if el.time.day_changed? and unit>Unit::DAY
            unit = Unit::DAY
          else
            unit = Unit::HOUR
            break
          end
        end
      end
    end
    v = el.value
  end
  return Unit.name(unit)
end
group_by(interval) click to toggle source
# File lib/time_array/time_array.rb, line 202
def group_by(interval)
  raise ArgumentError, "interval not valid. Valid intervals are :hour, :day, :wday, :month, :year" unless Units.valid?(interval)
  t = start_time
  h = GroupHash.new{|h,k| h[k]=[]}
  @v.each do |v|
    h[t.send(interval)]<<v
    t+=1.hour
  end
  h
end
if_zero(other_array)
Alias for: if_zero_then
if_zero_then(other_array) click to toggle source
# File lib/time_array/time_array.rb, line 265
def if_zero_then(other_array)
  return self if other_array.nil?
  raise NilVectorError if @v.nil? || (other_array.is_a?(TimeArray) && other_array.v.nil?)

  c = self.clone
  if other_array.is_a? Numeric
    default_value = other_array
  else
    c.align_with(other_array)
  end
  
  c.size.times do |i|
    c.set_value(i, default_value || other_array.value(i) || 0.0) if c.value(i).zero?
  end
  c
end
Also aliased as: if_zero
max() click to toggle source

Get the maximum value

# File lib/time_array/time_array.rb, line 102
def max
  @v.compact.max
rescue
  nil
end
min() click to toggle source

Get the minimum value

# File lib/time_array/time_array.rb, line 95
def min
  @v.compact.min
rescue
  nil
end
month_count() click to toggle source

get the count of month hours

# File lib/time_array/time_array.rb, line 300
def month_count
  h = {}
  @v.size.times do |i|
    time = @start_time + i.hours
    h[time.month] ||= 0.0
    h[time.month] += 1
  end

  # @v.each_with_index do |value, i|
  #   time = @start_time + i.hours
  #   h[time.month] ||= 0.0
  #   h[time.month] += 1
  # end
  
  c = self.clone 
  c.size.times do |i|
    time = @start_time + i.hours
    c.set_value(i, h[time.month])
  end
  c
end
month_sum() click to toggle source
# File lib/time_array/time_array.rb, line 284
def month_sum
  h = {}
  @v.each_with_index do |value, i|
    time = @start_time + i.hours
    h[time.month] ||= 0.0
    h[time.month] += value
  end
  c = self.clone 
  c.size.times do |i|
    time = @start_time + i.hours
    c.set_value(i, h[time.month])
  end
  c
end
print_values() click to toggle source
round!(ndigit=3) click to toggle source

Round every values of the array

# File lib/time_array/time_array.rb, line 109
def round!(ndigit=3)
  @v.collect!{|e| e.nil? ? nil : e.round(ndigit)}
  self
end
set_value(index, new_value) click to toggle source
# File lib/time_array/time_array.rb, line 198
def set_value(index, new_value)
  @v[index]=new_value if index>=0 && index<@v.size
end
size() click to toggle source
# File lib/time_array/time_array.rb, line 48
def size
  @v.size
end
sum(options = {}) click to toggle source

get the sum of the values

# File lib/time_array/time_array.rb, line 54
def sum(options = {})
  if options[:values]
    opt = options[:values].to_sym
    case opt
    when :positive, :non_negative
      @v.sum_positive
    when :negative, :non_positive
      @v.sum_negative
    when :zero
      0.0
    when :all, :non_zero
      @v.sum_all
    else
      raise ArgumentError, "Option '#{opt}' not recognized"
    end
  else
    @v.sum_all
  end
end
time_zone() click to toggle source
# File lib/time_array/time_array.rb, line 34
def time_zone
  Time.zone
end
to_s() click to toggle source
# File lib/time_array/time_array.rb, line 162
def to_s
  "Start time: #{@start_time}\nData (size: #{@v.size}):\n#{print_values}"
end
until_the_end_of_the_year(fill_value=0.0) click to toggle source

mah!

# File lib/time_array/time_array.rb, line 167
def until_the_end_of_the_year(fill_value=0.0)
  t = Time.zone.parse("#{@start_time.year+1}-01-01")
  hh = (t-@start_time)/( 60 * 60) # final size
  @v += Vector.new(hh-@v.size, fill_value) if hh>@v.size
  self
end
value(index) click to toggle source
# File lib/time_array/time_array.rb, line 190
def value(index)
  @v[index]
end
value_at(datetime_or_year, month=nil, day=nil, hour=nil) click to toggle source

Get value associated to a date

# File lib/time_array/time_array.rb, line 339
def value_at(datetime_or_year, month=nil, day=nil, hour=nil)
  if datetime_or_year.is_a? Time
    dt = datetime_or_year
  else
    dt = Time.zone.parse("#{datetime_or_year}-#{month}-#{day} #{hour}:00")
  end
  i = ((dt - @start_time)/3600.0).to_i
  raise DateTimeOutRangeError if i<0 || i>(size-1)
  value(i)
end
zone() click to toggle source
# File lib/time_array/time_array.rb, line 30
def zone
  Time.zone.name
end

Private Instance Methods

expand(data) click to toggle source
# File lib/time_array/time_array.rb, line 389
def expand(data)
  vector = Vector.new
  raise NilStartTimeError if @start_time.nil?
  start_time = @start_time.clone

  prev_value = start_time.send(@unit)
  data.each do |v|
    while start_time.send(@unit)==prev_value
      vector << v
      start_time+=1.hour
    end
    prev_value = start_time.send(@unit)
  end
  vector
end
floor_start_time(t, unit=:hour) click to toggle source
# File lib/time_array/time_array.rb, line 431
def floor_start_time(t, unit=:hour)
  return nil if t.nil?
  case @unit
  # when :'15minutes'
  #   t = t - t.sec - (60 * (t.min % 15)) # floor to hour
  when :hour
    t = Time.zone.parse("#{t.year}-#{t.month}-#{t.day} #{t.hour}:00:00")
    # t = t - t.sec - (60 * (t.min % 60)) # floor to hour
  when :day
    t = Time.zone.parse("#{t.year}-#{t.month}-#{t.day}")
  when :month
    t = Time.zone.parse("#{t.year}-#{t.month}-01")
  when :year
    t = Time.zone.parse("#{t.year}-01-01")
  end
  t
end
manage_options(options) click to toggle source
# File lib/time_array/time_array.rb, line 451
def manage_options(options)
  options = options.symbolize_keys.assert_valid_keys(:unit, :zone)

  # unit
  options = {unit: :hour}.merge(options)
  @unit = options[:unit].to_sym
  Units.validate(@unit)

  # zone
  Time.zone = options[:zone] || "Rome"
end
oper(other_array, op) click to toggle source
# File lib/time_array/time_array.rb, line 365
def oper(other_array, op)
  return self if other_array.nil?
  raise NilVectorError if @v.nil? || (other_array.is_a?(TimeArray) && other_array.v.nil?)

  c = self.clone
  if other_array.is_a? Numeric
    default_value = other_array
  else
    c.align_with(other_array)
  end
  
  # c.data(Array.new(other_array.size){[:+, :-].include?(op) ? 0.0 : 1.0}) if @v.nil?
  c.size.times do |i|
    c.set_value(i, c.value(i).to_f.send(op, (default_value || other_array.value(i) || 0.0)))
  end
  c
end
read_start_time(start_time) click to toggle source

start_time must be a Time (or similar) or a String valid start_time “yyyy”, “yyyy-m”, “yyyy-mm”, “yyyy-mm-dd”, “yyyy-mm-dd yy”

# File lib/time_array/time_array.rb, line 415
def read_start_time(start_time)
  if start_time.is_a?(String)
    start_time.gsub!("/", "-")
    start_time = "20#{r[0]}-01-01" if r = start_time.match(/^\d{2}$/) # "yy"
    start_time = "#{r[0]}-01-01"   if r = start_time.match(/^\d{4}$/) # "yyyy"
    start_time = "#{r[0]}-01"      if r = start_time.match(/^\d{4}-\d{1,2}$/) # "yyyy-m" or "yyyy-mm"
    start_time = Time.zone.parse(start_time)
    raise ArgumentError, "Start time not valid" if start_time.nil?
  end
  start_time
end
set_start_time(start_time) click to toggle source
# File lib/time_array/time_array.rb, line 406
def set_start_time(start_time)
  st = read_start_time(start_time)
  @start_time = floor_start_time(st, @unit)
end
set_values(data) click to toggle source
# File lib/time_array/time_array.rb, line 383
def set_values(data)
  # the values are always stored as hour values
  @v = @unit==:hour ? Vector.new(data) : expand(data)
end