earth 0.7.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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