class AnalysisWindow

The Analysis Window

The analysis window is defined by an analysis window configuration file.

They are aware of the geographical and temporal bounds of the study and handle all of the helper functions for performing calculations. All Queries happen through the analysis window and the method missing located within defines functions such as nodes_x_month.

Attributes

bounding_box[R]

The BoundingBox object instance for this analysis window

max_area[R]

The maximum area (in square meters) of changesets to be included in calculations

min_area[R]

The minimum area (in square meters) of changesets to be included in calculations

time_frame[R]

The TimeFrame object instance for this analysis window

Public Class Methods

new(args={}) click to toggle source

Can pass in an instance of a timeframe and bounding box, or use defaults

# File models/AnalysisWindow.rb, line 23
def initialize(args={})
        @bounding_box = args[:bounding_box] || BoundingBox.new
        @time_frame   = args[:time_frame]   || TimeFrame.new

        @max_area = args[:max_area] || 1000000000000
        @min_area = args[:min_area] || 1

        post_initialize
end

Public Instance Methods

build_buckets(unit=:all, step=1) click to toggle source

Buckets are temporal units which the query results are binned into.

Buckets can be defined with multiple units and steps. Defaults to just one bucket, the size of the analysis window.

# File models/AnalysisWindow.rb, line 44
def build_buckets(unit=:all, step=1)
        hour   = 60 * 60
        day    = 24 * hour

        if step.nil?
                step = 1
        end

        if unit.nil?
                unit = :all
        end

        buckets = []
        
        case unit
        when :all
                buckets << {start_date: time_frame.start_date, end_date: time_frame.end_date, objects: []}
        
        when :year
                year = time_frame.start_date.year
                bucket_start = Time.mktime(year, 1, 1)
                while bucket_start < time_frame.end_date
                        bucket_end   = Time.mktime(year+=step, 1, 1)
                        buckets << {start_date: bucket_start, end_date: bucket_end, objects: []}
                        bucket_start = bucket_end
                end

        when :month
                month = time_frame.start_date.mon
                year  = time_frame.start_date.year
                bucket_start = time_frame.start_date
                while bucket_start < time_frame.end_date
                        bucket_start = Time.mktime( year, (month) )
                        
                        month+=step
                        if (month-12) > 0
                                year  += 1
                            month = month-12
                        end
                        
                        bucket_end   = Time.mktime(year, (month) )
                        buckets << {start_date: bucket_start, end_date: bucket_end, objects: []}
                end

        when :day
                bucket_start = Time.mktime(time_frame.start_date.year, time_frame.start_date.mon, time_frame.start_date.day)
                while bucket_start < time_frame.end_date
                        bucket_end   = Time.at( bucket_start.to_i + step*day )
                        buckets << {start_date: bucket_start, end_date: bucket_end, objects: []}
                        bucket_start = bucket_end
                end
        
        when :week
                #fuck us, this is going to be ugly.  How should we do this? just start from the first week of the analysis window?
                #We could just add 7 days.

        when :hour
                bucket_start = Time.mktime(time_frame.start_date.year, time_frame.start_date.mon, time_frame.start_date.day, time_frame.start_date.hour)
                while bucket_start < time_frame.end_date
                        bucket_end   = Time.at( bucket_start.to_i + step*hour )
                        buckets << {start_date: bucket_start, end_date: bucket_end, objects: []}
                        bucket_start = bucket_end
                end
        end

        buckets.first[:start_date] = time_frame.start_date
        buckets.last[:end_date]    = time_frame.end_date

        return buckets
end
method_missing(m, *args, &block) click to toggle source

Method Missing

The Analysis window overrides method-missing to offer new functions such as changesets_x_day

Calls superclass method
# File models/AnalysisWindow.rb, line 118
def method_missing(m, *args, &block)
        # puts "Called method missing with this function: #{m} and these args: #{args}"
        begin
                #Break out the method by snake case
                pieces = m.to_s.split(/\_/)

                #Find the nodes_x_all, changesets_x_month, ways_x_yearly type of functions
                if pieces[1] == 'x'

                        unless args.empty?
                                cons = args[0][:constraints] #Better pass a hash
                                step = args[0][:step] || 1
                        end
                        
                        instance_eval "@#{pieces[2]}_#{pieces[0]} ||= #{pieces[0]}.run(unit: :#{pieces[2]}, step: step, constraints: cons)"
                end

        rescue => e
                puts $!
                super
        end
end
post_initialize() click to toggle source

If the frame failed or doesn't exist, then use all of the data by default

# File models/AnalysisWindow.rb, line 34
def post_initialize
        unless time_frame.active?
                @time_frame = TimeFrame.new( start_date: Changeset_Query.earliest_changeset_date, end_date:   Changeset_Query.latest_changeset_date )
        end
end

Changesets

↑ top

Public Instance Methods

changeset_count() click to toggle source

Get the number of changesets in the analysis window.

# File models/AnalysisWindow.rb, line 151
def changeset_count
        changesets_x_all.first[:objects].count
end
changesets() click to toggle source

Access the changesets query

# File models/AnalysisWindow.rb, line 144
def changesets
        @changesets ||= Changeset_Query.new(analysis_window: self)
end
distinct_users_in_changesets() click to toggle source
# File models/AnalysisWindow.rb, line 158
def distinct_users_in_changesets
        changesets_x_all.first[:objects].collect{|changeset| changeset.uid}.uniq
end

Nodes

↑ top

Public Instance Methods

node_added_count() click to toggle source
# File models/AnalysisWindow.rb, line 173
def node_added_count
        nodes_x_all.first[:objects].select{|node| node.version == 1}.count
end
node_edit_count() click to toggle source
# File models/AnalysisWindow.rb, line 168
def node_edit_count
        nodes_x_all.first[:objects].count
end
nodes() click to toggle source
# File models/AnalysisWindow.rb, line 163
def nodes
        @nodes ||= Node_Query.new( analysis_window: self )
end

Relations

↑ top

Public Instance Methods

relation_added_count() click to toggle source
# File models/AnalysisWindow.rb, line 203
def relation_added_count
        relations_x_all.first[:objects].select{|relation| relation.version == 1}.count
end
relation_edit_count() click to toggle source
# File models/AnalysisWindow.rb, line 198
def relation_edit_count
        relations_x_all.first[:objects].count
end
relations() click to toggle source
# File models/AnalysisWindow.rb, line 193
def relations
        @relations ||= Relation_Query.new( analysis_window: self )
end

Users

↑ top

Public Instance Methods

all_users_data() click to toggle source
# File models/AnalysisWindow.rb, line 208
def all_users_data
        User_Query.new(uids: distinct_users_in_changesets).run                
end
experienced_contributors() click to toggle source
# File models/AnalysisWindow.rb, line 227
def experienced_contributors
        all_users_data.select{|user| user.account_created < time_frame.start_date}.collect{|user| user.user}
end
new_contributors() click to toggle source
# File models/AnalysisWindow.rb, line 222
def new_contributors
        all_users_data.select{|user| user.account_created > time_frame.start_date and user.account_created < time_frame.end_date}.collect{|user| user.user}
end
top_contributors_by_changesets(args={limit: 5, unit: :all_time }) click to toggle source
# File models/AnalysisWindow.rb, line 232
def top_contributors_by_changesets(args={limit: 5, unit: :all_time })

        case args[:unit]
        when :all_time
                changesets_per_unit = changesets_x_all.first[:objects].group_by{|changeset| changeset.user}.sort_by{|k,v| v.length}.reverse
        when :month
                changesets_per_unit = changesets_x_month.group_by{|changeset| changeset.created_at.to_i / 100000}
        end
        changesets_per_unit.first(args[:limit])
end
users_editing_per_year() click to toggle source
# File models/AnalysisWindow.rb, line 213
def users_editing_per_year
        years = {}
        changesets_x_year.each do |bucket|
                years[ bucket[:start_date] ] = bucket[:objects].collect{|changeset| changeset.user}.uniq
        end
        years
end

Ways

↑ top

Public Instance Methods

way_added_count() click to toggle source
# File models/AnalysisWindow.rb, line 188
def way_added_count
        ways_x_all.first[:objects].select{|way| way.version == 1}.count
end
way_edit_count() click to toggle source
# File models/AnalysisWindow.rb, line 183
def way_edit_count
        ways_x_all.first[:objects].count
end
ways() click to toggle source
# File models/AnalysisWindow.rb, line 178
def ways
        @ways ||= Way_Query.new( analysis_window: self )
end