earth 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/earth.gemspec +2 -2
  2. data/features/automobile_fuel.feature +100 -0
  3. data/features/bus_class.feature +12 -42
  4. data/features/bus_fuel.feature +114 -0
  5. data/features/egrid_subregion.feature +113 -15
  6. data/features/support/imports/automobile_fuel_bad.csv +3 -3
  7. data/features/support/imports/automobile_fuel_good.csv +3 -3
  8. data/features/support/imports/bus_class_bad.csv +2 -3
  9. data/features/support/imports/bus_class_good.csv +2 -3
  10. data/features/support/imports/bus_fuel_bad.csv +3 -0
  11. data/features/support/imports/bus_fuel_good.csv +3 -0
  12. data/features/support/imports/egrid_subregion_bad.csv +2 -3
  13. data/features/support/imports/egrid_subregion_good.csv +2 -3
  14. data/lib/earth/automobile/automobile_fuel.rb +63 -58
  15. data/lib/earth/automobile/automobile_fuel/data_miner.rb +110 -0
  16. data/lib/earth/bus.rb +3 -0
  17. data/lib/earth/bus/bus_class.rb +21 -2
  18. data/lib/earth/bus/bus_class/data_miner.rb +79 -43
  19. data/lib/earth/bus/bus_fuel.rb +18 -0
  20. data/lib/earth/bus/bus_fuel/data_miner.rb +204 -0
  21. data/lib/earth/bus/bus_fuel_control.rb +7 -0
  22. data/lib/earth/bus/bus_fuel_control/data_miner.rb +41 -0
  23. data/lib/earth/bus/bus_fuel_year_control.rb +13 -0
  24. data/lib/earth/bus/bus_fuel_year_control/data_miner.rb +35 -0
  25. data/lib/earth/bus/data_miner.rb +3 -0
  26. data/lib/earth/fuel/fuel.rb +16 -0
  27. data/lib/earth/fuel/fuel/data_miner.rb +6 -1
  28. data/lib/earth/locality/egrid_region.rb +3 -2
  29. data/lib/earth/locality/egrid_region/data_miner.rb +8 -31
  30. data/lib/earth/locality/egrid_subregion.rb +18 -2
  31. data/lib/earth/locality/egrid_subregion/data_miner.rb +109 -56
  32. data/spec/earth/automobile/automobile_fuel_spec.rb +9 -12
  33. data/spec/earth/bus/bus_class_spec.rb +12 -0
  34. data/spec/earth/bus/bus_fuel_control_spec.rb +12 -0
  35. data/spec/earth/bus/bus_fuel_year_control_spec.rb +16 -0
  36. data/spec/earth/pet/species_spec.rb +0 -1
  37. data/spec/earth_spec.rb +2 -2
  38. metadata +46 -16
@@ -1,3 +1,3 @@
1
- name,base_fuel_name,distance_key,ef_key,blend_portion
2
- regular gasoline
3
- b20,Distillate Fuel Oil No. 2,diesel,diesel,1.1
1
+ name,co2_emission_factor,co2_emission_factor_units,co2_biogenic_emission_factor,co2_biogenic_emission_factor_units,ch4_emission_factor,ch4_emission_factor_units,n2o_emission_factor,n2o_emission_factor_units,hfc_emission_factor,hfc_emission_factor_units,base_fuel_name,distance_key,ef_key,blend_portion
2
+ regular gasoline,-1,kilograms_per_gallon,-1,kilograms_per_gallon,0,kilograms_per_litre,0,kilograms_per_litre,0,kilograms_per_litre
3
+ b20,-1,kilograms_per_gallon,-1,kilograms_per_gallon,0,kilograms_per_litre,0,kilograms_per_litre,0,kilograms_per_litre,Distillate Fuel Oil No. 2,diesel,diesel,1.1
@@ -1,3 +1,3 @@
1
- name,base_fuel_name,distance_key,ef_key,blend_portion
2
- regular gasoline,Motor Gasoline,gasoline,gasoline
3
- b20,Distillate Fuel Oil No. 2,diesel,diesel,0.2
1
+ name,co2_emission_factor,co2_emission_factor_units,co2_biogenic_emission_factor,co2_biogenic_emission_factor_units,ch4_emission_factor,ch4_emission_factor_units,n2o_emission_factor,n2o_emission_factor_units,hfc_emission_factor,hfc_emission_factor_units,base_fuel_name,distance_key,ef_key,blend_portion
2
+ regular gasoline,1,kilograms_per_litre,0,kilograms_per_litre,0.1,kilograms_co2e_per_litre,0.1,kilograms_co2e_per_litre,0.1,kilograms_co2e_per_litre,Motor Gasoline,gasoline,gasoline
3
+ b20,0,kilograms_per_litre,1,kilograms_per_litre,0.1,kilograms_co2e_per_litre,0.1,kilograms_co2e_per_litre,0.1,kilograms_co2e_per_litre,Distillate Fuel Oil No. 2,diesel,diesel,0.2
@@ -1,3 +1,2 @@
1
- name,distance,distance_units,passengers,speed,speed_units,diesel_intensity,diesel_intensity_units,alternative_fuels_intensity,alternative_fuels_intensity_units,air_conditioning_emission_factor,air_conditioning_emission_factor_units
2
- transit,10,kilometres,15,20,kilometres_per_hour,0.5,litres_per_kilometre,0,litres_per_kilometre,0,kilograms_per_kilometre
3
- regional,-10,distance_units,0,,,-2,diesel_intensity_units,-2,alternative_fuels_intensity_units
1
+ name,distance,distance_units,passengers,speed,speed_units,gasoline_intensity,gasoline_intensity_units,diesel_intensity,diesel_intensity_units,cng_intensity,cng_intensity_units,lng_intensity,lng_intensity_units,lpg_intensity,lpg_intensity_units,methanol_intensity,methanol_intensity_units,biodiesel_intensity,biodiesel_intensity_units,electricity_intensity,electricity_intensity_units,air_conditioning_emission_factor,air_conditioning_emission_factor_units,alternative_fuels_intensity,alternative_fuels_intensity_units
2
+ city transit,0,miles,0,0,miles_per_hour,-1,gallons_per_mile,0,gallons_per_mile,-1,gallons_per_mile,-1,gallons_per_mile,-1,gallons_per_mile,-1,gallons_per_mile,-1,gallons_per_mile,-1,kilowatt_hours_per_mile,0,pounds_co2e_per_mile,-1,gallons_per_mile
@@ -1,3 +1,2 @@
1
- name,distance,distance_units,passengers,speed,speed_units,diesel_intensity,diesel_intensity_units,alternative_fuels_intensity,alternative_fuels_intensity_units,air_conditioning_emission_factor,air_conditioning_emission_factor_units
2
- transit,10,kilometres,15,20,kilometres_per_hour,0.5,litres_per_kilometre,0,litres_per_kilometre,0,kilograms_per_kilometre
3
- regional,100,kilometres,30,80,kilometres_per_hour,0.1,litres_per_kilometre,0.2,litres_per_kilometre,0.5,kilograms_per_kilometre
1
+ name,distance,distance_units,passengers,speed,speed_units,gasoline_intensity,gasoline_intensity_units,diesel_intensity,diesel_intensity_units,cng_intensity,cng_intensity_units,lng_intensity,lng_intensity_units,lpg_intensity,lpg_intensity_units,methanol_intensity,methanol_intensity_units,biodiesel_intensity,biodiesel_intensity_units,electricity_intensity,electricity_intensity_units,air_conditioning_emission_factor,air_conditioning_emission_factor_units,alternative_fuels_intensity,alternative_fuels_intensity_units
2
+ city transit,1,kilometres,1,1,kilometres_per_hour,0,litres_per_kilometre,1,litres_per_kilometre,0,litres_per_kilometre,0,litres_per_kilometre,0,litres_per_kilometre,0,litres_per_kilometre,0,litres_per_kilometre,0,kilowatt_hours_per_kilometre,1,kilograms_co2e_per_kilometre,0,litres_per_kilometre
@@ -0,0 +1,3 @@
1
+ name,co2_emission_factor,co2_emission_factor_units,co2_biogenic_emission_factor,co2_biogenic_emission_factor_units,ch4_emission_factor,ch4_emission_factor_units,n2o_emission_factor,n2o_emission_factor_units,fuel_name,energy_content,energy_content_units
2
+ CNG,-1,kilograms_per_gallon,-1,kilograms_per_gallon,0,kilograms_per_kilometre,0,kilograms_per_kilometre
3
+ LNG,1,kilograms_per_litre,0,kilograms_per_litre,0.1,kilograms_co2e_per_kilometre,0.1,kilograms_co2e_per_kilometre,Pipeline Natural Gas,0,btu_per_gallon
@@ -0,0 +1,3 @@
1
+ name,co2_emission_factor,co2_emission_factor_units,co2_biogenic_emission_factor,co2_biogenic_emission_factor_units,ch4_emission_factor,ch4_emission_factor_units,n2o_emission_factor,n2o_emission_factor_units,fuel_name,energy_content,energy_content_units
2
+ CNG,0,kilograms_per_litre,1,kilograms_per_litre,0.1,kilograms_co2e_per_kilometre,0.1,kilograms_co2e_per_kilometre,Pipeline Natural Gas
3
+ LNG,1,kilograms_per_litre,0,kilograms_per_litre,0.1,kilograms_co2e_per_kilometre,0.1,kilograms_co2e_per_kilometre,Pipeline Natural Gas,10,megajoules_per_litre
@@ -1,3 +1,2 @@
1
- name,egrid_region_name,electricity_emission_factor,electricity_emission_factor_units
2
- US,US,1.2,kilograms_per_kilowatt_hour
3
- AKGD,foo,0
1
+ abbreviation,net_generation,net_generation_units,electricity_co2_emission_factor,electricity_co2_emission_factor_units,electricity_co2_biogenic_emission_factor,electricity_co2_biogenic_emission_factor_units,electricity_ch4_emission_factor,electricity_ch4_emission_factor_units,electricity_n2o_emission_factor,electricity_n2o_emission_factor_units,electricity_emission_factor,electricity_emission_factor_units,egrid_region_name
2
+ NEWE,0,kilowatt_hours,0,pounds_per_megawatt_hour,-1,pounds_per_megawatt_hour,0,pounds_per_gigawatt_hour,0,pounds_per_gigawatt_hour,0,pounds_per_megawatt_hour
@@ -1,3 +1,2 @@
1
- name,egrid_region_name,electricity_emission_factor,electricity_emission_factor_units
2
- US,US,1.2,kilograms_co2e_per_kilowatt_hour
3
- AKGD,AK,0.9,kilograms_co2e_per_kilowatt_hour
1
+ abbreviation,net_generation,net_generation_units,electricity_co2_emission_factor,electricity_co2_emission_factor_units,electricity_co2_biogenic_emission_factor,electricity_co2_biogenic_emission_factor_units,electricity_ch4_emission_factor,electricity_ch4_emission_factor_units,electricity_n2o_emission_factor,electricity_n2o_emission_factor_units,electricity_emission_factor,electricity_emission_factor_units,egrid_region_name
2
+ NEWE,1350,megawatt_hours,0.4,kilograms_per_kilowatt_hour,0,kilograms_per_kilowatt_hour,0.001,kilograms_co2e_per_kilowatt_hour,0.002,kilograms_co2e_per_kilowatt_hour,0.4,kilograms_co2e_per_kilowatt_hour,E
@@ -18,74 +18,79 @@ class AutomobileFuel < ActiveRecord::Base
18
18
  diesel_use = AutomobileTypeFuelYear.where(:year => latest_year, :fuel_common_name => 'diesel').sum('fuel_consumption')
19
19
  diesel_use / (gas_use + diesel_use)
20
20
  end
21
+
22
+ def fallback_co2_emission_factor
23
+ (Fuel.find_by_name("Motor Gasoline").co2_emission_factor * (1 - AutomobileFuel.fallback_blend_portion)) +
24
+ (Fuel.find_by_name("Distillate Fuel Oil No. 2").co2_emission_factor * AutomobileFuel.fallback_blend_portion)
25
+ end
26
+
27
+ def fallback_co2_emission_factor_units
28
+ Fuel.find_by_name("Motor Gasoline").co2_emission_factor_units
29
+ end
30
+
31
+ def fallback_co2_biogenic_emission_factor
32
+ (Fuel.find_by_name("Motor Gasoline").co2_biogenic_emission_factor * (1 - AutomobileFuel.fallback_blend_portion)) +
33
+ (Fuel.find_by_name("Distillate Fuel Oil No. 2").co2_biogenic_emission_factor * AutomobileFuel.fallback_blend_portion)
34
+ end
35
+
36
+ def fallback_co2_biogenic_emission_factor_units
37
+ Fuel.find_by_name("Motor Gasoline").co2_biogenic_emission_factor_units
38
+ end
39
+
40
+ def fallback_latest_type_fuel_years
41
+ AutomobileTypeFuelYear.where(:year => AutomobileTypeFuelYear.maximum('year'))
42
+ end
43
+
44
+ def fallback_ch4_emission_factor
45
+ fallback_latest_type_fuel_years.weighted_average(:ch4_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:ch4].global_warming_potential
46
+ end
47
+
48
+ def fallback_ch4_emission_factor_units
49
+ prefix = fallback_latest_type_fuel_years.first.ch4_emission_factor_units.split("_per_")[0]
50
+ suffix = fallback_latest_type_fuel_years.first.ch4_emission_factor_units.split("_per_")[1]
51
+ prefix + "_co2e_per_" + suffix
52
+ end
53
+
54
+ def fallback_n2o_emission_factor
55
+ fallback_latest_type_fuel_years.weighted_average(:n2o_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:n2o].global_warming_potential
56
+ end
57
+
58
+ def fallback_n2o_emission_factor_units
59
+ prefix = fallback_latest_type_fuel_years.first.n2o_emission_factor_units.split("_per_")[0]
60
+ suffix = fallback_latest_type_fuel_years.first.n2o_emission_factor_units.split("_per_")[1]
61
+ prefix + "_co2e_per_" + suffix
62
+ end
63
+
64
+ def fallback_hfc_emission_factor
65
+ fallback_latest_type_fuel_years.map do |tfy|
66
+ tfy.total_travel * tfy.type_year.hfc_emission_factor
67
+ end.sum / fallback_latest_type_fuel_years.sum('total_travel')
68
+ end
69
+
70
+ def fallback_hfc_emission_factor_units
71
+ fallback_latest_type_fuel_years.first.type_year.hfc_emission_factor_units
72
+ end
21
73
  end
22
74
 
23
- falls_back_on :name => 'fallback',
24
- :base_fuel_name => 'Motor Gasoline',
25
- :blend_fuel_name => 'Distillate Fuel Oil No. 2',
26
- :blend_portion => lambda { AutomobileFuel.fallback_blend_portion },
27
- :distance_key => 'fallback',
28
- :ef_key => 'fallback'
75
+ falls_back_on :co2_emission_factor => lambda { AutomobileFuel.fallback_co2_emission_factor },
76
+ :co2_emission_factor_units => lambda { AutomobileFuel.fallback_co2_emission_factor_units },
77
+ :co2_biogenic_emission_factor => lambda { AutomobileFuel.fallback_co2_biogenic_emission_factor },
78
+ :co2_biogenic_emission_factor_units => lambda { AutomobileFuel.fallback_co2_biogenic_emission_factor_units },
79
+ :ch4_emission_factor => lambda { AutomobileFuel.fallback_ch4_emission_factor },
80
+ :ch4_emission_factor_units => lambda { AutomobileFuel.fallback_ch4_emission_factor_units },
81
+ :n2o_emission_factor => lambda { AutomobileFuel.fallback_n2o_emission_factor },
82
+ :n2o_emission_factor_units => lambda { AutomobileFuel.fallback_n2o_emission_factor_units },
83
+ :hfc_emission_factor => lambda { AutomobileFuel.fallback_hfc_emission_factor },
84
+ :hfc_emission_factor_units => lambda { AutomobileFuel.fallback_hfc_emission_factor_units }
29
85
 
30
86
  data_miner do
31
- tap "Brighter Planet's sanitized automobile fuel type data", Earth.taps_server
87
+ tap "Brighter Planet's sanitized automobile fuel data", Earth.taps_server
32
88
 
33
89
  process "pull dependencies" do
34
90
  run_data_miner_on_belongs_to_associations
35
91
  end
36
92
  end
37
93
 
38
- # FIXME TODO should I run data miner on has_many associations?
39
- # AutomobileTypeFuelYearAge
40
- # => AutomobileTypeFuelYearControl
41
- # => AutomobileTypeFuelControl
42
- # AutomobileTypeYear
43
-
44
- # FIXME TODO should I run data miner on other classes we need?
45
- # Fuel
46
- # => FuelYear
47
- # GreenhouseGas
48
-
49
- def annual_distance # returns km
50
- scope = type_fuel_year_ages.any? ? type_fuel_year_ages : AutomobileTypeFuelYearAge
51
- scope.where(:year => scope.maximum('year')).weighted_average(:annual_distance, :weighted_by => :vehicles)
52
- end
53
-
54
- def co2_emission_factor # returns kg co2 / litre
55
- if blend_fuel.present?
56
- (base_fuel.co2_emission_factor * (1 - blend_portion)) + (blend_fuel.co2_emission_factor * blend_portion)
57
- else
58
- base_fuel.co2_emission_factor
59
- end
60
- end
61
-
62
- def co2_biogenic_emission_factor # returns kg co2 / litre
63
- if blend_fuel.present?
64
- (base_fuel.co2_biogenic_emission_factor * (1 - blend_portion)) + (blend_fuel.co2_biogenic_emission_factor * blend_portion)
65
- else
66
- base_fuel.co2_biogenic_emission_factor
67
- end
68
- end
69
-
70
- def latest_type_fuel_years
71
- scope = type_fuel_years.any? ? type_fuel_years : AutomobileTypeFuelYear
72
- scope.where(:year => scope.maximum('year'))
73
- end
74
-
75
- def ch4_emission_factor # returns kg co2e / litre
76
- latest_type_fuel_years.weighted_average(:ch4_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:ch4].global_warming_potential
77
- end
78
-
79
- def n2o_emission_factor # returns kg co2e / litre
80
- latest_type_fuel_years.weighted_average(:n2o_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:n2o].global_warming_potential
81
- end
82
-
83
- def hfc_emission_factor # returns kg co2e / litre (hfc emission factor is already in co2e)
84
- latest_type_fuel_years.map do |type_fuel_year|
85
- type_fuel_year.total_travel * type_fuel_year.type_year.hfc_emission_factor
86
- end.sum / latest_type_fuel_years.sum('total_travel')
87
- end
88
-
89
94
  CODES = {
90
95
  :electricity => 'El',
91
96
  :diesel => 'D'
@@ -8,6 +8,18 @@ AutomobileFuel.class_eval do
8
8
  float 'blend_portion' # the portion of the blend that is the blend fuel
9
9
  string 'distance_key' # used to look up annual distance from AutomobileTypeFuelYear
10
10
  string 'ef_key' # used to look up ch4 n2o and hfc emission factors from AutomobileTypeFuelYear
11
+ float 'annual_distance'
12
+ string 'annual_distance_units'
13
+ float 'co2_emission_factor'
14
+ string 'co2_emission_factor_units'
15
+ float 'co2_biogenic_emission_factor'
16
+ string 'co2_biogenic_emission_factor_units'
17
+ float 'ch4_emission_factor'
18
+ string 'ch4_emission_factor_units'
19
+ float 'n2o_emission_factor'
20
+ string 'n2o_emission_factor_units'
21
+ float 'hfc_emission_factor'
22
+ string 'hfc_emission_factor_units'
11
23
  end
12
24
 
13
25
  import "a list of pure automobile fuels",
@@ -30,6 +42,60 @@ AutomobileFuel.class_eval do
30
42
  store 'ef_key'
31
43
  end
32
44
 
45
+ process "Ensure necessary datasets are imported" do
46
+ AutomobileTypeFuelYearAge.run_data_miner!
47
+ AutomobileTypeYear.run_data_miner!
48
+ Fuel.run_data_miner!
49
+ GreenhouseGas.run_data_miner!
50
+ end
51
+
52
+ process "Derive annual distance" do
53
+ AutomobileFuel.all.each do |record|
54
+ scope = record.type_fuel_year_ages.where(:year => record.type_fuel_year_ages.maximum('year'))
55
+ record.annual_distance = scope.weighted_average(:annual_distance, :weighted_by => :vehicles)
56
+ record.annual_distance_units = scope.first.annual_distance_units
57
+ record.save
58
+ end
59
+ end
60
+
61
+ process "Derive co2 emission factor and co2 biogenic emission factors" do
62
+ AutomobileFuel.all.each do |record|
63
+ if record.blend_fuel.present?
64
+ record.co2_emission_factor = (record.base_fuel.co2_emission_factor * (1 - record.blend_portion)) + (record.blend_fuel.co2_emission_factor * record.blend_portion)
65
+ record.co2_biogenic_emission_factor = (record.base_fuel.co2_biogenic_emission_factor * (1 - record.blend_portion)) + (record.blend_fuel.co2_biogenic_emission_factor * record.blend_portion)
66
+ else
67
+ record.co2_emission_factor = record.base_fuel.co2_emission_factor
68
+ record.co2_biogenic_emission_factor = record.base_fuel.co2_biogenic_emission_factor
69
+ end
70
+ record.co2_emission_factor_units = record.base_fuel.co2_emission_factor_units
71
+ record.co2_biogenic_emission_factor_units = record.base_fuel.co2_biogenic_emission_factor_units
72
+ record.save
73
+ end
74
+ end
75
+
76
+ process "Derive ch4, n2o, and hfc emission factors" do
77
+ AutomobileFuel.all.each do |record|
78
+ scope = record.type_fuel_years.where(:year => record.type_fuel_years.maximum('year'))
79
+
80
+ record.ch4_emission_factor = scope.weighted_average(:ch4_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:ch4].global_warming_potential
81
+ ch4_prefix = scope.first.ch4_emission_factor_units.split("_per_")[0]
82
+ ch4_suffix = scope.first.ch4_emission_factor_units.split("_per_")[1]
83
+ record.ch4_emission_factor_units = ch4_prefix + "_co2e_per_" + ch4_suffix
84
+
85
+ record.n2o_emission_factor = scope.weighted_average(:n2o_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:n2o].global_warming_potential
86
+ n2o_prefix = scope.first.n2o_emission_factor_units.split("_per_")[0]
87
+ n2o_suffix = scope.first.n2o_emission_factor_units.split("_per_")[1]
88
+ record.n2o_emission_factor_units = n2o_prefix + "_co2e_per_" + n2o_suffix
89
+
90
+ record.hfc_emission_factor = scope.map do |tfy|
91
+ tfy.total_travel * tfy.type_year.hfc_emission_factor
92
+ end.sum / scope.sum('total_travel')
93
+ record.hfc_emission_factor_units = scope.first.type_year.hfc_emission_factor_units
94
+
95
+ record.save
96
+ end
97
+ end
98
+
33
99
  # FIXME TODO verify code somehow
34
100
 
35
101
  %w{ base_fuel_name distance_key ef_key }.each do |attribute|
@@ -37,6 +103,7 @@ AutomobileFuel.class_eval do
37
103
  AutomobileFuel.all.each do |fuel|
38
104
  value = fuel.send(:"#{attribute}")
39
105
  unless value.present?
106
+ puts "Missing #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}"
40
107
  raise "Missing #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}"
41
108
  end
42
109
  end
@@ -51,10 +118,53 @@ AutomobileFuel.class_eval do
51
118
  AutomobileFuel.all.each do |fuel|
52
119
  if fuel.blend_portion.present?
53
120
  unless fuel.blend_portion >=0 and fuel.blend_portion <= 1
121
+ puts "Invalid blend portion for AutomobileFuel #{fuel.name}: #{fuel.blend_portion} (should be from 0 to 1)"
54
122
  raise "Invalid blend portion for AutomobileFuel #{fuel.name}: #{fuel.blend_portion} (should be from 0 to 1)"
55
123
  end
56
124
  end
57
125
  end
58
126
  end
127
+
128
+ ["co2_emission_factor", "co2_biogenic_emission_factor"].each do |attribute|
129
+ verify "#{attribute.humanize} should be 0 or more" do
130
+ AutomobileFuel.all.each do |fuel|
131
+ value = fuel.send(attribute)
132
+ unless value >= 0
133
+ puts "Invalid #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}: #{value} (should be 0 or more)"
134
+ raise "Invalid #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}: #{value} (should be 0 or more)"
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ ["ch4_emission_factor", "n2o_emission_factor", "hfc_emission_factor"].each do |attribute|
141
+ verify "#{attribute.humanize} should be > 0" do
142
+ AutomobileFuel.all.each do |fuel|
143
+ value = fuel.send(attribute)
144
+ unless value > 0
145
+ puts "Invalid #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}: #{value} (should be > 0)"
146
+ raise "Invalid #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}: #{value} (should be > 0)"
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ [["co2_emission_factor_units", "kilograms_per_litre"],
153
+ ["co2_biogenic_emission_factor_units", "kilograms_per_litre"],
154
+ ["ch4_emission_factor_units", "kilograms_co2e_per_litre"],
155
+ ["n2o_emission_factor_units", "kilograms_co2e_per_litre"],
156
+ ["hfc_emission_factor_units", "kilograms_co2e_per_litre"]].each do |pair|
157
+ attribute = pair[0]
158
+ proper_units = pair[1]
159
+ verify "#{attribute.humanize} should be #{proper_units.humanize.downcase}" do
160
+ AutomobileFuel.all.each do |fuel|
161
+ units = fuel.send(attribute)
162
+ unless units == proper_units
163
+ puts "Invalid #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}: #{units} (should be #{proper_units})"
164
+ fail
165
+ end
166
+ end
167
+ end
168
+ end
59
169
  end
60
170
  end
data/lib/earth/bus.rb CHANGED
@@ -1 +1,4 @@
1
1
  require 'earth/bus/bus_class'
2
+ require 'earth/bus/bus_fuel'
3
+ require 'earth/bus/bus_fuel_control'
4
+ require 'earth/bus/bus_fuel_year_control'
@@ -4,10 +4,29 @@ class BusClass < ActiveRecord::Base
4
4
  # https://spreadsheets.google.com/pub?key=0AoQJbWqPrREqdHY0R0hjZnhRaTIxTnpvRk1HNThwUmc&hl=en&output=html
5
5
  falls_back_on :passengers => 7.485,
6
6
  :distance => 4.9726.miles.to(:kilometres),
7
+ :distance_units => 'kilometres',
7
8
  :speed => 19.849.miles.to(:kilometres),
9
+ :speed_units => 'kilometres_per_hour',
10
+ :gasoline_intensity => 0.00064134.gallons_per_mile.to(:litres_per_kilometre),
11
+ :gasoline_intensity_units => 'litres_per_kilometre',
8
12
  :diesel_intensity => 0.13836.gallons_per_mile.to(:litres_per_kilometre),
9
- :alternative_fuels_intensity => 0.04632038.gallons_per_mile.to(:litres_per_kilometre),
10
- :air_conditioning_emission_factor => 0.04779 / 1.miles.to(:kilometres)
13
+ :diesel_intensity_units => 'litres_per_kilometre',
14
+ :cng_intensity => 0.03175.gallons_per_mile.to(:litres_per_kilometre),
15
+ :cng_intensity_units => 'litres_per_kilometre',
16
+ :lng_intensity => 0.00419.gallons_per_mile.to(:litres_per_kilometre),
17
+ :lng_intensity_units => 'litres_per_kilometre',
18
+ :lpg_intensity => 0.00037.gallons_per_mile.to(:litres_per_kilometre),
19
+ :lpg_intensity_units => 'litres_per_kilometre',
20
+ :methanol_intensity => 0.00021.gallons_per_mile.to(:litres_per_kilometre),
21
+ :methanol_intensity_units => 'litres_per_kilometre',
22
+ :biodiesel_intensity => 0.00979.gallons_per_mile.to(:litres_per_kilometre),
23
+ :biodiesel_intensity_units => 'litres_per_kilometre',
24
+ :electricity_intensity => 0.00001804 / 1.miles.to(:kilometres),
25
+ :electricity_intensity_units => 'kilowatt_hours_per_kilometre',
26
+ :air_conditioning_emission_factor => 0.04779 / 1.miles.to(:kilometres),
27
+ :air_conditioning_emission_factor_units => 'kilograms_co2e_per_kilometre',
28
+ :alternative_fuels_intensity => 0.04632038.gallons_per_mile.to(:litres_per_kilometre), # deprecated
29
+ :alternative_fuels_intensity_units => 'litres_per_kilometre' # deprecated
11
30
 
12
31
  data_miner do
13
32
  tap "Brighter Planet's sanitized bus class data", Earth.taps_server
@@ -7,94 +7,130 @@ BusClass.class_eval do
7
7
  float 'passengers'
8
8
  float 'speed'
9
9
  string 'speed_units'
10
+ float 'gasoline_intensity'
11
+ string 'gasoline_intensity_units'
10
12
  float 'diesel_intensity'
11
13
  string 'diesel_intensity_units'
12
- float 'alternative_fuels_intensity'
13
- string 'alternative_fuels_intensity_units'
14
+ float 'cng_intensity'
15
+ string 'cng_intensity_units'
16
+ float 'lng_intensity'
17
+ string 'lng_intensity_units'
18
+ float 'lpg_intensity'
19
+ string 'lpg_intensity_units'
20
+ float 'methanol_intensity'
21
+ string 'methanol_intensity_units'
22
+ float 'biodiesel_intensity'
23
+ string 'biodiesel_intensity_units'
24
+ float 'electricity_intensity'
25
+ string 'electricity_intensity_units'
14
26
  float 'air_conditioning_emission_factor'
15
27
  string 'air_conditioning_emission_factor_units'
28
+ float 'alternative_fuels_intensity'
29
+ string 'alternative_fuels_intensity_units'
16
30
  end
17
31
 
18
32
  import "a list of bus classes and pre-calculated trip and fuel use characteristics",
19
- :url => 'https://spreadsheets.google.com/pub?key=0AoQJbWqPrREqdGRsSnJoS1hraGJvR012cDROWXFPbVE&hl=en&single=true&gid=0&output=csv' do
33
+ :url => 'https://spreadsheets.google.com/pub?hl=en&hl=en&key=0AoQJbWqPrREqdGRsSnJoS1hraGJvR012cDROWXFPbVE&output=csv' do
20
34
  key 'name'
21
35
  store 'distance', :units_field_name => 'distance_units'
22
36
  store 'passengers'
23
37
  store 'speed', :units_field_name => 'speed_units'
38
+ store 'gasoline_intensity', :units_field_name => 'gasoline_intensity_units'
24
39
  store 'diesel_intensity', :units_field_name => 'diesel_intensity_units'
25
- store 'alternative_fuels_intensity', :units_field_name => 'alternative_fuels_intensity_units'
40
+ store 'cng_intensity', :units_field_name => 'cng_intensity_units'
41
+ store 'lng_intensity', :units_field_name => 'lng_intensity_units'
42
+ store 'lpg_intensity', :units_field_name => 'lpg_intensity_units'
43
+ store 'methanol_intensity', :units_field_name => 'methanol_intensity_units'
44
+ store 'biodiesel_intensity', :units_field_name => 'biodiesel_intensity_units'
45
+ store 'electricity_intensity', :units_field_name => 'electricity_intensity_units'
26
46
  store 'air_conditioning_emission_factor', :units_field_name => 'air_conditioning_emission_factor_units'
47
+ store 'alternative_fuels_intensity', :units_field_name => 'alternative_fuels_intensity_units'
27
48
  end
28
49
 
29
- verify "Distance, passengers, speed, and diesel intensity should be greater than zero" do
50
+ verify "Some attributes should be greater than zero" do
30
51
  BusClass.all.each do |bus_class|
31
- %w{ distance passengers speed diesel_intensity }.each do |attribute|
52
+ %w{ distance passengers speed diesel_intensity air_conditioning_emission_factor }.each do |attribute|
32
53
  value = bus_class.send(:"#{attribute}")
33
54
  unless value > 0
34
- raise "Invalid #{attribute} for BusClass #{bus_class.name}: #{value} (should be > 0)"
55
+ puts "Invalid #{attribute.humanize.downcase} for BusClass #{bus_class.name}: #{value} (should be > 0)"
56
+ fail
35
57
  end
36
58
  end
37
59
  end
38
60
  end
39
61
 
40
- verify "Alternative fuels intensity and air conditioning emission factor should be zero or more" do
62
+ verify "Some attributes should be zero or more" do
41
63
  BusClass.all.each do |bus_class|
42
- %w{ alternative_fuels_intensity air_conditioning_emission_factor }.each do |attribute|
64
+ %w{ gasoline_intensity cng_intensity lng_intensity lpg_intensity methanol_intensity biodiesel_intensity electricity_intensity alternative_fuels_intensity }.each do |attribute|
43
65
  value = bus_class.send(:"#{attribute}")
44
66
  unless value >= 0
45
- raise "Invalid #{attribute} for BusClass #{bus_class.name}: #{value} (should be >= 0)"
67
+ puts "Invalid #{attribute.humanize.downcase} for BusClass #{bus_class.name}: #{value} (should be >= 0)"
68
+ fail
46
69
  end
47
70
  end
48
71
  end
49
72
  end
50
73
 
51
- verify "Distance units should be kilometres" do
52
- BusClass.all.each do |bus_class|
53
- unless bus_class.distance_units == "kilometres"
54
- raise "Invalid distance units for BusClass #{bus_class.name}: #{bus_class.distance_units} (should be kilometres)"
55
- end
56
- end
57
- end
58
-
59
- verify "Speed units should be kilometres per hour" do
60
- BusClass.all.each do |bus_class|
61
- unless bus_class.speed_units == "kilometres_per_hour"
62
- raise "Invalid speed units for BusClass #{bus_class.name}: #{bus_class.speed_units} (should be kilometres_per_hour)"
63
- end
64
- end
65
- end
66
-
67
- verify "Diesel intensity and alternative fuel intensity units should be litres per kilometre" do
74
+ verify "Units should be correct" do
68
75
  BusClass.all.each do |bus_class|
69
- %w{ diesel_intensity alternative_fuels_intensity }.each do |attribute|
70
- units = bus_class.send(:"#{attribute}_units")
71
- unless units == "litres_per_kilometre"
72
- raise "Invalid #{attribute}_units for BusClass #{bus_class.name}: #{units} (should be litres_per_kilometre)"
76
+ [["distance_units", "kilometres"],
77
+ ["speed_units", "kilometres_per_hour"],
78
+ ["diesel_intensity_units", "litres_per_kilometre"],
79
+ ["gasoline_intensity_units", "litres_per_kilometre"],
80
+ ["cng_intensity_units", "litres_per_kilometre"],
81
+ ["lng_intensity_units", "litres_per_kilometre"],
82
+ ["lpg_intensity_units", "litres_per_kilometre"],
83
+ ["methanol_intensity_units", "litres_per_kilometre"],
84
+ ["biodiesel_intensity_units", "litres_per_kilometre"],
85
+ ["electricity_intensity_units", "kilowatt_hours_per_kilometre"],
86
+ ["air_conditioning_emission_factor_units", "kilograms_co2e_per_kilometre"],
87
+ ["alternative_fuels_intensity_units", "litres_per_kilometre"]].each do |pair|
88
+ attribute = pair[0]
89
+ proper_units = pair[1]
90
+ units = bus_class.send(:"#{attribute}")
91
+ unless units == proper_units
92
+ puts "Invalid #{attribute.humanize.downcase} for BusClass #{bus_class.name}: #{units} (should be #{proper_units})"
93
+ fail
73
94
  end
74
95
  end
75
96
  end
76
97
  end
77
98
 
78
- verify "Air conditioning emission factor units should be kilograms per kilometre" do
79
- BusClass.all.each do |bus_class|
80
- unless bus_class.air_conditioning_emission_factor_units == "kilograms_per_kilometre"
81
- raise "Invalid air conditioning emission factor units for BusClass #{bus_class.name}: #{bus_class.air_conditioning_emission_factor_units} (should be kilograms_per_kilometre)"
82
- end
83
- end
84
- end
85
-
86
99
  verify "Fallbacks should satisfy same constraints as data" do
87
- %w{ distance passengers speed diesel_intensity }.each do |attribute|
100
+ %w{ distance passengers speed diesel_intensity air_conditioning_emission_factor }.each do |attribute|
88
101
  value = BusClass.fallback.send(:"#{attribute}")
89
102
  unless value > 0
90
- raise "Invalid BusClass fallback #{attribute}: #{value} (should be > 0)"
103
+ puts "Invalid #{attribute.humanize.downcase} for fallback BusClass: #{value} (should be > 0)"
104
+ fail
91
105
  end
92
106
  end
93
107
 
94
- %w{ alternative_fuels_intensity air_conditioning_emission_factor }.each do |attribute|
108
+ %w{ gasoline_intensity cng_intensity lng_intensity lpg_intensity methanol_intensity biodiesel_intensity electricity_intensity alternative_fuels_intensity }.each do |attribute|
95
109
  value = BusClass.fallback.send(:"#{attribute}")
96
110
  unless value >= 0
97
- raise "Invalid BusClass fallback #{attribute}: #{value} (should be >= 0)"
111
+ puts "Invalid #{attribute.humanize.downcase} for fallback BusClass: #{value} (should be >= 0)"
112
+ fail
113
+ end
114
+ end
115
+
116
+ [["distance_units", "kilometres"],
117
+ ["speed_units", "kilometres_per_hour"],
118
+ ["diesel_intensity_units", "litres_per_kilometre"],
119
+ ["gasoline_intensity_units", "litres_per_kilometre"],
120
+ ["cng_intensity_units", "litres_per_kilometre"],
121
+ ["lng_intensity_units", "litres_per_kilometre"],
122
+ ["lpg_intensity_units", "litres_per_kilometre"],
123
+ ["methanol_intensity_units", "litres_per_kilometre"],
124
+ ["biodiesel_intensity_units", "litres_per_kilometre"],
125
+ ["electricity_intensity_units", "kilowatt_hours_per_kilometre"],
126
+ ["air_conditioning_emission_factor_units", "kilograms_co2e_per_kilometre"],
127
+ ["alternative_fuels_intensity_units", "litres_per_kilometre"]].each do |pair|
128
+ attribute = pair[0]
129
+ proper_units = pair[1]
130
+ units = BusClass.fallback.send(:"#{attribute}")
131
+ unless units == proper_units
132
+ puts "Invalid #{attribute.humanize.downcase} for fallback BusClass: #{units} (should be #{proper_units})"
133
+ fail
98
134
  end
99
135
  end
100
136
  end