earth 0.11.20 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. data/data/automobile/annual_emission_controls.csv +143 -0
  2. data/data/automobile/annual_fuel_consumption.csv +81 -0
  3. data/data/automobile/annual_sizes.csv +541 -0
  4. data/data/automobile/auto_fuel_data.csv +13 -0
  5. data/data/automobile/auto_fuel_efs.csv +9 -0
  6. data/data/automobile/cafe_data.csv +1449 -0
  7. data/data/automobile/emission_control_techs.csv +21 -0
  8. data/data/automobile/hfc_emissions.csv +31 -0
  9. data/data/automobile/hybridity_multipliers.csv +8 -0
  10. data/data/automobile/sizes.csv +16 -0
  11. data/earth.gemspec +3 -2
  12. data/errata/aircraft/faa_errata.csv +1 -1
  13. data/errata/airline/bts_carrier_codes_errata.csv +44 -0
  14. data/errata/airport/openflights_errata.csv +450 -1
  15. data/errata/automobile_make_model_year_variant/feg_errata.csv +363 -1
  16. data/errata/automobile_make_year_fleet/cafe_errata.csv +69 -1
  17. data/errata/bts_aircraft/bts_errata.csv +1 -1
  18. data/errata/country/wri_errata.csv +1 -1
  19. data/errata/electricity/electric_market/nrel_errata.csv +13 -1
  20. data/errata/electricity/electric_utility/eia_errata.csv +18 -1
  21. data/errata/flight_segment/bts_errata.csv +4 -1
  22. data/lib/earth.rb +1 -0
  23. data/lib/earth/acronyms.rb +12 -0
  24. data/lib/earth/air/aircraft.rb +16 -0
  25. data/lib/earth/air/airline.rb +3 -0
  26. data/lib/earth/air/airline/data_miner.rb +18 -3
  27. data/lib/earth/air/airport.rb +2 -0
  28. data/lib/earth/air/bts_aircraft.rb +2 -0
  29. data/lib/earth/air/flight_distance_class.rb +2 -0
  30. data/lib/earth/air/flight_distance_class_seat_class.rb +2 -0
  31. data/lib/earth/air/flight_seat_class.rb +2 -0
  32. data/lib/earth/air/flight_segment.rb +10 -0
  33. data/lib/earth/air/flight_segment/data_miner.rb +10 -13
  34. data/lib/earth/automobile/automobile_activity_year.rb +21 -0
  35. data/lib/earth/automobile/automobile_activity_year/data_miner.rb +27 -0
  36. data/lib/earth/automobile/automobile_activity_year_type.rb +27 -0
  37. data/lib/earth/automobile/automobile_activity_year_type/data_miner.rb +27 -0
  38. data/lib/earth/automobile/automobile_activity_year_type_fuel.rb +19 -0
  39. data/lib/earth/automobile/automobile_activity_year_type_fuel/data_miner.rb +57 -0
  40. data/lib/earth/automobile/automobile_fuel.rb +93 -86
  41. data/lib/earth/automobile/automobile_fuel/data_miner.rb +64 -70
  42. data/lib/earth/automobile/automobile_make.rb +5 -1
  43. data/lib/earth/automobile/automobile_make/data_miner.rb +10 -37
  44. data/lib/earth/automobile/automobile_make_model.rb +22 -3
  45. data/lib/earth/automobile/automobile_make_model/data_miner.rb +41 -15
  46. data/lib/earth/automobile/automobile_make_model_year.rb +18 -7
  47. data/lib/earth/automobile/automobile_make_model_year/data_miner.rb +43 -27
  48. data/lib/earth/automobile/automobile_make_model_year_variant.rb +44 -8
  49. data/lib/earth/automobile/automobile_make_model_year_variant/data_miner.rb +182 -8
  50. data/lib/earth/automobile/automobile_make_year.rb +4 -2
  51. data/lib/earth/automobile/automobile_make_year/data_miner.rb +16 -15
  52. data/lib/earth/automobile/automobile_make_year_fleet.rb +2 -1
  53. data/lib/earth/automobile/automobile_make_year_fleet/data_miner.rb +5 -2
  54. data/lib/earth/automobile/automobile_model.rb +2 -1
  55. data/lib/earth/automobile/automobile_model/data_miner.rb +1 -2
  56. data/lib/earth/automobile/automobile_size_class.rb +7 -68
  57. data/lib/earth/automobile/automobile_size_class/data_miner.rb +16 -51
  58. data/lib/earth/automobile/automobile_type_fuel.rb +23 -0
  59. data/lib/earth/automobile/automobile_type_fuel/data_miner.rb +52 -0
  60. data/lib/earth/automobile/automobile_type_fuel_control.rb +2 -33
  61. data/lib/earth/automobile/automobile_type_fuel_control/data_miner.rb +19 -4
  62. data/lib/earth/automobile/automobile_type_fuel_year.rb +17 -54
  63. data/lib/earth/automobile/automobile_type_fuel_year/data_miner.rb +40 -94
  64. data/lib/earth/automobile/automobile_type_fuel_year_control.rb +25 -23
  65. data/lib/earth/automobile/automobile_type_fuel_year_control/data_miner.rb +6 -2
  66. data/lib/earth/automobile/automobile_year.rb +38 -1
  67. data/lib/earth/automobile/automobile_year/data_miner.rb +1 -2
  68. data/lib/earth/automobile/dependencies.txt +22 -36
  69. data/lib/earth/bus/bus_class.rb +2 -0
  70. data/lib/earth/bus/bus_fuel.rb +2 -0
  71. data/lib/earth/bus/bus_fuel_control.rb +2 -0
  72. data/lib/earth/bus/bus_fuel_year_control.rb +2 -0
  73. data/lib/earth/computation/computation_carrier.rb +2 -0
  74. data/lib/earth/computation/computation_carrier_instance_class.rb +2 -0
  75. data/lib/earth/computation/computation_carrier_region.rb +2 -0
  76. data/lib/earth/conversions_ext.rb +6 -0
  77. data/lib/earth/diet/diet_class.rb +2 -0
  78. data/lib/earth/diet/food_group.rb +2 -0
  79. data/lib/earth/fuel/fuel.rb +2 -0
  80. data/lib/earth/fuel/fuel/data_miner.rb +15 -0
  81. data/lib/earth/fuel/fuel_price.rb +2 -0
  82. data/lib/earth/fuel/fuel_type.rb +2 -0
  83. data/lib/earth/fuel/fuel_year.rb +2 -0
  84. data/lib/earth/fuel/greenhouse_gas.rb +2 -0
  85. data/lib/earth/hospitality/commercial_building_energy_consumption_survey_response/data_miner.rb +7 -7
  86. data/lib/earth/hospitality/lodging_class.rb +2 -0
  87. data/lib/earth/industry/industry.rb +2 -0
  88. data/lib/earth/industry/mecs_energy/data_miner.rb +1 -1
  89. data/lib/earth/industry/mecs_ratio/data_miner.rb +1 -1
  90. data/lib/earth/locality/census_division.rb +2 -0
  91. data/lib/earth/locality/census_region.rb +2 -0
  92. data/lib/earth/locality/climate_division.rb +2 -0
  93. data/lib/earth/locality/country.rb +4 -0
  94. data/lib/earth/locality/egrid_region.rb +3 -0
  95. data/lib/earth/locality/egrid_subregion.rb +2 -0
  96. data/lib/earth/locality/petroleum_administration_for_defense_district.rb +7 -0
  97. data/lib/earth/locality/state.rb +7 -0
  98. data/lib/earth/locality/zip_code.rb +4 -0
  99. data/lib/earth/pet/breed.rb +7 -0
  100. data/lib/earth/pet/breed/data_miner.rb +1 -1
  101. data/lib/earth/pet/breed_gender.rb +2 -0
  102. data/lib/earth/pet/gender.rb +2 -0
  103. data/lib/earth/pet/species.rb +2 -0
  104. data/lib/earth/rail/country_rail_class.rb +2 -0
  105. data/lib/earth/rail/country_rail_traction.rb +2 -0
  106. data/lib/earth/rail/country_rail_traction_class.rb +2 -0
  107. data/lib/earth/rail/national_transit_database_company.rb +7 -0
  108. data/lib/earth/rail/national_transit_database_mode.rb +2 -0
  109. data/lib/earth/rail/national_transit_database_record.rb +22 -0
  110. data/lib/earth/rail/rail_class.rb +2 -0
  111. data/lib/earth/rail/rail_company.rb +16 -0
  112. data/lib/earth/rail/rail_fuel.rb +2 -0
  113. data/lib/earth/rail/rail_traction.rb +2 -0
  114. data/lib/earth/residence/air_conditioner_use.rb +2 -0
  115. data/lib/earth/residence/clothes_machine_use.rb +2 -0
  116. data/lib/earth/residence/dishwasher_use.rb +2 -0
  117. data/lib/earth/residence/residence_appliance.rb +2 -0
  118. data/lib/earth/residence/residence_class.rb +2 -0
  119. data/lib/earth/residence/residence_fuel_price.rb +2 -0
  120. data/lib/earth/residence/residence_fuel_type.rb +2 -0
  121. data/lib/earth/residence/residential_energy_consumption_survey_response.rb +2 -0
  122. data/lib/earth/residence/urbanity.rb +2 -0
  123. data/lib/earth/shipping/carrier.rb +2 -0
  124. data/lib/earth/shipping/carrier_mode.rb +2 -0
  125. data/lib/earth/shipping/shipment_mode.rb +2 -0
  126. data/lib/earth/version.rb +1 -1
  127. data/spec/earth/air/airline_spec.rb +20 -0
  128. data/spec/earth/air/flight_segment_spec.rb +9 -4
  129. data/spec/earth/automobile/automobile_activity_year_spec.rb +30 -0
  130. data/spec/earth/automobile/automobile_activity_year_type_fuel_spec.rb +25 -0
  131. data/spec/earth/automobile/automobile_activity_year_type_spec.rb +38 -0
  132. data/spec/earth/automobile/automobile_fuel_spec.rb +91 -6
  133. data/spec/earth/automobile/automobile_make_model_spec.rb +74 -0
  134. data/spec/earth/automobile/automobile_make_model_year_spec.rb +90 -0
  135. data/spec/earth/automobile/automobile_make_model_year_variant_spec.rb +139 -90
  136. data/spec/earth/automobile/automobile_make_spec.rb +27 -0
  137. data/spec/earth/automobile/automobile_make_year_fleet_spec.rb +8 -21
  138. data/spec/earth/automobile/automobile_make_year_spec.rb +28 -0
  139. data/spec/earth/automobile/automobile_model_spec.rb +15 -0
  140. data/spec/earth/automobile/automobile_size_class_spec.rb +31 -0
  141. data/spec/earth/automobile/automobile_type_fuel_control_spec.rb +25 -0
  142. data/spec/earth/automobile/automobile_type_fuel_spec.rb +45 -0
  143. data/spec/earth/automobile/automobile_type_fuel_year_control_spec.rb +51 -0
  144. data/spec/earth/automobile/automobile_type_fuel_year_spec.rb +65 -0
  145. data/spec/earth/automobile/automobile_year_spec.rb +23 -0
  146. data/spec/earth/fuel/fuel_spec.rb +1 -1
  147. data/spec/earth/hospitality/commercial_building_energy_consumption_survey_response_spec.rb +11 -3
  148. data/spec/earth_spec.rb +3 -3
  149. data/spec/spec_helper.rb +1 -0
  150. metadata +78 -25
  151. data/lib/earth/automobile/automobile_size_class_year.rb +0 -44
  152. data/lib/earth/automobile/automobile_size_class_year/data_miner.rb +0 -18
  153. data/lib/earth/automobile/automobile_type_fuel_year_age.rb +0 -68
  154. data/lib/earth/automobile/automobile_type_fuel_year_age/data_miner.rb +0 -116
  155. data/lib/earth/automobile/automobile_type_year.rb +0 -58
  156. data/lib/earth/automobile/automobile_type_year/data_miner.rb +0 -30
  157. data/spec/earth/automobile/automobile_type_fuel_year_age_spec.rb +0 -20
@@ -1,100 +1,94 @@
1
1
  require 'earth/fuel/data_miner'
2
+
2
3
  AutomobileFuel.class_eval do
3
4
  data_miner do
4
- import "a list of pure automobile fuels",
5
- :url => 'https://spreadsheets.google.com/pub?key=0AoQJbWqPrREqdE9xTEdueFM2R0diNTgxUlk1QXFSb2c&gid=0&output=csv' do
6
- key 'name'
7
- store 'code'
8
- store 'base_fuel_name'
9
- store 'distance_key'
10
- store 'ef_key'
5
+ process "Start from scratch" do
6
+ delete_all
11
7
  end
12
8
 
13
- import "a list of blended automobile fuels",
14
- :url => 'https://spreadsheets.google.com/pub?key=0AoQJbWqPrREqdEswNGIxM0U4U0N1UUppdWw2ejJEX0E&gid=0&output=csv' do
9
+ import "a Brighter Planet-curated list of automobile fuels",
10
+ :url => "file://#{Earth::DATA_DIR}/automobile/auto_fuel_data.csv" do
15
11
  key 'name'
16
12
  store 'code'
17
- store 'base_fuel_name'
18
- store 'blend_fuel_name'
19
- store 'blend_portion'
13
+ store 'common_name'
20
14
  store 'distance_key'
21
- store 'ef_key'
15
+ store 'base_fuel_name', :nullify => true
16
+ store 'blend_fuel_name', :nullify => true
17
+ store 'blend_portion', :nullify => true
22
18
  end
23
19
 
24
- process "Ensure AutomobileTypeFuelYearAge, AutomobileTypeYear, Fuel, and GreenhouseGas are populated" do
25
- AutomobileTypeFuelYearAge.run_data_miner!
26
- AutomobileTypeYear.run_data_miner!
20
+ process "Ensure Fuel is populated" do
27
21
  Fuel.run_data_miner!
28
- GreenhouseGas.run_data_miner!
29
22
  end
30
23
 
31
- process "Derive annual distance" do
32
- find_each do |record|
33
- scope = record.type_fuel_year_ages.where(:year => record.type_fuel_year_ages.maximum('year'))
34
- record.annual_distance = scope.weighted_average(:annual_distance, :weighted_by => :vehicles)
35
- record.annual_distance_units = scope.first.annual_distance_units
36
- record.save!
24
+ process "Derive energy content and co2 emission factors from Fuel" do
25
+ elec = AutomobileFuel.find 'electricity'
26
+ elec.energy_content = 1.kilowatt_hours.to(:megajoules)
27
+ elec.energy_content_units = 'megajoules_per_kilowatt_hour'
28
+ elec.save!
29
+
30
+ where("name != 'electricity'").each do |auto_fuel|
31
+ %w{ energy_content co2_emission_factor co2_biogenic_emission_factor }.each do |method|
32
+ value = if auto_fuel.blend_portion
33
+ (auto_fuel.blend_portion * auto_fuel.blend_fuel.send(method)) + ((1 - auto_fuel.blend_portion) * auto_fuel.base_fuel.send(method))
34
+ else
35
+ auto_fuel.base_fuel.send method
36
+ end
37
+ auto_fuel.send("#{method}=", value)
38
+ auto_fuel.send("#{method}_units=", auto_fuel.base_fuel.send("#{method}_units"))
39
+ end
40
+ auto_fuel.save!
37
41
  end
38
42
  end
39
43
 
40
- process "Derive energy content" do
41
- find_each do |record|
42
- if record.blend_fuel.present?
43
- record.energy_content = (record.base_fuel.energy_content * (1 - record.blend_portion)) + (record.blend_fuel.energy_content * record.blend_portion)
44
- else
45
- record.energy_content = record.base_fuel.energy_content
46
- end
47
- record.energy_content_units = record.base_fuel.energy_content_units
48
- record.save!
49
- end
44
+ import "Alternative fuel ch4 and n2o emission factors derived from the EPA GHG inventory",
45
+ :url => "file://#{Earth::DATA_DIR}/automobile/auto_fuel_efs.csv" do
46
+ key 'name'
47
+ store 'ch4_emission_factor', :from_units => :grams_per_mile, :to_units => :kilograms_per_kilometre
48
+ store 'n2o_emission_factor', :from_units => :grams_per_mile, :to_units => :kilograms_per_kilometre
49
+ end
50
+
51
+ process "Ensure AutomobileTypeFuel is populated" do
52
+ AutomobileTypeFuel.run_data_miner!
50
53
  end
51
54
 
52
- process "Derive co2 emission factor and co2 biogenic emission factors" do
55
+ process "Derive annual distance, emission factors, and total consumption from AutomobileTypeFuel" do
53
56
  find_each do |record|
54
- if record.blend_fuel.present?
55
- record.co2_emission_factor = (record.base_fuel.co2_emission_factor.to_f * (1 - record.blend_portion)) + (record.blend_fuel.co2_emission_factor.to_f * record.blend_portion)
56
- record.co2_biogenic_emission_factor = (record.base_fuel.co2_biogenic_emission_factor.to_f * (1 - record.blend_portion)) + (record.blend_fuel.co2_biogenic_emission_factor.to_f * record.blend_portion)
57
- else
58
- record.co2_emission_factor = record.base_fuel.co2_emission_factor
59
- record.co2_biogenic_emission_factor = record.base_fuel.co2_biogenic_emission_factor
57
+ if (type_fuels = record.type_fuels).any?
58
+ %w{ annual_distance ch4_emission_factor n2o_emission_factor }.each do |item|
59
+ record.send("#{item}=", type_fuels.weighted_average(item, :weighted_by => :vehicles))
60
+ record.send("#{item}_units=", type_fuels.first.send("#{item}_units"))
61
+ end
62
+ unless record.name =~ / gasoline/
63
+ record.total_consumption = record.type_fuels.sum(:fuel_consumption)
64
+ record.total_consumption_units = record.type_fuels.first.fuel_consumption_units
65
+ end
66
+ record.save!
60
67
  end
61
- record.co2_emission_factor_units = record.base_fuel.co2_emission_factor_units
62
- record.co2_biogenic_emission_factor_units = record.base_fuel.co2_biogenic_emission_factor_units
63
- record.save!
64
68
  end
65
69
  end
66
70
 
67
- process "Derive ch4, n2o, and hfc emission factors" do
68
- find_each do |record|
69
- scope = record.type_fuel_years.where(:year => record.type_fuel_years.maximum('year'))
70
-
71
- record.ch4_emission_factor = scope.weighted_average(:ch4_emission_factor, :weighted_by => :total_travel).to_f * GreenhouseGas[:ch4].global_warming_potential
72
- ch4_prefix = scope.first.ch4_emission_factor_units.split("_per_")[0]
73
- ch4_suffix = scope.first.ch4_emission_factor_units.split("_per_")[1]
74
- record.ch4_emission_factor_units = ch4_prefix + "_co2e_per_" + ch4_suffix
75
-
76
- record.n2o_emission_factor = scope.weighted_average(:n2o_emission_factor, :weighted_by => :total_travel).to_f * GreenhouseGas[:n2o].global_warming_potential
77
- n2o_prefix = scope.first.n2o_emission_factor_units.split("_per_")[0]
78
- n2o_suffix = scope.first.n2o_emission_factor_units.split("_per_")[1]
79
- record.n2o_emission_factor_units = n2o_prefix + "_co2e_per_" + n2o_suffix
80
-
81
- record.hfc_emission_factor = scope.map do |tfy|
82
- tfy.total_travel.to_f * tfy.type_year.hfc_emission_factor
83
- end.sum / scope.sum('total_travel')
84
- record.hfc_emission_factor_units = scope.first.type_year.hfc_emission_factor_units
85
-
86
- record.save!
71
+ process "Derive annual distance for alternative fuels" do
72
+ %w{ diesel gasoline }.each do |key|
73
+ reference_fuel = find(key)
74
+ where(:annual_distance => nil, :distance_key => key).update_all %{
75
+ annual_distance = #{reference_fuel.annual_distance},
76
+ annual_distance_units = '#{reference_fuel.annual_distance_units}'
77
+ }
87
78
  end
88
79
  end
89
80
 
90
- # FIXME TODO DEPRECATED motorcycle needs this
91
- process "Derive emission factor" do
92
- update_all(%{
93
- emission_factor = 1.0 * co2_emission_factor + ch4_emission_factor + n2o_emission_factor + hfc_emission_factor,
94
- emission_factor_units = 'kilograms_co2e_per_litre'
95
- })
81
+ process "Ensure GreenhouseGas is populated" do
82
+ GreenhouseGas.run_data_miner!
96
83
  end
97
84
 
98
- # FIXME TODO verify code somehow
85
+ process "Convert emission factors to co2e" do
86
+ %w{ ch4 n2o }.each do |gas|
87
+ where("#{gas}_emission_factor_units = 'kilograms_per_kilometre'").update_all %{
88
+ #{gas}_emission_factor = #{gas}_emission_factor * #{GreenhouseGas[gas].global_warming_potential},
89
+ #{gas}_emission_factor_units = 'kilograms_co2e_per_kilometre'
90
+ }
91
+ end
92
+ end
99
93
  end
100
94
  end
@@ -1,8 +1,12 @@
1
- require 'earth/fuel'
2
1
  class AutomobileMake < ActiveRecord::Base
3
2
  self.primary_key = "name"
4
3
 
4
+ # for calculating fuel efficiency
5
+ has_many :make_years, :foreign_key => :make_name, :primary_key => :name, :class_name => 'AutomobileMakeYear'
6
+
5
7
  col :name
6
8
  col :fuel_efficiency, :type => :float
7
9
  col :fuel_efficiency_units
10
+
11
+ warn_unless_size 81
8
12
  end
@@ -1,54 +1,27 @@
1
- require 'earth/fuel/data_miner'
2
1
  AutomobileMake.class_eval do
3
2
  data_miner do
4
3
  process "Start from scratch" do
5
4
  delete_all
6
5
  end
7
6
 
8
- process "Ensure AutomobileMakeModelYearVariant and AutomobileMakeYearFleet are populated" do
9
- AutomobileMakeModelYearVariant.run_data_miner!
10
- AutomobileMakeYearFleet.run_data_miner!
7
+ process "Ensure AutomobileMakeYear is populated" do
8
+ AutomobileMakeYear.run_data_miner!
11
9
  end
12
10
 
13
- process "Derive manufacturer names from automobile make model year variants" do
11
+ process "Derive manufacturer names from AutomobileMakeYear" do
14
12
  ::Earth::Utils.insert_ignore(
15
- :src => AutomobileMakeModelYearVariant,
13
+ :src => AutomobileMakeYear,
16
14
  :dest => AutomobileMake,
17
15
  :cols => { :make_name => :name }
18
16
  )
19
17
  end
20
18
 
21
- # sabshere 1/31/11 add Avanti, DaimlerChrysler, IHC, Tesla, etc.
22
- process "Derive extra manufacturer names from CAFE data" do
23
- ::Earth::Utils.insert_ignore(
24
- :src => AutomobileMakeYearFleet,
25
- :dest => AutomobileMake,
26
- :cols => { :make_name => :name }
27
- )
28
- end
29
-
30
- # FIXME TODO derive units here
31
- process "Calculate fuel efficiency from CAFE data" do
32
- makes = arel_table
33
- year_fleets = AutomobileMakeYearFleet.arel_table
34
- conditional_relation = makes[:name].eq(year_fleets[:make_name])
35
- relation = AutomobileMakeYearFleet.weighted_average_relation(:fuel_efficiency, :weighted_by => :volume).where(conditional_relation)
36
- update_all(%{
37
- fuel_efficiency = (#{relation.to_sql}),
38
- fuel_efficiency_units = 'kilometres_per_litre'
39
- })
40
- end
41
-
42
- # FIXME TODO derive units here
43
- process "Calculate any missing fuel effeciencies from automobile make model year variants" do
44
- makes = arel_table
45
- variants = AutomobileMakeModelYearVariant.arel_table
46
- conditional_relation = variants[:make_name].eq(makes[:name])
47
- relation = variants.project(variants[:fuel_efficiency].average).where(conditional_relation)
48
- where(:fuel_efficiency => nil).update_all(%{
49
- fuel_efficiency = (#{relation.to_sql}),
50
- fuel_efficiency_units = 'kilometres_per_litre'
51
- })
19
+ process "Derive fuel efficiency from AutomobileMakeYear" do
20
+ find_each do |make|
21
+ make.fuel_efficiency = make.make_years.weighted_average(:fuel_efficiency)
22
+ make.fuel_efficiency_units = make.make_years.first.fuel_efficiency_units
23
+ make.save!
24
+ end
52
25
  end
53
26
  end
54
27
  end
@@ -1,12 +1,31 @@
1
- require 'earth/fuel'
2
1
  class AutomobileMakeModel < ActiveRecord::Base
3
2
  self.primary_key = "name"
4
3
 
5
- col :name # make + model
4
+ # Used by Automobile and AutomobileTrip to look up auto fuel and alt auto fuel
5
+ belongs_to :automobile_fuel, :foreign_key => :fuel_code, :primary_key => :code
6
+ belongs_to :alt_automobile_fuel, :foreign_key => :alt_fuel_code, :primary_key => :code, :class_name => 'AutomobileFuel'
7
+
8
+ # for deriving fuel codes and type name
9
+ def model_years
10
+ AutomobileMakeModelYear.where(:make_name => make_name, :model_name => model_name)
11
+ end
12
+
13
+ col :name
6
14
  col :make_name
7
- col :model_name # model only
15
+ col :model_name
16
+ col :fuel_code
8
17
  col :fuel_efficiency_city, :type => :float
9
18
  col :fuel_efficiency_city_units
10
19
  col :fuel_efficiency_highway, :type => :float
11
20
  col :fuel_efficiency_highway_units
21
+ col :alt_fuel_code
22
+ col :alt_fuel_efficiency_city, :type => :float
23
+ col :alt_fuel_efficiency_city_units
24
+ col :alt_fuel_efficiency_highway, :type => :float
25
+ col :alt_fuel_efficiency_highway_units
26
+ col :type_name
27
+
28
+ warn_unless_size 2353
29
+ warn_if_nulls_except :alt_fuel_code
30
+ warn_if_nulls /alt_fuel_efficiency/, :conditions => 'alt_fuel_code IS NOT NULL'
12
31
  end
@@ -5,13 +5,13 @@ AutomobileMakeModel.class_eval do
5
5
  delete_all
6
6
  end
7
7
 
8
- process "Ensure AutomobileMakeModelYearVariant is populated" do
9
- AutomobileMakeModelYearVariant.run_data_miner!
8
+ process "Ensure AutomobileMakeModelYear is populated" do
9
+ AutomobileMakeModelYear.run_data_miner!
10
10
  end
11
11
 
12
- process "Derive model names from automobile make model year variants" do
12
+ process "Derive model names from AutomobileMakeModelYear" do
13
13
  ::Earth::Utils.insert_ignore(
14
- :src => AutomobileMakeModelYearVariant,
14
+ :src => AutomobileMakeModelYear,
15
15
  :dest => AutomobileMakeModel,
16
16
  :cols => {
17
17
  [:make_name, :model_name] => :name,
@@ -21,18 +21,44 @@ AutomobileMakeModel.class_eval do
21
21
  )
22
22
  end
23
23
 
24
- # FIXME TODO not weighted until we get weightings on auto variants
25
- process "Derive average fuel economy from automobile make model year variants" do
24
+ process "Derive fuel codes and type name from AutomobileMakeModelYear" do
25
+ find_each do |amm|
26
+ codes = amm.model_years.map(&:fuel_code).uniq
27
+ if codes.count == 1
28
+ amm.fuel_code = codes.first
29
+ elsif codes.all?{ |code| ['R', 'P', 'G'].include? code }
30
+ amm.fuel_code = 'G'
31
+ end
32
+
33
+ alt_codes = amm.model_years.map(&:alt_fuel_code).uniq
34
+ amm.alt_fuel_code = (alt_codes.first if alt_codes.count == 1)
35
+
36
+ type_names = amm.model_years.map(&:type_name).uniq
37
+ amm.type_name = (type_names.one? ? type_names.first : nil)
38
+
39
+ amm.save!
40
+ end
41
+ end
42
+
43
+ process "Derive fuel efficiencies from AutomobileMakeModelYear" do
26
44
  models = arel_table
27
- variants = AutomobileMakeModelYearVariant.arel_table
28
- conditional_relation = models[:make_name].eq(variants[:make_name]).and(models[:model_name].eq(variants[:model_name]))
29
- %w{ city highway }.each do |type|
30
- null_check = variants[:"fuel_efficiency_#{type}"].not_eq(nil)
31
- relation = variants.project(variants[:"fuel_efficiency_#{type}"].average).where(conditional_relation).where(null_check)
32
- update_all(%{
33
- fuel_efficiency_#{type} = (#{relation.to_sql}),
34
- fuel_efficiency_#{type}_units = 'kilometres_per_litre'
35
- })
45
+ model_years = AutomobileMakeModelYear.arel_table
46
+ join_relation = model_years[:make_name].eq(models[:make_name]).and(model_years[:model_name].eq(models[:model_name]))
47
+
48
+ %w{ fuel_efficiency_city fuel_efficiency_highway }.each do |fe|
49
+ fe_sql = AutomobileMakeModelYear.where(join_relation).weighted_average_relation("#{fe}").to_sql
50
+ update_all %{
51
+ #{fe} = (#{fe_sql}),
52
+ #{fe}_units = 'kilometres_per_litre'
53
+ }
54
+ end
55
+
56
+ %w{ alt_fuel_efficiency_city alt_fuel_efficiency_highway }.each do |fe|
57
+ fe_sql = AutomobileMakeModelYear.where(join_relation).weighted_average_relation("#{fe}").to_sql
58
+ where("alt_fuel_code IS NOT NULL").update_all %{
59
+ #{fe} = (#{fe_sql}),
60
+ #{fe}_units = 'kilometres_per_litre'
61
+ }
36
62
  end
37
63
  end
38
64
  end
@@ -1,18 +1,29 @@
1
- require 'earth/fuel'
2
1
  class AutomobileMakeModelYear < ActiveRecord::Base
3
2
  self.primary_key = "name"
4
3
 
5
- # Need this so Automobile and AutomobileTrip can do characteristics[:make_model_year].automobile_fuel
6
- belongs_to :automobile_fuel, :foreign_key => 'fuel_code', :primary_key => 'code'
4
+ # Used by Automobile and AutomobileTrip to look up auto fuel and alt auto fuel
5
+ belongs_to :automobile_fuel, :foreign_key => 'fuel_code', :primary_key => 'code'
6
+ belongs_to :alt_automobile_fuel, :foreign_key => 'alt_fuel_code', :primary_key => 'code', :class_name => 'AutomobileFuel'
7
7
 
8
- col :name # make + model + year
8
+ col :name
9
9
  col :make_name
10
10
  col :model_name
11
- col :year, :type => :integer
11
+ col :year, :type => :integer
12
+ col :hybridity,:type => :boolean
12
13
  col :fuel_code
13
- col :hybridity, :type => :boolean
14
- col :fuel_efficiency_city, :type => :float
14
+ col :fuel_efficiency_city, :type => :float
15
15
  col :fuel_efficiency_city_units
16
16
  col :fuel_efficiency_highway, :type => :float
17
17
  col :fuel_efficiency_highway_units
18
+ col :alt_fuel_code
19
+ col :alt_fuel_efficiency_city, :type => :float
20
+ col :alt_fuel_efficiency_city_units
21
+ col :alt_fuel_efficiency_highway, :type => :float
22
+ col :alt_fuel_efficiency_highway_units
23
+ col :type_name # whether the vehicle is a passenger car or light-duty truck
24
+ col :weighting, :type => :float # for calculating AutomobileMakeModel fuel efficiencies
25
+
26
+ warn_unless_size 10997
27
+ warn_if_nulls_except :alt_fuel_code
28
+ warn_if_nulls /alt_fuel_efficiency/, :conditions => 'alt_fuel_code IS NOT NULL'
18
29
  end
@@ -1,4 +1,3 @@
1
- require 'earth/fuel/data_miner'
2
1
  AutomobileMakeModelYear.class_eval do
3
2
  data_miner do
4
3
  process "Start from scratch" do
@@ -9,7 +8,7 @@ AutomobileMakeModelYear.class_eval do
9
8
  AutomobileMakeModelYearVariant.run_data_miner!
10
9
  end
11
10
 
12
- process "Derive model year names from automobile make model year variants" do
11
+ process "Derive names AutomobileMakeModelYearVariant" do
13
12
  ::Earth::Utils.insert_ignore(
14
13
  :src => AutomobileMakeModelYearVariant,
15
14
  :dest => AutomobileMakeModelYear,
@@ -22,40 +21,57 @@ AutomobileMakeModelYear.class_eval do
22
21
  )
23
22
  end
24
23
 
25
- process "Derive fuel from automobile make model year variants" do
26
- model_years = arel_table
27
- variants = AutomobileMakeModelYearVariant.arel_table
28
- 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]))
29
- 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})"
30
- end
31
-
32
- # FIXME TODO not in automobile_make_model_year_variants because they're missing from the EPA FEG download files:
33
- # 2005 Honda Accord Hybrid
34
- # 2006 Honda Accord Hybrid
35
- # 2009 Chrysler Aspen HEV
36
- # 2009 Dodge Durango HEV
37
- import "A list of hybrid make model years derived from the EPA fuel economy guide",
38
- :url => 'https://docs.google.com/spreadsheet/pub?hl=en_US&hl=en_US&key=0AoQJbWqPrREqdGtzekE4cGNoRGVmdmZMaTNvOWluSnc&output=csv' do
39
- key 'name', :synthesize => proc { |record| [record['make_name'], record['model_name'], record['year']].join(' ') }
40
- store 'hybridity'
24
+ process "Identify hybrid vehicles" do
25
+ where("model_name LIKE '%HYBRID%'").update_all :hybridity => true
26
+ where("make_name = 'Infiniti' AND model_name REGEXP '[A-Z][0-9]{2}H'").update_all :hybridity => true
27
+ where("make_name = 'Lexus' AND model_name REGEXP '[A-Z]{2}[0-9]{3}H'").update_all :hybridity => true
28
+ where(:make_name => 'Chevrolet', :model_name => 'VOLT').update_all :hybridity => true
29
+ where(:make_name => 'Honda', :model_name => 'INSIGHT').update_all :hybridity => true
30
+ where(:make_name => 'Honda', :model_name => 'CR-Z').update_all :hybridity => true
31
+ where("make_name = 'Toyota' AND model_name LIKE 'PRIUS%'").update_all :hybridity => true
32
+ where(:hybridity => nil).update_all :hybridity => false
41
33
  end
42
34
 
43
- process "Set hybridity to FALSE for all other make model years" do
44
- where(:hybridity => nil).update_all :hybridity => false
35
+ process "Derive fuel codes from AutomobileMakeModelYearVariant" do
36
+ model_years = arel_table
37
+ variants = AutomobileMakeModelYearVariant.arel_table
38
+ join_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]))
39
+
40
+ update_all "fuel_code = (#{variants.project('GROUP_CONCAT(DISTINCT fuel_code)').where(join_relation).to_sql})"
41
+ update_all "alt_fuel_code = (#{variants.project('GROUP_CONCAT(DISTINCT alt_fuel_code)').where(join_relation).to_sql})"
42
+ where(:fuel_code => ['R,P', 'P,R']).update_all "fuel_code = 'G'"
45
43
  end
46
44
 
47
45
  # FIXME TODO: weight by volume somehow
48
- process "Calculate city and highway fuel efficiency from automobile make model year variants" do
46
+ process "Calculate city and highway fuel efficiency from AutomobileMakeModelYearVariants" do
49
47
  model_years = arel_table
50
48
  variants = AutomobileMakeModelYearVariant.arel_table
51
- 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]))
52
- %w{ city highway }.each do |type|
53
- null_check = variants[:"fuel_efficiency_#{type}"].not_eq(nil)
54
- relation = variants.project(variants[:"fuel_efficiency_#{type}"].average).where(conditional_relation).where(null_check)
49
+
50
+ join_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{ fuel_efficiency_city fuel_efficiency_highway }.each do |fe|
55
52
  update_all(%{
56
- fuel_efficiency_#{type} = (#{relation.to_sql}),
57
- fuel_efficiency_#{type}_units = 'kilometres_per_litre'
53
+ #{fe} = (#{variants.project(variants["#{fe}"].average).where(join_relation).to_sql}),
54
+ #{fe}_units = 'kilometres_per_litre'
58
55
  })
56
+ where("alt_fuel_code IS NOT NULL").update_all(%{
57
+ alt_#{fe} = (#{variants.project(variants["alt_#{fe}"].average).where(join_relation).to_sql}),
58
+ alt_#{fe}_units = 'kilometres_per_litre'
59
+ })
60
+ end
61
+ end
62
+
63
+ process "Derive type name from AutomobileMakeModelYearVariant" do
64
+ find_each do |ammy|
65
+ type_names = AutomobileMakeModelYearVariant.where(:make_name => ammy.make_name, :model_name => ammy.model_name, :year => ammy.year).map(&:type_name).uniq
66
+ ammy.type_name = (type_names.one? ? type_names.first : nil)
67
+ ammy.save!
68
+ end
69
+ end
70
+
71
+ # For calculating AutomobileMakeModel fuel efficiencies
72
+ process "Derive weighting from AutomobileYear" do
73
+ connection.select_values("SELECT DISTINCT year FROM #{quoted_table_name}").each do |year|
74
+ where(:year => year).update_all "weighting = #{AutomobileYear.weighting(year)}"
59
75
  end
60
76
  end
61
77
  end