earth 0.3.15 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/Gemfile +1 -0
  2. data/earth.gemspec +4 -4
  3. data/features/automobile_fuel.feature +44 -0
  4. data/features/automobile_type_fuel_age.feature +2 -1
  5. data/features/automobile_type_fuel_year.feature +86 -16
  6. data/features/automobile_type_fuel_year_age.feature +94 -0
  7. data/features/automobile_type_fuel_year_control.feature +44 -4
  8. data/features/automobile_type_year.feature +27 -7
  9. data/features/carrier_mode.feature +20 -30
  10. data/features/fuel_year.feature +22 -12
  11. data/features/support/imports/automobile_fuel_bad.csv +3 -0
  12. data/features/support/imports/automobile_fuel_good.csv +3 -0
  13. data/features/support/imports/automobile_type_fuel_year_age_bad.csv +2 -0
  14. data/features/support/imports/automobile_type_fuel_year_age_good.csv +2 -0
  15. data/features/support/imports/automobile_type_fuel_year_bad.csv +2 -2
  16. data/features/support/imports/automobile_type_fuel_year_control_bad.csv +2 -3
  17. data/features/support/imports/automobile_type_fuel_year_control_good.csv +2 -3
  18. data/features/support/imports/automobile_type_fuel_year_good.csv +2 -2
  19. data/features/support/imports/automobile_type_year_bad.csv +2 -2
  20. data/features/support/imports/automobile_type_year_good.csv +2 -2
  21. data/features/support/imports/carrier_mode_bad.csv +2 -3
  22. data/features/support/imports/carrier_mode_good.csv +2 -3
  23. data/features/support/imports/fuel_year_bad.csv +2 -2
  24. data/features/support/imports/fuel_year_good.csv +2 -2
  25. data/lib/earth.rb +5 -5
  26. data/lib/earth/air/airline/data_miner.rb +1 -0
  27. data/lib/earth/air/airport/data_miner.rb +1 -1
  28. data/lib/earth/air/flight_segment/data_miner.rb +5 -0
  29. data/lib/earth/automobile.rb +2 -0
  30. data/lib/earth/automobile/automobile_fuel.rb +93 -0
  31. data/lib/earth/automobile/automobile_fuel/data_miner.rb +60 -0
  32. data/lib/earth/automobile/automobile_fuel_type.rb +1 -0
  33. data/lib/earth/automobile/automobile_fuel_type/data_miner.rb +2 -1
  34. data/lib/earth/automobile/automobile_make/data_miner.rb +11 -0
  35. data/lib/earth/automobile/automobile_make_fleet_year.rb +2 -2
  36. data/lib/earth/automobile/automobile_make_model.rb +1 -1
  37. data/lib/earth/automobile/automobile_make_model/data_miner.rb +1 -0
  38. data/lib/earth/automobile/automobile_make_model_year/data_miner.rb +1 -0
  39. data/lib/earth/automobile/automobile_make_model_year_variant.rb +2 -1
  40. data/lib/earth/automobile/automobile_make_model_year_variant/data_miner.rb +21 -7
  41. data/lib/earth/automobile/automobile_make_year.rb +2 -2
  42. data/lib/earth/automobile/automobile_make_year/data_miner.rb +3 -0
  43. data/lib/earth/automobile/automobile_size_class/data_miner.rb +11 -7
  44. data/lib/earth/automobile/automobile_size_class_year/data_miner.rb +2 -1
  45. data/lib/earth/automobile/automobile_type_fuel_age.rb +1 -0
  46. data/lib/earth/automobile/automobile_type_fuel_age/data_miner.rb +52 -34
  47. data/lib/earth/automobile/automobile_type_fuel_control/data_miner.rb +1 -1
  48. data/lib/earth/automobile/automobile_type_fuel_year.rb +7 -0
  49. data/lib/earth/automobile/automobile_type_fuel_year/data_miner.rb +57 -63
  50. data/lib/earth/automobile/automobile_type_fuel_year_age.rb +13 -0
  51. data/lib/earth/automobile/automobile_type_fuel_year_age/data_miner.rb +184 -0
  52. data/lib/earth/automobile/automobile_type_fuel_year_control.rb +6 -0
  53. data/lib/earth/automobile/automobile_type_fuel_year_control/data_miner.rb +24 -8
  54. data/lib/earth/automobile/automobile_type_year.rb +2 -0
  55. data/lib/earth/automobile/automobile_type_year/data_miner.rb +28 -11
  56. data/lib/earth/automobile/data_miner.rb +2 -0
  57. data/lib/earth/bus/bus_class.rb +8 -8
  58. data/lib/earth/computation/computation_platform/data_miner.rb +1 -1
  59. data/lib/earth/computation/server_type/data_miner.rb +1 -1
  60. data/lib/earth/computation/server_type_alias/data_miner.rb +1 -1
  61. data/lib/earth/conversions_ext.rb +4 -0
  62. data/lib/earth/fuel.rb +1 -0
  63. data/lib/earth/fuel/data_miner.rb +1 -0
  64. data/lib/earth/fuel/fuel.rb +77 -0
  65. data/lib/earth/fuel/fuel/data_miner.rb +98 -0
  66. data/lib/earth/fuel/fuel_type/data_miner.rb +2 -2
  67. data/lib/earth/fuel/fuel_year/data_miner.rb +95 -26
  68. data/lib/earth/fuel/greenhouse_gas.rb +6 -0
  69. data/lib/earth/fuel/greenhouse_gas/data_miner.rb +1 -1
  70. data/lib/earth/hospitality/lodging_class/data_miner.rb +21 -9
  71. data/lib/earth/locality/census_division.rb +6 -5
  72. data/lib/earth/locality/census_division/data_miner.rb +9 -9
  73. data/lib/earth/locality/country.rb +9 -0
  74. data/lib/earth/locality/country/data_miner.rb +1 -1
  75. data/lib/earth/pet/breed/data_miner.rb +0 -1
  76. data/lib/earth/pet/breed_gender/data_miner.rb +0 -1
  77. data/lib/earth/shipping/carrier.rb +3 -3
  78. data/lib/earth/shipping/carrier/data_miner.rb +2 -2
  79. data/lib/earth/shipping/carrier_mode/data_miner.rb +15 -42
  80. data/lib/earth/shipping/shipment_mode/data_miner.rb +1 -1
  81. data/lib/earth/version.rb +1 -1
  82. data/spec/earth/automobile/automobile_fuel_spec.rb +19 -0
  83. data/spec/earth_spec.rb +3 -3
  84. metadata +141 -33
@@ -25,7 +25,7 @@ AutomobileTypeFuelControl.class_eval do
25
25
  AutomobileTypeFuelControl.all.each do |record|
26
26
  %w{ type_name fuel_common_name control_name }.each do |attribute|
27
27
  value = record.send(:"#{attribute}")
28
- if value.nil?
28
+ unless value.present?
29
29
  raise "Missing #{attribute} for AutomobileTypeFuelControl '#{record.name}'"
30
30
  end
31
31
  end
@@ -1,7 +1,14 @@
1
1
  class AutomobileTypeFuelYear < ActiveRecord::Base
2
2
  set_primary_key :name
3
3
 
4
+ has_many :year_controls, :class_name => 'AutomobileTypeFuelYearControl', :foreign_key => 'type_fuel_year_name'
5
+ belongs_to :type_year, :class_name => 'AutomobileTypeYear', :foreign_key => 'type_year_name'
6
+
4
7
  data_miner do
5
8
  tap "Brighter Planet's sanitized automobile type fuel year data", Earth.taps_server
9
+
10
+ process "pull dependencies" do
11
+ run_data_miner_on_belongs_to_associations
12
+ end
6
13
  end
7
14
  end
@@ -5,6 +5,7 @@ AutomobileTypeFuelYear.class_eval do
5
5
  string 'type_name'
6
6
  string 'fuel_common_name'
7
7
  integer 'year'
8
+ string 'type_year_name'
8
9
  float 'total_travel'
9
10
  string 'total_travel_units'
10
11
  float 'fuel_consumption'
@@ -13,15 +14,14 @@ AutomobileTypeFuelYear.class_eval do
13
14
  string 'ch4_emission_factor_units'
14
15
  float 'n2o_emission_factor'
15
16
  string 'n2o_emission_factor_units'
16
- float 'hfc_emission_factor'
17
- string 'hfc_emission_factor_units'
18
17
  end
19
18
 
20
19
  import "total vehicle miles travelled by gasoline passenger cars from the 2010 EPA GHG Inventory",
21
20
  :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
22
21
  :filename => 'Annex Tables/Annex 3/Table A-87.csv',
23
- :skip => 1 do
24
- key 'name', :synthesize => lambda { |row| "Passenger cars gasoline #{row['Year']}" if row['Year'].length < 5 }
22
+ :skip => 1,
23
+ :select => lambda { |row| row['Year'].to_i.to_s == row['Year'] } do
24
+ key 'name', :synthesize => lambda { |row| "Passenger cars gasoline #{row['Year']}" }
25
25
  store 'type_name', :static => 'Passenger cars'
26
26
  store 'fuel_common_name', :static => 'gasoline'
27
27
  store 'year', :field_name => 'Year'
@@ -31,8 +31,9 @@ AutomobileTypeFuelYear.class_eval do
31
31
  import "total vehicle miles travelled by gasoline light-duty trucks from the 2010 EPA GHG Inventory",
32
32
  :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
33
33
  :filename => 'Annex Tables/Annex 3/Table A-87.csv',
34
- :skip => 1 do
35
- key 'name', :synthesize => lambda { |row| "Light-duty trucks gasoline #{row['Year']}" if row['Year'].length < 5 }
34
+ :skip => 1,
35
+ :select => lambda { |row| row['Year'].to_i.to_s == row['Year'] } do
36
+ key 'name', :synthesize => lambda { |row| "Light-duty trucks gasoline #{row['Year']}" }
36
37
  store 'type_name', :static => 'Light-duty trucks'
37
38
  store 'fuel_common_name', :static => 'gasoline'
38
39
  store 'year', :field_name => 'Year'
@@ -42,8 +43,9 @@ AutomobileTypeFuelYear.class_eval do
42
43
  import "total vehicle miles travelled by diesel passenger cars from the 2010 EPA GHG Inventory",
43
44
  :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
44
45
  :filename => 'Annex Tables/Annex 3/Table A-88.csv',
45
- :skip => 1 do
46
- key 'name', :synthesize => lambda { |row| "Passenger cars diesel #{row['Year']}" if row['Year'].length < 5 }
46
+ :skip => 1,
47
+ :select => lambda { |row| row['Year'].to_i.to_s == row['Year'] } do
48
+ key 'name', :synthesize => lambda { |row| "Passenger cars diesel #{row['Year']}" }
47
49
  store 'type_name', :static => 'Passenger cars'
48
50
  store 'fuel_common_name', :static => 'diesel'
49
51
  store 'year', :field_name => 'Year'
@@ -53,8 +55,9 @@ AutomobileTypeFuelYear.class_eval do
53
55
  import "total vehicle miles travelled by diesel light-duty trucks from the 2010 EPA GHG Inventory",
54
56
  :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
55
57
  :filename => 'Annex Tables/Annex 3/Table A-88.csv',
56
- :skip => 1 do
57
- key 'name', :synthesize => lambda { |row| "Light-duty trucks diesel #{row['Year']}" if row['Year'].length < 5 }
58
+ :skip => 1,
59
+ :select => lambda { |row| row['Year'].to_i.to_s == row['Year'] } do
60
+ key 'name', :synthesize => lambda { |row| "Light-duty trucks diesel #{row['Year']}" }
58
61
  store 'type_name', :static => 'Light-duty trucks'
59
62
  store 'fuel_common_name', :static => 'diesel'
60
63
  store 'year', :field_name => 'Year'
@@ -63,8 +66,12 @@ AutomobileTypeFuelYear.class_eval do
63
66
 
64
67
  process "Convert total travel from billion miles to kilometres" do
65
68
  conversion_factor = 1_000_000_000.miles.to(:kilometres)
66
- update_all "total_travel = total_travel * #{conversion_factor}"
67
- update_all "total_travel_units = 'kilometres'"
69
+ connection.execute %{
70
+ UPDATE automobile_type_fuel_years
71
+ SET total_travel = total_travel * #{conversion_factor},
72
+ total_travel_units = 'kilometres'
73
+ WHERE total_travel_units = 'billion_miles'
74
+ }
68
75
  end
69
76
 
70
77
  import "fuel consumption derived from the 2010 EPA GHG Inventory",
@@ -73,47 +80,40 @@ AutomobileTypeFuelYear.class_eval do
73
80
  store 'fuel_consumption', :units_field_name => 'fuel_consumption_units'
74
81
  end
75
82
 
76
- process "Calculate CH4 and N2O emision factors from AutomobileTypeFuelYearControl and AutomobileTypeFuelControl" do
77
- AutomobileTypeFuelYearControl.run_data_miner!
78
- AutomobileTypeFuelControl.run_data_miner!
79
-
80
- year_controls = AutomobileTypeFuelYearControl.arel_table
81
- controls = AutomobileTypeFuelControl.arel_table
82
- years = AutomobileTypeFuelYear.arel_table
83
-
84
- join_relation = controls[:type_name].eq(year_controls[:type_name]).and(controls[:fuel_common_name].eq(year_controls[:fuel_common_name])).and(controls[:control_name].eq(year_controls[:control_name]))
85
- where_relation = year_controls[:type_name].eq(years[:type_name]).and(year_controls[:fuel_common_name].eq(years[:fuel_common_name])).and(year_controls[:year].eq(years[:year]))
86
-
87
- %w{ ch4 n2o }.each do |gas|
88
- update_all "#{gas}_emission_factor = (
89
- SELECT SUM(automobile_type_fuel_year_controls.total_travel_percent * automobile_type_fuel_controls.#{gas}_emission_factor)
90
- FROM automobile_type_fuel_year_controls
91
- INNER JOIN automobile_type_fuel_controls
92
- ON #{join_relation.to_sql}
93
- WHERE #{where_relation.to_sql}) * total_travel / fuel_consumption"
94
- update_all "#{gas}_emission_factor_units = 'kilograms_per_litre'"
83
+ process "Derive type year name for association with AutomobileTypeYear" do
84
+ if ActiveRecord::Base.connection.adapter_name.downcase == 'sqlite'
85
+ update_all "type_year_name = type_name || ' ' || year"
86
+ else
87
+ update_all "type_year_name = CONCAT(type_name, ' ', year)"
95
88
  end
96
89
  end
97
90
 
98
- process "Calculate HFC emission factor from AutomobileTypeYear" do
99
- AutomobileTypeYear.run_data_miner!
100
- type_fuel_years = AutomobileTypeFuelYear.arel_table
101
- type_years = AutomobileTypeYear.arel_table
91
+ process "Calculate CH4 and N2O emision factors from AutomobileTypeFuelYearControl and AutomobileTypeFuelControl" do
92
+ AutomobileTypeFuelYearControl.run_data_miner!
93
+ AutomobileTypeFuelControl.run_data_miner!
102
94
 
103
95
  AutomobileTypeFuelYear.all.each do |record|
104
- fuel_consumption = AutomobileTypeFuelYear.find_all_by_type_name_and_year(record.type_name, record.year).map{|x| x.fuel_consumption}.sum
105
- hfc_emissions_sql = type_years.project(type_years[:hfc_emissions]).where(type_years[:type_name].eq(record.type_name).and(type_years[:year].eq(record.year))).to_sql
106
- connection.execute "UPDATE automobile_type_fuel_years SET hfc_emission_factor = ((#{hfc_emissions_sql}) / #{fuel_consumption}) WHERE type_name = '#{record.type_name}' AND year = #{record.year}"
96
+ record.ch4_emission_factor = record.year_controls.map do |year_control|
97
+ year_control.total_travel_percent * year_control.control.ch4_emission_factor
98
+ end.sum * record.total_travel / record.fuel_consumption
99
+
100
+ record.n2o_emission_factor = record.year_controls.map do |year_control|
101
+ year_control.total_travel_percent * year_control.control.n2o_emission_factor
102
+ end.sum * record.total_travel / record.fuel_consumption
103
+
104
+ record.ch4_emission_factor_units = 'kilograms_per_litre'
105
+ record.n2o_emission_factor_units = 'kilograms_per_litre'
106
+
107
+ record.save
107
108
  end
108
- update_all "hfc_emission_factor_units = 'kilograms_co2e_per_litre'"
109
109
  end
110
110
 
111
- verify "Type name and fuel common name should never be missing" do
112
- AutomobileTypeFuelYear.all.each do |record|
113
- %w{ type_name fuel_common_name }.each do |attribute|
111
+ %w{ type_name fuel_common_name type_year_name }.each do |attribute|
112
+ verify "#{attribute.humanize} should never be missing" do
113
+ AutomobileTypeFuelYear.all.each do |record|
114
114
  value = record.send(:"#{attribute}")
115
- if value.nil?
116
- raise "Missing #{attribute} for AutomobileTypeFuelYear '#{record.name}'"
115
+ unless value.present?
116
+ raise "Missing #{attribute.humanize.downcase} for AutomobileTypeFuelYear '#{record.name}'"
117
117
  end
118
118
  end
119
119
  end
@@ -128,34 +128,28 @@ AutomobileTypeFuelYear.class_eval do
128
128
  end
129
129
  end
130
130
 
131
- verify "Total travel, fuel consumption, and emission factors should be greater than zero" do
132
- AutomobileTypeFuelYear.all.each do |record|
133
- %w{ total_travel fuel_consumption ch4_emission_factor n2o_emission_factor }.each do |attribute|
131
+ %w{ total_travel fuel_consumption ch4_emission_factor n2o_emission_factor }.each do |attribute|
132
+ verify "#{attribute.humanize} should be greater than zero" do
133
+ AutomobileTypeFuelYear.all.each do |record|
134
134
  value = record.send(:"#{attribute}")
135
135
  unless value > 0
136
- raise "Invalid #{attribute} for AutomobileTypeFuelYear '#{record.name}': #{value} (should be > 0)"
136
+ raise "Invalid #{attribute.humanize.downcase} for AutomobileTypeFuelYear '#{record.name}': #{value} (should be > 0)"
137
137
  end
138
138
  end
139
139
  end
140
140
  end
141
141
 
142
- verify "HFC emission factor should be zero or more" do
143
- AutomobileTypeFuelYear.all.each do |record|
144
- value = record.send(:hfc_emission_factor)
145
- unless value >= 0
146
- raise "Invalid HFC emission factor for AutomobileTypeFuelYear '#{record.name}': #{value} (should be >= 0)"
147
- end
148
- end
149
- end
150
-
151
- verify "Units should be correct" do
152
- AutomobileTypeFuelYear.all.each do |record|
153
- ["total_travel_units kilometres", "fuel_consumption_units litres", "ch4_emission_factor_units kilograms_per_litre", "n2o_emission_factor_units kilograms_per_litre", "hfc_emission_factor_units kilograms_co2e_per_litre"].each do |pair|
154
- attribute = pair.split[0]
155
- proper_units = pair.split[1]
142
+ [["total_travel_units", "kilometres"],
143
+ ["fuel_consumption_units", "litres"],
144
+ ["ch4_emission_factor_units", "kilograms_per_litre"],
145
+ ["n2o_emission_factor_units", "kilograms_per_litre"]].each do |pair|
146
+ attribute = pair[0]
147
+ proper_units = pair[1]
148
+ verify "#{attribute.humanize} should be #{proper_units.humanize.downcase}" do
149
+ AutomobileTypeFuelYear.all.each do |record|
156
150
  units = record.send(:"#{attribute}")
157
151
  unless units == proper_units
158
- raise "Invalid #{attribute} for AutomobileTypeFuelYear '#{record.name}': #{units} (should be #{proper_units})"
152
+ raise "Invalid #{attribute.humanize.downcase} for AutomobileTypeFuelYear '#{record.name}': #{units} (should be #{proper_units})"
159
153
  end
160
154
  end
161
155
  end
@@ -0,0 +1,13 @@
1
+ class AutomobileTypeFuelYearAge < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ belongs_to :type_fuel_year, :class_name => 'AutomobileTypeFuelYear', :foreign_key => 'type_fuel_year_name'
5
+
6
+ data_miner do
7
+ tap "Brighter Planet's sanitized automobile type fuel age", Earth.taps_server
8
+
9
+ process "Pull dependencies" do
10
+ run_data_miner_on_belongs_to_associations
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,184 @@
1
+ AutomobileTypeFuelYearAge.class_eval do
2
+ data_miner do
3
+ schema Earth.database_options do
4
+ string 'name'
5
+ string 'type_name'
6
+ string 'fuel_common_name'
7
+ integer 'year'
8
+ integer 'age'
9
+ string 'type_fuel_year_name'
10
+ float 'total_travel_percent'
11
+ float 'annual_distance'
12
+ string 'annual_distance_units'
13
+ integer 'vehicles'
14
+ end
15
+
16
+ import "total travel distribution of gasoline passenger cars from the 2010 EPA GHG Inventory",
17
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
18
+ :filename => 'Annex Tables/Annex 3/Table A-93.csv',
19
+ :skip => 1,
20
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
21
+ key 'name', :synthesize => lambda { |row| "Passenger cars gasoline 2008 age #{row['Vehicle Age']}" }
22
+ store 'type_name', :static => 'Passenger cars'
23
+ store 'fuel_common_name', :static => 'gasoline'
24
+ store 'year', :static => '2008'
25
+ store 'age', :field_name => 'Vehicle Age'
26
+ store 'total_travel_percent', :synthesize => lambda { |row| row['LDGV'].to_f / 100 }
27
+ end
28
+
29
+ import "total travel distribution of gasoline light-duty trucks from the 2010 EPA GHG Inventory",
30
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
31
+ :filename => 'Annex Tables/Annex 3/Table A-93.csv',
32
+ :skip => 1,
33
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
34
+ key 'name', :synthesize => lambda { |row| "Light-duty trucks gasoline 2008 age #{row['Vehicle Age']}" }
35
+ store 'type_name', :static => 'Light-duty trucks'
36
+ store 'fuel_common_name', :static => 'gasoline'
37
+ store 'year', :static => '2008'
38
+ store 'age', :field_name => 'Vehicle Age'
39
+ store 'total_travel_percent', :synthesize => lambda { |row| row['LDGT'].to_f / 100 }
40
+ end
41
+
42
+ import "total travel distribution of diesel passenger cars from the 2010 EPA GHG Inventory",
43
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
44
+ :filename => 'Annex Tables/Annex 3/Table A-93.csv',
45
+ :skip => 1,
46
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
47
+ key 'name', :synthesize => lambda { |row| "Passenger cars diesel 2008 age #{row['Vehicle Age']}" }
48
+ store 'type_name', :static => 'Passenger cars'
49
+ store 'fuel_common_name', :static => 'diesel'
50
+ store 'year', :static => '2008'
51
+ store 'age', :field_name => 'Vehicle Age'
52
+ store 'total_travel_percent', :synthesize => lambda { |row| row['LDDV'].to_f / 100 }
53
+ end
54
+
55
+ import "total travel distribution of diesel light-duty trucks from the 2010 EPA GHG Inventory",
56
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
57
+ :filename => 'Annex Tables/Annex 3/Table A-93.csv',
58
+ :skip => 1,
59
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
60
+ key 'name', :synthesize => lambda { |row| "Light-duty trucks diesel 2008 age #{row['Vehicle Age']}" }
61
+ store 'type_name', :static => 'Light-duty trucks'
62
+ store 'fuel_common_name', :static => 'diesel'
63
+ store 'year', :static => '2008'
64
+ store 'age', :field_name => 'Vehicle Age'
65
+ store 'total_travel_percent', :synthesize => lambda { |row| row['LDDT'].to_f / 100 }
66
+ end
67
+
68
+ import "average annual distance for gasoline passenger cars from the 2010 EPA GHG Inventory",
69
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
70
+ :filename => 'Annex Tables/Annex 3/Table A-92.csv',
71
+ :skip => 1,
72
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
73
+ key 'name', :synthesize => lambda { |row| "Passenger cars gasoline 2008 age #{row['Vehicle Age']}" }
74
+ store 'annual_distance', :synthesize => lambda { |row| row['LDGV'].to_s.sub(',', '') }, :units => :miles
75
+ end
76
+
77
+ import "average annual distance for gasoline light-duty trucks from the 2010 EPA GHG Inventory",
78
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
79
+ :filename => 'Annex Tables/Annex 3/Table A-92.csv',
80
+ :skip => 1,
81
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
82
+ key 'name', :synthesize => lambda { |row| "Light-duty trucks gasoline 2008 age #{row['Vehicle Age']}" }
83
+ store 'annual_distance', :synthesize => lambda { |row| row['LDGT'].to_s.sub(',', '') }, :units => :miles
84
+ end
85
+
86
+ import "average annual distance for diesel passenger cars from the 2010 EPA GHG Inventory",
87
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
88
+ :filename => 'Annex Tables/Annex 3/Table A-92.csv',
89
+ :skip => 1,
90
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
91
+ key 'name', :synthesize => lambda { |row| "Passenger cars diesel 2008 age #{row['Vehicle Age']}" }
92
+ store 'annual_distance', :synthesize => lambda { |row| row['LDDV'].to_s.sub(',', '') }, :units => :miles
93
+ end
94
+
95
+ import "average annual distance for diesel light-duty trucks from the 2010 EPA GHG Inventory",
96
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
97
+ :filename => 'Annex Tables/Annex 3/Table A-92.csv',
98
+ :skip => 1,
99
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] } do
100
+ key 'name', :synthesize => lambda { |row| "Light-duty trucks diesel 2008 age #{row['Vehicle Age']}" }
101
+ store 'annual_distance', :synthesize => lambda { |row| row['LDDT'].to_s.sub(',', '') }, :units => :miles
102
+ end
103
+
104
+ process "Convert annual distance from miles to kilometres" do
105
+ conversion_factor = 1.miles.to(:kilometres)
106
+ connection.execute %{
107
+ UPDATE automobile_type_fuel_year_ages
108
+ SET annual_distance = annual_distance * #{conversion_factor},
109
+ annual_distance_units = 'kilometres'
110
+ WHERE annual_distance_units = 'miles'
111
+ }
112
+ end
113
+
114
+ process "Derive type fuel year name for association with AutomobileTypeFuelYear" do
115
+ if ActiveRecord::Base.connection.adapter_name == 'sqlite'
116
+ update_all "type_fuel_year_name = type_name || ' ' || fuel_common_name || ' ' year"
117
+ else
118
+ update_all "type_fuel_year_name = CONCAT(type_name, ' ', fuel_common_name, ' ', year)"
119
+ end
120
+ end
121
+
122
+ process "Calculate number of vehicles from total travel percent and AutomobileTypeFuelYear" do
123
+ AutomobileTypeFuelYear.run_data_miner!
124
+ AutomobileTypeFuelYearAge.all.each do |record|
125
+ record.vehicles = record.total_travel_percent * record.type_fuel_year.total_travel / record.annual_distance
126
+ record.save
127
+ end
128
+ end
129
+
130
+ %w{ type_name fuel_common_name type_fuel_year_name}.each do |attribute|
131
+ verify "#{attribute.humanize} should never be missing" do
132
+ AutomobileTypeFuelYearAge.all.each do |record|
133
+ value = record.send(:"#{attribute}")
134
+ unless value.present?
135
+ raise "Missing #{attribute.humanize.downcase} for AutomobileTypeFuelYearAge '#{record.name}'"
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ verify "Year should be 2008" do
142
+ AutomobileTypeFuelYearAge.all.each do |record|
143
+ value = record.send(:year)
144
+ unless value == 2008
145
+ raise "Invalid year for AutomobileTypeFuelYearAge '#{record.name}': #{value} (should be 2008)"
146
+ end
147
+ end
148
+ end
149
+
150
+ [["age", 0, 30], ["total_travel_percent", 0, 1]].each do |triplet|
151
+ attribute = triplet[0]
152
+ min = triplet[1]
153
+ max = triplet[2]
154
+ verify "#{attribute.humanize} should be from #{min} to #{max}" do
155
+ AutomobileTypeFuelYearAge.all.each do |record|
156
+ value = record.send(:"#{attribute}")
157
+ unless value >= min and value <= max
158
+ raise "Invalid #{attribute.humanize.downcase} for AutomobileTypeFuelYearAge '#{record.name}': #{value} (should be from #{min} to #{max})"
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ %w{ annual_distance vehicles }.each do |attribute|
165
+ verify "#{attribute.humanize} should be greater than zero" do
166
+ AutomobileTypeFuelYearAge.all.each do |record|
167
+ value = record.send(:"#{attribute}")
168
+ unless value > 0
169
+ raise "Invalid #{attribute.humanize.downcase} for AutomobileTypeFuelYearAge '#{record.name}': #{value} (should be > 0)"
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ verify "Annual distance units should be kilometres" do
176
+ AutomobileTypeFuelYearAge.all.each do |record|
177
+ units = record.send(:annual_distance_units)
178
+ unless units == "kilometres"
179
+ raise "Invalid annual distance units for AutomobileTypeFuelYearAge '#{record.name}': #{units} (should be kilometres)"
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -1,7 +1,13 @@
1
1
  class AutomobileTypeFuelYearControl < ActiveRecord::Base
2
2
  set_primary_key :name
3
3
 
4
+ belongs_to :control, :class_name => 'AutomobileTypeFuelControl', :foreign_key => 'type_fuel_control_name'
5
+
4
6
  data_miner do
5
7
  tap "Brighter Planet's sanitized automobile type fuel year control data", Earth.taps_server
8
+
9
+ process "Pull dependencies" do
10
+ run_data_miner_on_belongs_to_associations
11
+ end
6
12
  end
7
13
  end
@@ -6,6 +6,8 @@ AutomobileTypeFuelYearControl.class_eval do
6
6
  string 'fuel_common_name'
7
7
  integer 'year'
8
8
  string 'control_name'
9
+ string 'type_fuel_control_name'
10
+ string 'type_fuel_year_name'
9
11
  float 'total_travel_percent'
10
12
  end
11
13
 
@@ -19,12 +21,28 @@ AutomobileTypeFuelYearControl.class_eval do
19
21
  store 'total_travel_percent'
20
22
  end
21
23
 
22
- verify "Type name, fuel common name, and control name should never be missing" do
23
- AutomobileTypeFuelYearControl.all.each do |record|
24
- %w{ type_name fuel_common_name control_name }.each do |attribute|
24
+ process "Derive type fuel control name for association with AutomobileTypeFuelControl" do
25
+ if ActiveRecord::Base.connection.adapter_name.downcase == 'sqlite'
26
+ update_all "type_fuel_control_name = type_name || ' ' || fuel_common_name || ' ' || control_name"
27
+ else
28
+ update_all "type_fuel_control_name = CONCAT(type_name, ' ', fuel_common_name, ' ', control_name)"
29
+ end
30
+ end
31
+
32
+ process "Derive type fuel year name for association with AutomobileTypeFuelYear" do
33
+ if ActiveRecord::Base.connection.adapter_name.downcase == 'sqlite'
34
+ update_all "type_fuel_year_name = type_name || ' ' || fuel_common_name || ' ' || year"
35
+ else
36
+ update_all "type_fuel_year_name = CONCAT(type_name, ' ', fuel_common_name, ' ', year)"
37
+ end
38
+ end
39
+
40
+ %w{ type_name fuel_common_name control_name type_fuel_control_name type_fuel_year_name }.each do |attribute|
41
+ verify "#{attribute.humanize} should never be missing" do
42
+ AutomobileTypeFuelYearControl.all.each do |record|
25
43
  value = record.send(:"#{attribute}")
26
- if value.nil?
27
- raise "Missing #{attribute} for AutomobileTypeFuelYearControl '#{record.name}'"
44
+ unless value.present?
45
+ raise "Missing #{attribute.humanize.downcase} for AutomobileTypeFuelYearControl '#{record.name}'"
28
46
  end
29
47
  end
30
48
  end
@@ -39,8 +57,6 @@ AutomobileTypeFuelYearControl.class_eval do
39
57
  end
40
58
  end
41
59
 
42
- # FIXME TODO
43
- # verify "Total travel percent for each type fuel year should sum to one" do
44
- # end
60
+ # FIXME TODO verify "Total travel percent for each type fuel year should sum to one"
45
61
  end
46
62
  end