earth 0.7.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. data/certification_changelog.markdown +21 -0
  2. data/lib/earth/air.rb +0 -2
  3. data/lib/earth/air/aircraft.rb +77 -27
  4. data/lib/earth/air/aircraft/data_miner.rb +12 -19
  5. data/lib/earth/air/aircraft_instance.rb +2 -0
  6. data/lib/earth/air/aircraft_instance_seat_class.rb +1 -0
  7. data/lib/earth/air/airport/data_miner.rb +1 -1
  8. data/lib/earth/air/data_miner.rb +0 -2
  9. data/lib/earth/air/flight_distance_class.rb +2 -3
  10. data/lib/earth/air/flight_distance_class/data_miner.rb +0 -13
  11. data/lib/earth/air/flight_distance_class_seat_class.rb +3 -2
  12. data/lib/earth/air/flight_seat_class.rb +0 -6
  13. data/lib/earth/air/flight_seat_class/data_miner.rb +0 -7
  14. data/lib/earth/air/flight_segment.rb +47 -53
  15. data/lib/earth/air/flight_segment/data_miner.rb +2 -2
  16. data/lib/earth/automobile.rb +4 -3
  17. data/lib/earth/automobile/automobile_fuel.rb +56 -119
  18. data/lib/earth/automobile/automobile_fuel/data_miner.rb +17 -4
  19. data/lib/earth/automobile/automobile_make.rb +1 -16
  20. data/lib/earth/automobile/automobile_make/data_miner.rb +25 -25
  21. data/lib/earth/automobile/automobile_make_model.rb +0 -26
  22. data/lib/earth/automobile/automobile_make_model/data_miner.rb +12 -13
  23. data/lib/earth/automobile/automobile_make_model_year.rb +6 -37
  24. data/lib/earth/automobile/automobile_make_model_year/data_miner.rb +34 -18
  25. data/lib/earth/automobile/automobile_make_model_year_variant.rb +27 -49
  26. data/lib/earth/automobile/automobile_make_model_year_variant/data_miner.rb +111 -140
  27. data/lib/earth/automobile/automobile_make_year.rb +0 -12
  28. data/lib/earth/automobile/automobile_make_year/data_miner.rb +22 -23
  29. data/lib/earth/automobile/automobile_make_year_fleet.rb +11 -0
  30. data/lib/earth/automobile/{automobile_make_fleet_year → automobile_make_year_fleet}/data_miner.rb +1 -2
  31. data/lib/earth/automobile/automobile_model.rb +5 -0
  32. data/lib/earth/automobile/automobile_model/data_miner.rb +19 -0
  33. data/lib/earth/automobile/automobile_size_class.rb +1 -0
  34. data/lib/earth/automobile/automobile_size_class/data_miner.rb +30 -4
  35. data/lib/earth/automobile/automobile_type_fuel_year.rb +1 -1
  36. data/lib/earth/automobile/automobile_type_fuel_year/data_miner.rb +30 -19
  37. data/lib/earth/automobile/automobile_type_fuel_year_age.rb +0 -3
  38. data/lib/earth/automobile/automobile_type_fuel_year_age/data_miner.rb +13 -15
  39. data/lib/earth/automobile/automobile_type_fuel_year_control.rb +0 -4
  40. data/lib/earth/automobile/automobile_type_fuel_year_control/data_miner.rb +0 -8
  41. data/lib/earth/automobile/automobile_type_year.rb +2 -1
  42. data/lib/earth/automobile/automobile_type_year/data_miner.rb +12 -10
  43. data/lib/earth/automobile/automobile_year.rb +5 -0
  44. data/lib/earth/automobile/automobile_year/data_miner.rb +15 -0
  45. data/lib/earth/automobile/data_miner.rb +5 -3
  46. data/lib/earth/automobile/dependencies.txt +45 -0
  47. data/lib/earth/bus/bus_class.rb +1 -87
  48. data/lib/earth/bus/bus_class/data_miner.rb +0 -1
  49. data/lib/earth/bus/bus_fuel/data_miner.rb +12 -19
  50. data/lib/earth/bus/bus_fuel_control/data_miner.rb +8 -12
  51. data/lib/earth/conversions_ext.rb +1 -0
  52. data/lib/earth/fuel/fuel/data_miner.rb +28 -38
  53. data/lib/earth/fuel/fuel_year/data_miner.rb +36 -47
  54. data/lib/earth/hospitality/lodging_class/data_miner.rb +12 -6
  55. data/lib/earth/locality.rb +1 -0
  56. data/lib/earth/locality/country.rb +1 -1
  57. data/lib/earth/locality/country/data_miner.rb +36 -28
  58. data/lib/earth/locality/data_miner.rb +1 -0
  59. data/lib/earth/locality/egrid_subregion/data_miner.rb +19 -14
  60. data/lib/earth/locality/urbanity/data_miner.rb +1 -3
  61. data/lib/earth/locality/zip_code/data_miner.rb +1 -1
  62. data/lib/earth/rail/national_transit_database_record/data_miner.rb +10 -14
  63. data/lib/earth/rail/rail_fuel.rb +2 -6
  64. data/lib/earth/residence/air_conditioner_use/data_miner.rb +1 -3
  65. data/lib/earth/residence/clothes_machine_use/data_miner.rb +1 -3
  66. data/lib/earth/residence/dishwasher_use/data_miner.rb +1 -3
  67. data/lib/earth/residence/residence_class/data_miner.rb +1 -3
  68. data/lib/earth/residence/residential_energy_consumption_survey_response/data_miner.rb +3 -1
  69. data/lib/earth/utils.rb +15 -5
  70. data/lib/earth/version.rb +1 -1
  71. data/spec/earth_spec.rb +4 -4
  72. metadata +9 -11
  73. data/features/automobile_type_fuel_age.feature +0 -55
  74. data/lib/earth/air/aircraft_class.rb +0 -59
  75. data/lib/earth/air/aircraft_class/data_miner.rb +0 -14
  76. data/lib/earth/air/aircraft_fuel_use_equation.rb +0 -33
  77. data/lib/earth/air/aircraft_fuel_use_equation/data_miner.rb +0 -13
  78. data/lib/earth/automobile/automobile_make_fleet_year.rb +0 -46
  79. data/lib/earth/automobile/automobile_type_fuel_age.rb +0 -65
  80. data/lib/earth/automobile/automobile_type_fuel_age/data_miner.rb +0 -149
@@ -13,32 +13,48 @@ AutomobileMakeModelYear.class_eval do
13
13
  :src => AutomobileMakeModelYearVariant,
14
14
  :dest => AutomobileMakeModelYear,
15
15
  :cols => {
16
- :make_model_year_name => :name,
16
+ [:make_name, :model_name, :year] => :name,
17
17
  :make_name => :make_name,
18
- :name => :model_name,
19
- :make_model_name => :make_model_name,
18
+ :model_name => :model_name,
20
19
  :year => :year,
21
- :make_year_name => :make_year_name
22
20
  }
23
- # :where => 'LENGTH(src.make_name) > 0 AND LENGTH(src.make_model_name) > 0'
24
21
  )
25
22
  end
26
23
 
27
- # FIXME TODO make this a method on AutomobileMakeModelYear?
28
- # TODO: weight by volume somehow
29
- # note that we used to derive averages from make years, but here we get it from variants
30
- # even without volume-weighting, the values are much better.
31
- # for example, 20km/l for a toyota prius 2006 vs. 13km/l if you use make years
24
+ process "Derive fuel from automobile make model year variants" do
25
+ model_years = arel_table
26
+ variants = AutomobileMakeModelYearVariant.arel_table
27
+ conditional_relation = variants[:make_name].eq(model_years[:make_name]).and(variants[:model_name].eq(model_years[:model_name])).and(variants[:year].eq(model_years[:year]))
28
+ where("(#{variants.project('COUNT(DISTINCT fuel_code)').where(conditional_relation).to_sql}) = 1").update_all "fuel_code = (#{variants.project('DISTINCT fuel_code').where(conditional_relation).to_sql})"
29
+ end
30
+
31
+ # FIXME TODO not in automobile_make_model_year_variants because they're missing from the EPA FEG download files:
32
+ # 2005 Honda Accord Hybrid
33
+ # 2006 Honda Accord Hybrid
34
+ # 2009 Chrysler Aspen HEV
35
+ # 2009 Dodge Durango HEV
36
+ import "A list of hybrid make model years derived from the EPA fuel economy guide",
37
+ :url => 'https://docs.google.com/spreadsheet/pub?hl=en_US&hl=en_US&key=0AoQJbWqPrREqdGtzekE4cGNoRGVmdmZMaTNvOWluSnc&output=csv' do
38
+ key 'name', :synthesize => lambda { |record| [record['make_name'], record['model_name'], record['year']].join(' ') }
39
+ store 'hybridity'
40
+ end
41
+
42
+ process "Set hybridity to FALSE for all other make model years" do
43
+ where(:hybridity => nil).update_all :hybridity => false
44
+ end
45
+
46
+ # FIXME TODO: weight by volume somehow
32
47
  process "Calculate city and highway fuel efficiency from automobile make model year variants" do
33
- model_years = AutomobileMakeModelYear.arel_table
48
+ model_years = arel_table
34
49
  variants = AutomobileMakeModelYearVariant.arel_table
35
- conditional_relation = model_years[:name].eq(variants[:make_model_year_name])
36
- %w{ city highway }.each do |i|
37
- null_check = variants[:"fuel_efficiency_#{i}"].not_eq(nil)
38
- # sabshere 12/6/10 careful, don't use AutomobileMakeModelYearVariant.where here or you will be forced into projecting *
39
- relation = variants.project(variants[:"fuel_efficiency_#{i}"].average).where(conditional_relation).where(null_check)
40
- update_all "fuel_efficiency_#{i} = (#{relation.to_sql})"
41
- update_all "fuel_efficiency_#{i}_units" => 'kilometres_per_litre'
50
+ conditional_relation = model_years[:make_name].eq(variants[:make_name]).and(model_years[:model_name].eq(variants[:model_name])).and(model_years[:year].eq(variants[:year]))
51
+ %w{ city highway }.each do |type|
52
+ null_check = variants[:"fuel_efficiency_#{type}"].not_eq(nil)
53
+ relation = variants.project(variants[:"fuel_efficiency_#{type}"].average).where(conditional_relation).where(null_check)
54
+ update_all(%{
55
+ fuel_efficiency_#{type} = (#{relation.to_sql}),
56
+ fuel_efficiency_#{type}_units = 'kilometres_per_litre'
57
+ })
42
58
  end
43
59
  end
44
60
  end
@@ -1,64 +1,42 @@
1
1
  class AutomobileMakeModelYearVariant < ActiveRecord::Base
2
2
  set_primary_key :row_hash
3
3
 
4
- belongs_to :make, :class_name => 'AutomobileMake', :foreign_key => 'make_name'
5
- belongs_to :make_model, :class_name => 'AutomobileMakeModel', :foreign_key => 'make_model_name'
6
- belongs_to :make_model_year, :class_name => 'AutomobileMakeModelYear', :foreign_key => 'make_model_year_name'
7
- belongs_to :fuel, :class_name => 'AutomobileFuel', :foreign_key => 'fuel_code', :primary_key => 'code'
4
+ # It looks like synthesizing a unique name would require including pretty much every column from the FEGs
5
+ # (e.g. creeper gear, automatic vs automatic with lockup, feedback fuel system, etc.)
6
+ # The advantages of not keying on row_hash is we could update variants to note whether they're hybrid or not and
7
+ # it would let users specify variants. But my conclusion is that trying to do this won't be much of an improvement
8
+ # because it will be a bunch of work to include all the columns and the names will be really long and obtuse
9
+ # -Ian 10/18/2011
8
10
 
9
11
  col :row_hash
10
- col :name # short name!
11
12
  col :make_name
12
- col :make_model_name # make + model
13
- col :make_year_name # make + year
14
- col :make_model_year_name # make + model + year
15
- col :year, :type => :integer
16
- col :fuel_efficiency, :type => :float
17
- col :fuel_efficiency_units
18
- col :fuel_efficiency_city, :type => :float
19
- col :fuel_efficiency_city_units
20
- col :fuel_efficiency_highway, :type => :float
21
- col :fuel_efficiency_highway_units
22
- col :fuel_code
13
+ col :model_name
14
+ col :year, :type => :integer
23
15
  col :transmission
16
+ col :speeds
24
17
  col :drive
25
- col :turbo, :type => :boolean
26
- col :supercharger, :type => :boolean
27
- col :cylinders, :type => :integer
18
+ col :fuel_code
19
+ col :cylinders, :type => :integer
28
20
  col :displacement, :type => :float
29
- col :raw_fuel_efficiency_city, :type => :float
21
+ col :turbo, :type => :boolean
22
+ col :supercharger, :type => :boolean
23
+ col :injection, :type => :boolean
24
+ col :fuel_efficiency, :type => :float
25
+ col :fuel_efficiency_units
26
+ col :fuel_efficiency_city, :type => :float
27
+ col :fuel_efficiency_city_units
28
+ col :fuel_efficiency_highway, :type => :float
29
+ col :fuel_efficiency_highway_units
30
+ col :raw_fuel_efficiency_city, :type => :float
30
31
  col :raw_fuel_efficiency_city_units
31
32
  col :raw_fuel_efficiency_highway, :type => :float
32
33
  col :raw_fuel_efficiency_highway_units
33
- col :carline_mfr_code, :type => :integer
34
- col :vi_mfr_code, :type => :integer
35
- col :carline_code, :type => :integer
34
+ col :carline_mfr_code, :type => :integer
35
+ col :vi_mfr_code, :type => :integer
36
+ col :carline_code, :type => :integer
36
37
  col :carline_class_code, :type => :integer
37
- col :injection, :type => :boolean
38
38
  col :carline_class_name
39
- col :speeds
40
39
  add_index :make_name
41
- add_index :make_model_name
42
- add_index :make_year_name
43
- add_index :make_model_year_name
44
-
45
- # verify "Fuel code should appear in AutomobileFuel" do
46
- # if (violators = connection.select_values("SELECT DISTINCT fuel_code FROM #{quoted_table_name} WHERE fuel_code NOT IN (SELECT code FROM #{AutomobileFuel.quoted_table_name})")).any?
47
- # raise "Invalid fuel code(s): #{violators.join(', ')}"
48
- # end
49
- # true
50
- # end
51
- #
52
- # verify "Fuel efficiencies should be greater than zero" do
53
- # [:fuel_efficiency, :fuel_efficiency_city, :fuel_efficiency_highway].each do |field|
54
- # if AutomobileMakeModelYearVariant.where(field => nil).any?
55
- # raise "Invalid #{field} in automobile_make_model_year_variants: nil is not > 0"
56
- # else
57
- # min = AutomobileMakeModelYearVariant.minimum(field)
58
- # unless min > 0
59
- # raise "Invalid #{field} in automobile_make_model_year_variants: #{min} is not > 0"
60
- # end
61
- # end
62
- # end
63
- # end
64
- end
40
+ add_index :model_name
41
+ add_index :year
42
+ end
@@ -1,69 +1,24 @@
1
1
  AutomobileMakeModelYearVariant.class_eval do
2
2
  # For errata
3
3
  class AutomobileMakeModelYearVariant::Guru
4
- def transmission_is_blank?(row)
5
- row['transmission'].blank?
6
- end
7
-
8
- def is_a_2007_gmc_or_chevrolet?(row)
9
- row['year'] == 2007 and %w(GMC CHEVROLET).include? row['MFR'].upcase
10
- end
11
-
12
- def is_a_porsche?(row)
13
- row['make'].to_s.upcase == 'PORSCHE'
14
- end
15
-
16
- def is_not_a_porsche?(row)
17
- !is_a_porsche? row
18
- end
19
-
20
- def is_a_mercedes_benz?(row)
21
- row['make'].to_s =~ /MERCEDES/i
22
- end
23
-
24
- def is_a_lexus?(row)
25
- row['make'].to_s.upcase == 'LEXUS'
26
- end
27
-
28
- def is_a_bmw?(row)
29
- row['make'].to_s.upcase == 'BMW'
30
- end
31
-
32
- def is_a_ford?(row)
33
- row['make'].to_s.upcase == 'FORD'
34
- end
35
-
36
- def is_a_rolls_royce_and_model_contains_bentley?(row)
37
- is_a_rolls_royce?(row) and model_contains_bentley?(row)
38
- end
39
-
40
- def is_a_bentley?(row)
41
- row['make'].to_s.upcase == 'BENTLEY'
4
+ %w{ alpina bentley chevrolet dodge ferrari jaguar kia lexus maybach mercedes-benz mitsubishi porsche toyota tvr volvo yugo }.each do |make|
5
+ make_for_method = make.gsub('-', '_')
6
+ method_name = :"is_a_#{make_for_method}?"
7
+ define_method method_name do |row|
8
+ row['make'].to_s.upcase == "#{make.humanize.upcase}"
9
+ end
42
10
  end
43
11
 
44
- def is_a_rolls_royce?(row)
45
- row['make'].to_s =~ /ROLLS/i
12
+ %w{ alpina bentley maybach smart }.each do |model|
13
+ method_name = :"model_contains_#{model}?"
14
+ define_method method_name do |row|
15
+ row['model'].to_s =~ /#{model.upcase}/i
16
+ end
46
17
  end
47
18
 
48
19
  def is_a_turbo_brooklands?(row)
49
20
  row['model'] =~ /TURBO R\/RL BKLDS/i
50
21
  end
51
-
52
- def model_contains_maybach?(row)
53
- row['model'] =~ /MAYBACH/i
54
- end
55
-
56
- def model_contains_bentley?(row)
57
- row['model'] =~ /BENTLEY/i
58
- end
59
-
60
- def name_contains_smart?(row)
61
- row['model'] =~ / smart /i
62
- end
63
-
64
- def source_code
65
- IO.read __FILE__
66
- end
67
22
  end
68
23
 
69
24
  # updated with 2010 names
@@ -78,18 +33,18 @@ AutomobileMakeModelYearVariant.class_eval do
78
33
  'CVT' => 'Continuously Variable',
79
34
  'OT' => 'Other'
80
35
  }
81
-
36
+
82
37
  ENGINE_TYPES = {
83
38
  '(GUZZLER)' => nil, # "gas guzzler"
84
39
  '(POLICE)' => nil, # police automobile_variant
85
40
  '(MPFI)' => 'injection',
86
41
  '(MPI*)' => 'injection',
87
42
  '(SPFI)' => 'injection',
88
- '(FFS)' => 'injection',
43
+ '(FFS)' => nil, # doesn't necessarily mean fuel injection
89
44
  '(TURBO)' => 'turbo',
90
45
  '(TRBO)' => 'turbo',
91
46
  '(TC*)' => 'turbo',
92
- '(FFS,TRBO)' => %w(injection turbo),
47
+ '(FFS,TRBO)' => 'turbo',
93
48
  '(S-CHARGE)' => 'supercharger',
94
49
  '(SC*)' => 'supercharger',
95
50
  '(DIESEL)' => nil, # diesel
@@ -165,26 +120,33 @@ AutomobileMakeModelYearVariant.class_eval do
165
120
  end
166
121
  def apply(row)
167
122
  row.merge!({
168
- 'make' => row['carline_mfr_name'], # make it line up with the errata
169
- 'model' => row['carline_name'], # ditto
170
- 'transmission' => TRANSMISSIONS[row['model_trans'][0, 1]],
171
- 'speeds' => (row['model_trans'][1, 1] == 'V') ? 'variable' : row['model_trans'][1, 1],
172
- 'turbo' => [ENGINE_TYPES[row['engine_desc1']], ENGINE_TYPES[row['engine_desc2']]].flatten.include?('turbo'),
173
- 'supercharger' => [ENGINE_TYPES[row['engine_desc1']], ENGINE_TYPES[row['engine_desc2']]].flatten.include?('supercharger'),
174
- 'injection' => [ENGINE_TYPES[row['engine_desc1']], ENGINE_TYPES[row['engine_desc2']]].flatten.include?('injection'),
175
- 'displacement' => _displacement(row['opt_disp']),
176
- 'year' => year
123
+ 'make' => row['carline_mfr_name'], # make it line up with the errata
124
+ 'model' => row['carline_name'].upcase, # ditto
125
+ 'year' => year,
126
+ 'transmission' => TRANSMISSIONS[row['model_trans'][0,1].to_s],
127
+ 'speeds' => row['model_trans'][1,1] == 'V' ? 'variable' : row['model_trans'][1,1],
128
+ 'displacement' => _displacement(row),
129
+ 'turbo' => _turbo(row),
130
+ 'supercharger' => [ENGINE_TYPES[row['engine_desc1'].to_s], ENGINE_TYPES[row['engine_desc2'].to_s]].flatten.include?('supercharger'),
131
+ 'injection' => row['fuel_system'] == 'FI' ? true : false
177
132
  })
178
133
  row
179
134
  end
180
- def _displacement(str)
181
- str = str.gsub(/[\(\)]/, '').strip
182
- if str =~ /^(.+)L$/
135
+ def _displacement(row)
136
+ optional_displacement = row['opt_disp'].gsub(/[\(\)]/, '').strip.to_s
137
+ if optional_displacement =~ /^(\d\.\d)L$/
183
138
  $1.to_f
184
- elsif str =~ /^(.+)CC$/
185
- $1.to_f / 1000
139
+ elsif optional_displacement =~ /^(\d{4})CC$/
140
+ ($1.to_f / 1000).round(1)
141
+ else
142
+ row['disp_cub_in'].to_f.cubic_inches.to(:litres).round(1)
186
143
  end
187
144
  end
145
+ def _turbo(row)
146
+ engine_types = [ENGINE_TYPES[row['engine_desc1'].to_s], ENGINE_TYPES[row['engine_desc2'].to_s]]
147
+ engine_types << (row['carline_name'].to_s.downcase.include?('turbo') ? 'turbo' : nil)
148
+ engine_types.flatten.include?('turbo')
149
+ end
188
150
  end
189
151
 
190
152
  class AutomobileMakeModelYearVariant::ParserC
@@ -195,12 +157,12 @@ AutomobileMakeModelYearVariant.class_eval do
195
157
  end
196
158
  def apply(row)
197
159
  row.merge!({
198
- 'make' => row['Manufacturer'], # make it line up with the errata
199
- 'model' => row['carline name'], # ditto
160
+ 'make' => row['Manufacturer'], # make it line up with the errata
161
+ 'model' => row['carline name'].upcase, # ditto
200
162
  'drive' => row['drv'] + 'WD',
201
- 'transmission' => TRANSMISSIONS[row['trans'][-3, 1]], # only using prefix, probably a FIXME
163
+ 'transmission' => TRANSMISSIONS[row['trans'][-3, 1]],
202
164
  'speeds' => (row['trans'][-2, 1] == 'V') ? '1' : row['trans'][-2, 1],
203
- 'turbo' => row['T'] == 'T',
165
+ 'turbo' => (row['T'] == 'T' || row['carline name'].to_s.downcase.include?('turbo')) ? true : false,
204
166
  'supercharger' => row['S'] == 'S',
205
167
  'injection' => true,
206
168
  'year' => year
@@ -217,10 +179,10 @@ AutomobileMakeModelYearVariant.class_eval do
217
179
  end
218
180
  def apply(row)
219
181
  row.merge!({
220
- 'make' => row['MFR'], # make it line up with the errata
221
- 'model' => row['CAR LINE'], # ditto
182
+ 'make' => row['MFR'], # make it line up with the errata
183
+ 'model' => row['CAR LINE'].upcase, # ditto
222
184
  'drive' => row['DRIVE SYS'] + 'WD',
223
- 'transmission' => TRANSMISSIONS[row['TRANS'][-3, 1]], # only using prefix, probably a FIXME
185
+ 'transmission' => TRANSMISSIONS[row['TRANS'][-3, 1]],
224
186
  'speeds' => (row['TRANS'][-2, 1] == 'V') ? '1' : row['TRANS'][-2, 1],
225
187
  'turbo' => row['TURBO'] == 'T',
226
188
  'supercharger' => row['SPCHGR'] == 'S',
@@ -249,8 +211,8 @@ AutomobileMakeModelYearVariant.class_eval do
249
211
  end
250
212
  def apply(row)
251
213
  row.merge!({
252
- 'make' => row['Division'], # make it line up with the errata
253
- 'model' => row['Carline'], # ditto
214
+ 'make' => row['Division'], # make it line up with the errata
215
+ 'model' => row['Carline'].upcase, # ditto
254
216
  'drive' => row['Drive Sys'] + 'WD',
255
217
  'transmission' => TRANSMISSIONS[row['Trans']],
256
218
  'speeds' => row['# Gears'],
@@ -266,46 +228,47 @@ AutomobileMakeModelYearVariant.class_eval do
266
228
 
267
229
  data_miner do
268
230
  # 1985---1997
269
- # FIXME TODO one Jaguar in the 1990 FEG has no model name
270
231
  # FIXME TODO 14 records in the 1995 FEG are missing fuel efficiencies
271
232
  (85..97).each do |yy|
272
233
  # [85, 95, 96].each do |yy|
273
234
  filename = (yy == 96) ? "#{yy}MFGUI.ASC" : "#{yy}MFGUI.DAT"
274
- import("19#{ yy } Fuel Economy Guide",
235
+ import "19#{ yy } Fuel Economy Guide",
275
236
  :url => "http://www.fueleconomy.gov/FEG/epadata/#{yy}mfgui.zip",
237
+ # :url => "file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/#{filename}",
276
238
  :format => :fixed_width,
277
239
  :cut => ((yy == 95) ? '13-' : nil),
278
240
  :schema_name => :fuel_economy_guide_b,
279
241
  :select => lambda { |row| row['model'].present? and (row['suppress_code'].blank? or row['suppress_code'].to_f == 0) and row['state_code'] == 'F' },
280
242
  :filename => filename,
281
243
  :transform => { :class => AutomobileMakeModelYearVariant::ParserB, :year => "19#{yy}".to_i },
282
- :errata => { :url => 'https://spreadsheets.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdEFqVXRvQjRGNUpxNHFCOXhqSjRmdlE&output=csv', :responder => AutomobileMakeModelYearVariant::Guru.new }) do
244
+ :errata => { :url => "https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDkxTElWRVlvUXB3Uy04SDhSYWkzakE&output=csv", :responder => AutomobileMakeModelYearVariant::Guru.new } do
245
+ # :errata => { :url => "file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/errata_new.csv", :responder => AutomobileMakeModelYearVariant::Guru.new } do
283
246
  key 'row_hash'
284
- store 'name', :field_name => 'model'
285
- store 'make_name', :field_name => 'make'
247
+ store 'make_name', :field_name => 'make'
248
+ store 'model_name', :field_name => 'model'
286
249
  store 'year'
287
- store 'fuel_code', :field_name => 'fuel_type'
288
- store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
289
- store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
290
- store 'raw_fuel_efficiency_highway', :field_name => 'unadj_hwy_mpg', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
291
- store 'raw_fuel_efficiency_city', :field_name => 'unadj_city_mpg', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
292
- store 'cylinders', :field_name => 'no_cyc'
293
- store 'drive', :field_name => 'drive_system'
294
- store 'carline_mfr_code'
295
- store 'vi_mfr_code'
296
- store 'carline_code'
297
- store 'carline_class_code', :field_name => 'carline_clss'
298
250
  store 'transmission'
299
251
  store 'speeds'
252
+ store 'drive', :field_name => 'drive_system'
253
+ store 'fuel_code', :field_name => 'fuel_type'
254
+ store 'cylinders', :field_name => 'no_cyc'
255
+ store 'displacement'
300
256
  store 'turbo'
301
257
  store 'supercharger'
302
258
  store 'injection'
303
- store 'displacement'
259
+ store 'raw_fuel_efficiency_city', :field_name => 'unadj_city_mpg', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
260
+ store 'raw_fuel_efficiency_highway', :field_name => 'unadj_hwy_mpg', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
261
+ store 'carline_mfr_code'
262
+ store 'vi_mfr_code'
263
+ store 'carline_code'
264
+ store 'carline_class_code', :field_name => 'carline_clss'
304
265
  end
305
266
  end
306
267
 
307
268
  # 1998--2005
308
269
  {
270
+ # FIXME TODO 2005 Mercedes-Benz SLK55 AMG has NULL speeds (it does in the EPA FEG also)
271
+ # FIXME TODO numbers from xls files are getting imported as floats rather than integers (e.g. 4.0WD rather than 4WD)
309
272
  1998 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/98guide6.zip', :filename => '98guide6.csv' },
310
273
  1999 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/99guide.zip', :filename => '99guide6.csv' },
311
274
  2000 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/00data.zip', :filename => 'G6080900.xls' },
@@ -314,30 +277,37 @@ AutomobileMakeModelYearVariant.class_eval do
314
277
  2003 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/03data.zip', :filename => 'guide_2003_feb04-03b.csv' },
315
278
  2004 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/04data.zip', :filename => 'gd04-Feb1804-RelDtFeb20.csv' },
316
279
  2005 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/05data.zip', :filename => 'guide2005-2004oct15.csv' }
280
+ # 1998 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/98guide6.csv' },
281
+ # 1999 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/99guide6.csv' },
282
+ # 2000 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/G6080900.csv' },
283
+ # 2001 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/01guide0918.csv' },
284
+ # 2002 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/guide_jan28.csv' },
285
+ # 2003 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/guide_2003_feb04-03b.csv' },
286
+ # 2004 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/gd04-Feb1804-RelDtFeb20.csv' },
287
+ # 2005 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/guide2005-2004oct15.csv' }
317
288
  }.each do |year, options|
318
289
  import "#{ year } Fuel Economy Guide",
319
290
  options.merge(:transform => { :class => AutomobileMakeModelYearVariant::ParserC, :year => year },
320
- :errata => { :url => 'https://spreadsheets.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdEFqVXRvQjRGNUpxNHFCOXhqSjRmdlE&output=csv', :responder => AutomobileMakeModelYearVariant::Guru.new },
291
+ :errata => { :url => "https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDkxTElWRVlvUXB3Uy04SDhSYWkzakE&output=csv", :responder => AutomobileMakeModelYearVariant::Guru.new },
292
+ # :errata => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/errata_new.csv', :responder => AutomobileMakeModelYearVariant::Guru.new },
321
293
  :select => lambda { |row| row['model'].present? }) do
322
294
  key 'row_hash'
323
- store 'name', :field_name => 'model'
324
- store 'make_name', :field_name => 'make'
325
- store 'fuel_code', :field_name => 'fl'
326
- store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
327
- store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
328
- store 'raw_fuel_efficiency_highway', :field_name => 'uhwy', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
329
- store 'raw_fuel_efficiency_city', :field_name => 'ucty', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
330
- store 'cylinders', :field_name => 'cyl'
331
- store 'displacement', :field_name => 'displ'
332
- store 'carline_class_code', :field_name => 'cls' if year >= 2000
333
- store 'carline_class_name', :field_name => 'Class'
295
+ store 'make_name', :field_name => 'make'
296
+ store 'model_name', :field_name => 'model'
334
297
  store 'year'
335
298
  store 'transmission'
336
299
  store 'speeds'
300
+ store 'drive'
301
+ store 'fuel_code', :field_name => 'fl'
302
+ store 'cylinders', :field_name => 'cyl'
303
+ store 'displacement', :field_name => 'displ'
337
304
  store 'turbo'
338
305
  store 'supercharger'
339
306
  store 'injection'
340
- store 'drive'
307
+ store 'raw_fuel_efficiency_highway', :field_name => 'uhwy', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
308
+ store 'raw_fuel_efficiency_city', :field_name => 'ucty', :from_units => :miles_per_gallon, :to_units => :kilometres_per_litre
309
+ store 'carline_class_code', :field_name => 'cls' if year >= 2000
310
+ store 'carline_class_name', :field_name => 'Class'
341
311
  end
342
312
  end
343
313
 
@@ -347,15 +317,21 @@ AutomobileMakeModelYearVariant.class_eval do
347
317
  # the 07data.xls file provided by the government has a bad encoding
348
318
  2007 => { :url => 'http://static.brighterplanet.com/science/data/transport/automobiles/fuel_economy_guide/2007_FE_guide_ALL_no_sales_May_01_2007.csv' },
349
319
  2008 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/08data.zip', :filename => '2008_FE_guide_ALL_rel_dates_-no sales-for DOE-5-1-08.csv' },
350
- 2009 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/09data.zip', :filename => '2009_FE_guide for DOE_ALL-rel dates-no-sales-8-28-08download.csv' },
320
+ 2009 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/09data.zip', :filename => '2009_FE_guide for DOE_ALL-rel dates-no-sales-8-28-08download.csv' }
321
+ # 2006 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/2006_FE_Guide_14-Nov-2005_download.csv' },
322
+ # 2007 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/2007_FE_guide_ALL_no_sales_May_01_2007.csv' },
323
+ # 2008 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/2008_FE_guide.csv' },
324
+ # 2009 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/2009_FE_guide.csv' }
351
325
  }.each do |year, options|
352
326
  import "#{ year } Fuel Economy Guide",
353
327
  options.merge(:transform => { :class => AutomobileMakeModelYearVariant::ParserD, :year => year },
354
- :errata => { :url => 'https://spreadsheets.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdEFqVXRvQjRGNUpxNHFCOXhqSjRmdlE&output=csv', :responder => AutomobileMakeModelYearVariant::Guru.new },
328
+ :errata => { :url => "https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDkxTElWRVlvUXB3Uy04SDhSYWkzakE&output=csv", :responder => AutomobileMakeModelYearVariant::Guru.new },
329
+ # :errata => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/errata_new.csv', :responder => AutomobileMakeModelYearVariant::Guru.new },
355
330
  :select => lambda { |row| row['model'].present? }) do
356
331
  key 'row_hash'
357
- store 'name', :field_name => 'model'
358
332
  store 'make_name', :field_name => 'make'
333
+ store 'model_name', :field_name => 'model'
334
+ store 'year'
359
335
  store 'fuel_code', :field_name => 'FUEL TYPE'
360
336
  store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
361
337
  store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
@@ -365,7 +341,6 @@ AutomobileMakeModelYearVariant.class_eval do
365
341
  store 'displacement', :field_name => 'DISPLACEMENT'
366
342
  store 'carline_class_code', :field_name => 'CLS'
367
343
  store 'carline_class_name', :field_name => 'CLASS'
368
- store 'year'
369
344
  store 'transmission'
370
345
  store 'speeds'
371
346
  store 'turbo'
@@ -377,16 +352,22 @@ AutomobileMakeModelYearVariant.class_eval do
377
352
 
378
353
  # 2010--?
379
354
  {
355
+ # FIXME TODO numbers from xlsx files are getting imported as floats rather than integers (e.g. speeds = 6.0 rather than 6)
356
+ # Note: it's ok for electric vehicles to be missing cylinders and displacement
380
357
  2010 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/10data.zip', :filename => '2010FEGuide for DOE-all rel dates-no-sales-02-22-2011public.xlsx' },
381
358
  2011 => { :url => 'http://www.fueleconomy.gov/FEG/epadata/11data.zip', :filename => '2011FEGuide-for DOE rel-dates before 1-23-2011-no-sales-01-10-2011_All_public.xlsx' }
359
+ # 2010 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/2010FEGuide.xlsx' },
360
+ # 2011 => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/2011FEGuide.xlsx' }
382
361
  }.each do |year, options|
383
362
  import "#{ year } Fuel Economy Guide",
384
363
  options.merge(:transform => { :class => AutomobileMakeModelYearVariant::ParserE, :year => year },
385
- :errata => { :url => 'https://spreadsheets.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdEFqVXRvQjRGNUpxNHFCOXhqSjRmdlE&output=csv', :responder => AutomobileMakeModelYearVariant::Guru.new },
364
+ :errata => { :url => "https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDkxTElWRVlvUXB3Uy04SDhSYWkzakE&output=csv", :responder => AutomobileMakeModelYearVariant::Guru.new },
365
+ # :errata => { :url => 'file:///Users/ian/Documents/brighter_planet/documents1/science/data/transport/automobiles/fuel_economy_guide/errata_new.csv', :responder => AutomobileMakeModelYearVariant::Guru.new },
386
366
  :select => lambda { |row| row['model'].present? }) do
387
367
  key 'row_hash'
388
- store 'name', :field_name => 'model'
389
368
  store 'make_name', :field_name => 'make'
369
+ store 'model_name', :field_name => 'model'
370
+ store 'year'
390
371
  store 'fuel_code', :field_name => 'fuel_type_code'
391
372
  store 'fuel_efficiency_highway', :static => nil, :units => :kilometres_per_litre
392
373
  store 'fuel_efficiency_city', :static => nil, :units => :kilometres_per_litre
@@ -396,7 +377,6 @@ AutomobileMakeModelYearVariant.class_eval do
396
377
  store 'displacement', :field_name => 'Eng Displ'
397
378
  store 'carline_class_code', :field_name => 'Carline Class'
398
379
  store 'carline_class_name', :field_name => 'Carline Class Desc'
399
- store 'year'
400
380
  store 'transmission'
401
381
  store 'speeds'
402
382
  store 'turbo'
@@ -406,36 +386,27 @@ AutomobileMakeModelYearVariant.class_eval do
406
386
  end
407
387
  end
408
388
 
409
- process "Derive model and model year names" do
410
- update_all "make_model_name = make_name || ' ' || name"
411
- update_all "make_year_name = make_name || ' ' || year"
412
- update_all "make_model_year_name = make_name || ' ' || name || ' ' || year"
413
- end
414
-
415
389
  # Note: need to divide by 0.425143707 b/c equation is designed for miles / gallon not km / l
416
390
  # Note: EPA seems to adjust differently for plug-in hybrid electric vehicles (e.g. Leaf and Volt)
417
391
  process "Calculate adjusted fuel efficiency using the latest EPA equations from EPA Fuel Economy Trends report Appendix A including conversion from miles per gallon to kilometres per litre" do
418
- update_all 'fuel_efficiency_city = 1.0 / ((0.003259 / 0.425143707) + (1.1805 / raw_fuel_efficiency_city))', 'raw_fuel_efficiency_city > 0'
419
- update_all 'fuel_efficiency_highway = 1.0 / ((0.001376 / 0.425143707) + (1.3466 / raw_fuel_efficiency_highway))', 'raw_fuel_efficiency_highway > 0'
392
+ where("raw_fuel_efficiency_city > 0").update_all(%{
393
+ fuel_efficiency_city = 1.0 / ((0.003259 / 0.425143707) + (1.1805 / raw_fuel_efficiency_city)),
394
+ fuel_efficiency_city_units = 'kilometres_per_litre'
395
+ })
396
+ where("raw_fuel_efficiency_highway > 0").update_all(%{
397
+ fuel_efficiency_highway = 1.0 / ((0.001376 / 0.425143707) + (1.3466 / raw_fuel_efficiency_highway)),
398
+ fuel_efficiency_highway_units = 'kilometres_per_litre'
399
+ })
420
400
  end
421
401
 
422
402
  # This will be useful later for calculating MakeModel and Make fuel efficiency based on Variant
423
403
  # NOTE: we use a 43/57 city/highway weighting per the latest EPA analysis of real-world driving behavior
424
404
  # This results in a deviation from EPA fuel economy label values which use a historical 55/45 weighting
425
405
  process "Calculate combined adjusted fuel efficiency using the latest EPA equation" do
426
- update_all "fuel_efficiency = 1.0 / ((0.43 / fuel_efficiency_city) + (0.57 / fuel_efficiency_highway))"
427
- end
428
-
429
- process "Set units" do
430
- update_all :fuel_efficiency_units => 'kilometres_per_litre'
431
- update_all :fuel_efficiency_city_units => 'kilometres_per_litre'
432
- update_all :fuel_efficiency_highway_units => 'kilometres_per_litre'
433
- end
434
-
435
- process "Ensure related tables are populated" do
436
- AutomobileMakeModelYear.run_data_miner!
437
- AutomobileMakeModel.run_data_miner!
438
- AutomobileFuel.run_data_miner!
406
+ update_all(%{
407
+ fuel_efficiency = 1.0 / ((0.43 / fuel_efficiency_city) + (0.57 / fuel_efficiency_highway)),
408
+ fuel_efficiency_units = 'kilometres_per_litre'
409
+ })
439
410
  end
440
411
  end
441
412
  end