earth 0.12.3 → 0.12.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/Gemfile +1 -0
  2. data/TODO +1 -0
  3. data/bin/earth_tester.rb +39 -47
  4. data/data/air/airlines.csv +45 -0
  5. data/data/air/airports.csv +11 -0
  6. data/data/hospitality/lodging_classes.csv +4 -0
  7. data/data/locality/national_electricity_efs.csv +137 -0
  8. data/earth.gemspec +1 -1
  9. data/errata/airline/bts_carrier_codes_errata.csv +2 -0
  10. data/lib/earth.rb +3 -0
  11. data/lib/earth/active_record_base_class_methods.rb +25 -0
  12. data/lib/earth/air/aircraft.rb +5 -4
  13. data/lib/earth/air/airline.rb +5 -1
  14. data/lib/earth/air/airline/data_miner.rb +1 -1
  15. data/lib/earth/air/airport.rb +10 -2
  16. data/lib/earth/air/airport/data_miner.rb +11 -5
  17. data/lib/earth/air/bts_aircraft.rb +1 -1
  18. data/lib/earth/air/flight_segment.rb +14 -1
  19. data/lib/earth/air/flight_segment/data_miner.rb +6 -13
  20. data/lib/earth/automobile/automobile_activity_year/data_miner.rb +1 -1
  21. data/lib/earth/automobile/automobile_activity_year_type/data_miner.rb +1 -1
  22. data/lib/earth/automobile/automobile_fuel/data_miner.rb +5 -5
  23. data/lib/earth/automobile/automobile_make/data_miner.rb +1 -1
  24. data/lib/earth/automobile/automobile_make_model/data_miner.rb +1 -1
  25. data/lib/earth/automobile/automobile_make_model_year/data_miner.rb +1 -1
  26. data/lib/earth/automobile/automobile_make_model_year_variant/data_miner.rb +6 -6
  27. data/lib/earth/automobile/automobile_type_fuel/data_miner.rb +2 -2
  28. data/lib/earth/automobile/automobile_type_fuel_year/data_miner.rb +1 -1
  29. data/lib/earth/conversions_ext.rb +7 -6
  30. data/lib/earth/fuel/fuel.rb +1 -1
  31. data/lib/earth/fuel/fuel/data_miner.rb +1 -3
  32. data/lib/earth/hospitality/commercial_building_energy_consumption_survey_response.rb +3 -1
  33. data/lib/earth/hospitality/commercial_building_energy_consumption_survey_response/data_miner.rb +44 -11
  34. data/lib/earth/hospitality/lodging_class.rb +0 -1
  35. data/lib/earth/hospitality/lodging_class/data_miner.rb +3 -9
  36. data/lib/earth/industry/merchant_category/data_miner.rb +14 -0
  37. data/lib/earth/locality/country.rb +33 -7
  38. data/lib/earth/locality/country/data_miner.rb +46 -32
  39. data/lib/earth/locality/egrid_subregion.rb +1 -1
  40. data/lib/earth/locality/egrid_subregion/data_miner.rb +16 -31
  41. data/lib/earth/locality/electricity_mix.rb +37 -0
  42. data/lib/earth/locality/electricity_mix/data_miner.rb +87 -0
  43. data/lib/earth/locality/state.rb +12 -4
  44. data/lib/earth/locality/state/data_miner.rb +33 -18
  45. data/lib/earth/locality/zip_code.rb +9 -1
  46. data/lib/earth/locality/zip_code/data_miner.rb +4 -0
  47. data/lib/earth/rail/country_rail_traction/data_miner.rb +2 -2
  48. data/lib/earth/rail/country_rail_traction_class/data_miner.rb +2 -2
  49. data/lib/earth/rail/national_transit_database_record.rb +4 -0
  50. data/lib/earth/rail/rail_company/data_miner.rb +3 -3
  51. data/lib/earth/rail/rail_fuel/data_miner.rb +1 -1
  52. data/lib/earth/residence/clothes_machine_use/data_miner.rb +1 -1
  53. data/lib/earth/residence/dishwasher_use/data_miner.rb +1 -1
  54. data/lib/earth/residence/residence_fuel_price.rb +1 -1
  55. data/lib/earth/version.rb +1 -1
  56. data/spec/earth/air/airline_spec.rb +1 -1
  57. data/spec/earth/air/airport_spec.rb +7 -0
  58. data/spec/earth/air/flight_segment_spec.rb +26 -12
  59. data/spec/earth/automobile/automobile_type_fuel_spec.rb +1 -1
  60. data/spec/earth/automobile/automobile_type_fuel_year_spec.rb +3 -3
  61. data/spec/earth/fuel/fuel_spec.rb +1 -1
  62. data/spec/earth/hospitality/commercial_building_energy_consumption_survey_response_spec.rb +32 -19
  63. data/spec/earth/hospitality/lodging_class_spec.rb +18 -0
  64. data/spec/earth/industry/mecs_energy_spec.rb +2 -2
  65. data/spec/earth/industry/mecs_ratio_spec.rb +1 -1
  66. data/spec/earth/industry/merchant_category_spec.rb +17 -0
  67. data/spec/earth/locality/country_spec.rb +32 -16
  68. data/spec/earth/locality/egrid_subregion_spec.rb +40 -27
  69. data/spec/earth/locality/electricity_mix_spec.rb +70 -0
  70. data/spec/earth/locality/state_spec.rb +10 -11
  71. data/spec/earth/locality/zip_code_spec.rb +9 -5
  72. data/spec/earth_spec.rb +4 -4
  73. data/spec/spec_helper.rb +3 -0
  74. metadata +19 -10
  75. data/lib/earth/hospitality/country_lodging_class.rb +0 -18
  76. data/lib/earth/hospitality/country_lodging_class/data_miner.rb +0 -40
  77. data/lib/earth/industry/merchant.rb +0 -9
  78. data/spec/earth/hospitality/country_lodging_class_spec.rb +0 -30
@@ -1,4 +1,3 @@
1
- require 'earth/locality'
2
1
  class LodgingClass < ActiveRecord::Base
3
2
  self.primary_key = "name"
4
3
 
@@ -1,14 +1,8 @@
1
- require 'earth/locality/data_miner'
2
1
  LodgingClass.class_eval do
3
2
  data_miner do
4
- process "Ensure CountryLodgingClass is populated" do
5
- CountryLodgingClass.run_data_miner!
6
- end
7
-
8
- process "Derive lodging classes from CountryLodgingClass" do
9
- connection.select_values("SELECT DISTINCT lodging_class_name FROM #{CountryLodgingClass.quoted_table_name}").each do |lodging_class_name|
10
- find_or_create_by_name lodging_class_name
11
- end
3
+ import "A Brighter Planet-curated list of lodging classes",
4
+ :url => "file://#{Earth::DATA_DIR}/hospitality/lodging_classes.csv" do
5
+ key :name
12
6
  end
13
7
  end
14
8
  end
@@ -0,0 +1,14 @@
1
+ MerchantCategory.data_miner do
2
+ process "Start from scratch" do
3
+ delete_all
4
+ end
5
+
6
+ import "the IRS Merchant Category Code table",
7
+ :url => 'http://www.irs.gov/irb/2004-31_IRB/ar17.html',
8
+ :headers => %w{mcc description ignore},
9
+ :row_css => 'div.informaltable tbody tr',
10
+ :column_css => 'td' do
11
+ key 'mcc'
12
+ store 'description'
13
+ end
14
+ end
@@ -1,5 +1,4 @@
1
1
  require 'earth/automobile'
2
- require 'earth/fuel'
3
2
  require 'earth/hospitality'
4
3
  require 'earth/rail'
5
4
 
@@ -7,7 +6,17 @@ class Country < ActiveRecord::Base
7
6
  self.primary_key = "iso_3166_code"
8
7
 
9
8
  has_many :rail_companies, :foreign_key => 'country_iso_3166_code' # used to calculate rail data
10
- has_many :lodging_classes, :foreign_key => 'country_iso_3166_code', :class_name => 'CountryLodgingClass'
9
+ has_one :electricity_mix, :foreign_key => 'country_iso_3166_code'
10
+
11
+ data_miner do
12
+ process "Ensure ElectricityMix is imported because it's like a belongs_to association" do
13
+ ElectricityMix.run_data_miner!
14
+ end
15
+ end
16
+
17
+ def self.united_states
18
+ find_by_iso_3166_code('US')
19
+ end
11
20
 
12
21
  falls_back_on :name => 'fallback',
13
22
  :automobile_urbanity => lambda { united_states.automobile_urbanity }, # for now assume US represents world
@@ -19,8 +28,15 @@ class Country < ActiveRecord::Base
19
28
  :automobile_highway_speed_units => lambda { united_states.automobile_highway_speed_units }, # for now assume US represents world
20
29
  :automobile_trip_distance => lambda { united_states.automobile_trip_distance }, # for now assume US represents world
21
30
  :automobile_trip_distance_units => lambda { united_states.automobile_trip_distance_units }, # for now assume US represents world
31
+ :electricity_mix => lambda { ElectricityMix.fallback },
22
32
  :electricity_emission_factor => 0.626089, # from ecometrica paper - FIXME TODO calculate this
23
33
  :electricity_emission_factor_units => 'kilograms_co2e_per_kilowatt_hour', # FIXME TODO derive this
34
+ :electricity_co2_emission_factor => 0.623537, # from ecometrica paper - FIXME TODO calculate this
35
+ :electricity_co2_emission_factor_units => 'kilograms_per_kilowatt_hour', # FIXME TODO derive this
36
+ :electricity_ch4_emission_factor => 0.000208, # from ecometrica paper - FIXME TODO calculate this
37
+ :electricity_ch4_emission_factor_units => 'kilograms_co2e_per_kilowatt_hour', # FIXME TODO derive this
38
+ :electricity_n2o_emission_factor => 0.002344, # from ecometrica paper - FIXME TODO calculate this
39
+ :electricity_n2o_emission_factor_units => 'kilograms_co2e_per_kilowatt_hour', # FIXME TODO derive this
24
40
  :electricity_loss_factor => 0.096, # from ecometrica paper - FIXME TODO calculate this
25
41
  :flight_route_inefficiency_factor => lambda { maximum(:flight_route_inefficiency_factor) }, # default to the largest inefficiency factor
26
42
  :lodging_occupancy_rate => lambda { united_states.lodging_occupancy_rate }, # for now assume US represents world
@@ -43,10 +59,6 @@ class Country < ActiveRecord::Base
43
59
  :rail_trip_co2_emission_factor => lambda { weighted_average(:rail_trip_co2_emission_factor, :weighted_by => :rail_passengers) },
44
60
  :rail_trip_co2_emission_factor_units => 'kilograms_per_passenger_kilometre' # FIXME TODO derive this
45
61
 
46
- def self.united_states
47
- find_by_iso_3166_code('US')
48
- end
49
-
50
62
  col :iso_3166_code # alpha-2 2-letter like GB
51
63
  col :iso_3166_numeric_code, :type => :integer # numeric like 826; aka UN M49 code
52
64
  col :iso_3166_alpha_3_code # 3-letter like GBR
@@ -66,6 +78,12 @@ class Country < ActiveRecord::Base
66
78
  col :automobile_trip_distance_units
67
79
  col :electricity_emission_factor, :type => :float
68
80
  col :electricity_emission_factor_units
81
+ col :electricity_co2_emission_factor, :type => :float
82
+ col :electricity_co2_emission_factor_units
83
+ col :electricity_ch4_emission_factor, :type => :float
84
+ col :electricity_ch4_emission_factor_units
85
+ col :electricity_n2o_emission_factor, :type => :float
86
+ col :electricity_n2o_emission_factor_units
69
87
  col :electricity_loss_factor, :type => :float
70
88
  col :flight_route_inefficiency_factor, :type => :float
71
89
  col :lodging_occupancy_rate, :type => :float
@@ -90,5 +108,13 @@ class Country < ActiveRecord::Base
90
108
  col :rail_trip_co2_emission_factor_units
91
109
 
92
110
  warn_unless_size 249
93
- warn_if_nulls_except /heating/, /cooling/
111
+ warn_if_nulls_except(
112
+ /heating/,
113
+ /cooling/,
114
+ /automobile/,
115
+ /electricity/,
116
+ /flight/,
117
+ /lodging/,
118
+ /rail/
119
+ )
94
120
  end
@@ -5,6 +5,10 @@ require 'earth/rail/data_miner'
5
5
 
6
6
  Country.class_eval do
7
7
  data_miner do
8
+ process "Start from scratch" do
9
+ delete_all
10
+ end
11
+
8
12
  # http://www.iso.org/iso/list-en1-semic-3.txt
9
13
  # http://unstats.un.org/unsd/methods/m49/m49alpha.htm
10
14
  import "OpenGeoCode.org's Country Codes to Country Names list",
@@ -61,36 +65,48 @@ Country.class_eval do
61
65
  )
62
66
  end
63
67
 
68
+ # DEPRECATED - eventually cut all elec stuff (replaced by ElectricityMix)
64
69
  # ELECTRICITY
65
70
  process "Ensure GreehouseGas is populated" do
66
71
  GreenhouseGas.run_data_miner!
67
72
  end
68
73
 
69
- import "calculate national electricity emission factors from Brander et al. (2011)",
70
- :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdDZmWHFjLVdBZGRBdGxVdDdqd1YtYWc&output=csv' do
74
+ import "national average electricity emission factors from Brander et al. (2011)",
75
+ :url => "file://#{Earth::DATA_DIR}/locality/national_electricity_efs.csv" do
71
76
  key 'iso_3166_code', :field_name => 'country_iso_3166_code'
72
- store 'electricity_emission_factor', :synthesize => proc { |row|
73
- (
74
- row['electricity_co2_emission_factor'].to_f +
75
- (row['electricity_ch4_emission_factor'].to_f * GreenhouseGas[:ch4].global_warming_potential) +
76
- (row['electricity_n2o_emission_factor'].to_f * GreenhouseGas[:n2o].global_warming_potential)
77
- ) }, :units => 'kilograms_co2e_per_kilowatt_hour'
77
+ store 'electricity_co2_emission_factor', :field_name => 'co2_emission_factor', :units_field_name => 'co2_emission_factor_units'
78
+ store 'electricity_ch4_emission_factor', :synthesize => proc { |row| row['ch4_emission_factor'].to_f * GreenhouseGas[:ch4].global_warming_potential }, :units => 'kilograms_co2e_per_kilowatt_hour'
79
+ store 'electricity_n2o_emission_factor', :synthesize => proc { |row| row['n2o_emission_factor'].to_f * GreenhouseGas[:n2o].global_warming_potential }, :units => 'kilograms_co2e_per_kilowatt_hour'
78
80
  store 'electricity_loss_factor', :field_name => 'loss_factor'
79
81
  end
80
82
 
81
- process "Ensure EgridSubregion and EgridRegion are populated" do
83
+ process "Ensure EgridSubregion is populated" do
82
84
  EgridSubregion.run_data_miner!
83
- EgridRegion.run_data_miner!
84
85
  end
85
86
 
86
- process "Derive average US electricity emission factor and loss factor from eGRID" do
87
+ process "Derive average US electricity data from EgridSubregion" do
87
88
  united_states.update_attributes!(
88
- :electricity_emission_factor => EgridSubregion.fallback.electricity_emission_factor,
89
- :electricity_emission_factor_units => EgridSubregion.fallback.electricity_emission_factor_units,
90
- :electricity_loss_factor => EgridRegion.fallback.loss_factor
89
+ :electricity_co2_emission_factor => EgridSubregion.fallback.co2_emission_factor,
90
+ :electricity_co2_emission_factor_units => EgridSubregion.fallback.co2_emission_factor_units,
91
+ :electricity_ch4_emission_factor => EgridSubregion.fallback.ch4_emission_factor,
92
+ :electricity_ch4_emission_factor_units => EgridSubregion.fallback.ch4_emission_factor_units,
93
+ :electricity_n2o_emission_factor => EgridSubregion.fallback.n2o_emission_factor,
94
+ :electricity_n2o_emission_factor_units => EgridSubregion.fallback.n2o_emission_factor_units,
95
+ :electricity_loss_factor => EgridSubregion.fallback.egrid_region.loss_factor
91
96
  )
92
97
  end
93
98
 
99
+ process "Calculate combined electricity emission factor" do
100
+ where('electricity_co2_emission_factor IS NOT NULL').update_all(%{
101
+ electricity_emission_factor = electricity_co2_emission_factor + electricity_ch4_emission_factor + electricity_n2o_emission_factor,
102
+ electricity_emission_factor_units = 'kilograms_co2e_per_kilowatt_hour'
103
+ })
104
+ end
105
+
106
+ process "Ensure ElectricityMix is data mined because it's like a belongs_to association" do
107
+ ElectricityMix.run_data_miner!
108
+ end
109
+
94
110
  # FLIGHT
95
111
  import "country-specific flight route inefficiency factors derived from Kettunen et al. (2005)",
96
112
  :url => "file://#{Earth::DATA_DIR}/locality/country_flight_data.csv" do
@@ -103,25 +119,23 @@ Country.class_eval do
103
119
  united_states.update_attributes! :lodging_occupancy_rate => 0.601 # per http://www.pwc.com/us/en/press-releases/2012/pwc-us-lodging-industry-forecast.jhtml
104
120
  end
105
121
 
106
- process "Ensure CountryLodgingClass is populated" do
107
- CountryLodgingClass.run_data_miner!
122
+ process "Ensure CommercialBuildingEnergyConsumptionSurveyResponse is populated" do
123
+ CommercialBuildingEnergyConsumptionSurveyResponse.run_data_miner!
108
124
  end
109
125
 
110
- process "Derive average hotel characteristics from CountryLodgingClass" do
111
- find_each do |country|
112
- if (lodging_classes = country.lodging_classes).any?
113
- country.update_attributes!(
114
- :lodging_natural_gas_intensity => lodging_classes.weighted_average(:natural_gas_intensity),
115
- :lodging_fuel_oil_intensity => lodging_classes.weighted_average(:fuel_oil_intensity),
116
- :lodging_electricity_intensity => lodging_classes.weighted_average(:electricity_intensity),
117
- :lodging_district_heat_intensity => lodging_classes.weighted_average(:district_heat_intensity),
118
- :lodging_natural_gas_intensity_units => 'cubic_metres_per_occupied_room_night', # FIXME TODO derive this
119
- :lodging_fuel_oil_intensity_units => 'litres_per_occupied_room_night', # FIXME TODO derive this
120
- :lodging_electricity_intensity_units => 'kilowatt_hours_per_occupied_room_night', # FIXME TODO derive this
121
- :lodging_district_heat_intensity_units => 'megajoules_per_occupied_room_night' # FIXME TODO derive this
122
- )
123
- end
124
- end
126
+ process "Derive US average hotel characteristics from CommercialBuildingEnergyConsumptionSurveyResponse" do
127
+ lodgings = CommercialBuildingEnergyConsumptionSurveyResponse.lodging_records
128
+
129
+ united_states.update_attributes!(
130
+ :lodging_natural_gas_intensity => lodgings.weighted_average(:natural_gas_per_room_night),
131
+ :lodging_fuel_oil_intensity => lodgings.weighted_average(:fuel_oil_per_room_night),
132
+ :lodging_electricity_intensity => lodgings.weighted_average(:electricity_per_room_night),
133
+ :lodging_district_heat_intensity => lodgings.weighted_average(:district_heat_per_room_night),
134
+ :lodging_natural_gas_intensity_units => lodgings.first.natural_gas_per_room_night_units,
135
+ :lodging_fuel_oil_intensity_units => lodgings.first.fuel_oil_per_room_night_units,
136
+ :lodging_electricity_intensity_units => lodgings.first.electricity_per_room_night_units,
137
+ :lodging_district_heat_intensity_units => lodgings.first.district_heat_per_room_night_units
138
+ )
125
139
  end
126
140
 
127
141
  # RAIL
@@ -131,7 +145,7 @@ Country.class_eval do
131
145
  end
132
146
 
133
147
  process "Calculate rail passengers, trip distance, and speed from RailCompany" do
134
- find_each do |country|
148
+ safe_find_each do |country|
135
149
  if (rail_companies = country.rail_companies).any?
136
150
  country.update_attributes!(
137
151
  :rail_passengers => rail_companies.sum(:passengers),
@@ -3,8 +3,8 @@ require 'earth/locality/egrid_region'
3
3
  class EgridSubregion < ActiveRecord::Base
4
4
  self.primary_key = "abbreviation"
5
5
 
6
- has_many :zip_codes, :foreign_key => 'egrid_subregion_abbreviation'
7
6
  belongs_to :egrid_region, :foreign_key => 'egrid_region_name'
7
+ has_one :electricity_mix, :foreign_key => 'egrid_subregion_abbreviation'
8
8
 
9
9
  falls_back_on :name => 'fallback',
10
10
  :egrid_region => lambda { EgridRegion.fallback },
@@ -14,10 +14,9 @@ EgridSubregion.class_eval do
14
14
  store 'name', :field_name => 'SRNAME'
15
15
  store 'nerc_abbreviation', :field_name => 'NERC'
16
16
  store 'net_generation', :field_name => 'SRNGENAN', :units => :megawatt_hours
17
- store 'co2_emission_factor', :field_name => 'SRCO2RTA', :units => :pounds_per_megawatt_hour
18
- store 'co2_biogenic_emission_factor', :static => '0.0', :units => :kilograms_per_kilowatt_hour
19
- store 'ch4_emission_factor', :field_name => 'SRCH4RTA', :units => :pounds_per_gigawatt_hour
20
- store 'n2o_emission_factor', :field_name => 'SRN2ORTA', :units => :pounds_per_gigawatt_hour
17
+ store 'co2_emission_factor', :field_name => 'SRCO2RTA', :from_units => :pounds_per_megawatt_hour, :to_units => :kilograms_per_kilowatt_hour
18
+ store 'ch4_emission_factor', :field_name => 'SRCH4RTA', :from_units => :pounds_per_gigawatt_hour, :to_units => :kilograms_per_kilowatt_hour
19
+ store 'n2o_emission_factor', :field_name => 'SRN2ORTA', :from_units => :pounds_per_gigawatt_hour, :to_units => :kilograms_per_kilowatt_hour
21
20
  end
22
21
 
23
22
  import "eGRID subregion to region associations",
@@ -26,41 +25,27 @@ EgridSubregion.class_eval do
26
25
  store 'egrid_region_name'
27
26
  end
28
27
 
29
- process "Convert co2 emission factors to metric units" do
30
- conversion_factor = 1.pounds.to(:kilograms) / 1_000.0 # kg / lbs * MWh / kWh
31
- where(:co2_emission_factor_units => 'pounds_per_megawatt_hour').update_all(%{
32
- co2_emission_factor = co2_emission_factor * #{conversion_factor},
33
- co2_emission_factor_units = 'kilograms_per_kilowatt_hour'
34
- })
35
- end
36
-
37
28
  process "Insure GreenhouseGas is populated" do
38
29
  GreenhouseGas.run_data_miner!
39
30
  end
40
31
 
41
- process "Convert ch4 emission factor to metric units and co2e" do
42
- conversion_factor = 1.pounds.to(:kilograms) / 1_000_000.0 # kg / lbs * GWh / kWh
43
- gwp = GreenhouseGas[:ch4].global_warming_potential
44
- where(:ch4_emission_factor_units => 'pounds_per_gigawatt_hour').update_all(%{
45
- ch4_emission_factor = ch4_emission_factor * #{conversion_factor} * #{gwp},
46
- ch4_emission_factor_units = 'kilograms_co2e_per_kilowatt_hour'
47
- })
48
- end
49
-
50
- process "Convert n2o emission factor to metric units and co2e" do
51
- conversion_factor = 1.pounds.to(:kilograms) / 1_000_000.0 # kg / lbs * GWh / kWh
52
- gwp = GreenhouseGas[:n2o].global_warming_potential
53
- where(:n2o_emission_factor_units => 'pounds_per_gigawatt_hour').update_all(%{
54
- n2o_emission_factor = n2o_emission_factor * #{conversion_factor} * #{gwp},
55
- n2o_emission_factor_units = 'kilograms_co2e_per_kilowatt_hour'
56
- })
32
+ %w{ ch4 n2o }.each do |gas|
33
+ process "Convert #{gas} emission factors to co2e" do
34
+ gwp = GreenhouseGas[gas].global_warming_potential
35
+
36
+ where("#{gas}_emission_factor_units = 'kilograms_per_kilowatt_hour'").update_all(%{
37
+ #{gas}_emission_factor = #{gas}_emission_factor * #{gwp},
38
+ #{gas}_emission_factor_units = 'kilograms_co2e_per_kilowatt_hour'
39
+ })
40
+ end
57
41
  end
58
42
 
59
- process "Calculate combined emission factor" do
60
- update_all(%{
43
+ # DEPRECATED - but don't remove until cut State.electricity_emission_factor
44
+ process "Calculate combined electricity emission factor" do
45
+ update_all %{
61
46
  electricity_emission_factor = co2_emission_factor + ch4_emission_factor + n2o_emission_factor,
62
47
  electricity_emission_factor_units = 'kilograms_co2e_per_kilowatt_hour'
63
- })
48
+ }
64
49
  end
65
50
  end
66
51
  end
@@ -0,0 +1,37 @@
1
+ class ElectricityMix < ActiveRecord::Base
2
+ self.primary_key = :name
3
+
4
+ def energy_content
5
+ 1.kilowatt_hours.to(:megajoules)
6
+ end
7
+
8
+ def energy_content_units
9
+ 'megajoules_per_kilowatt_hour'
10
+ end
11
+
12
+ falls_back_on :name => 'fallback',
13
+ :co2_emission_factor => 0.623537, # from ecometrica paper FIXME TODO calculate this
14
+ :co2_emission_factor_units => 'kilograms_per_kilowatt_hour',
15
+ :ch4_emission_factor => 0.000208, # from ecometrica paper FIXME TODO calculate this
16
+ :ch4_emission_factor_units => 'kilograms_co2e_per_kilowatt_hour',
17
+ :n2o_emission_factor => 0.002344, # from ecometrica paper FIXME TODO calculate this
18
+ :n2o_emission_factor_units => 'kilograms_co2e_per_kilowatt_hour',
19
+ :loss_factor => 0.096 # from ecometrica paper FIXME TODO calculate this
20
+
21
+ col :name
22
+ col :egrid_subregion_abbreviation
23
+ col :state_postal_abbreviation
24
+ col :country_iso_3166_code
25
+ col :co2_emission_factor, :type => :float
26
+ col :co2_emission_factor_units
27
+ col :co2_biogenic_emission_factor, :type => :float
28
+ col :co2_biogenic_emission_factor_units
29
+ col :ch4_emission_factor, :type => :float
30
+ col :ch4_emission_factor_units
31
+ col :n2o_emission_factor, :type => :float
32
+ col :n2o_emission_factor_units
33
+ col :loss_factor, :type => :float
34
+
35
+ warn_unless_size 187
36
+ warn_if_any_nulls
37
+ end
@@ -0,0 +1,87 @@
1
+ ElectricityMix.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ delete_all
5
+ end
6
+
7
+ process "Ensure GreenhouseGas is populated" do
8
+ GreenhouseGas.run_data_miner!
9
+ end
10
+
11
+ import "national electricity mixes from Brander et al. (2011)",
12
+ :url => "file://#{Earth::DATA_DIR}/locality/national_electricity_efs.csv" do
13
+ key :name, :synthesize => lambda { |row| [row['country_iso_3166_code'], 'national electricity'].join(' ') }
14
+ store :country_iso_3166_code
15
+ store :co2_emission_factor, :units_field_name => 'co2_emission_factor_units'
16
+ store :ch4_emission_factor, :synthesize => proc { |row| row['ch4_emission_factor'].to_f * GreenhouseGas[:ch4].global_warming_potential }, :units => 'kilograms_co2e_per_kilowatt_hour'
17
+ store :n2o_emission_factor, :synthesize => proc { |row| row['n2o_emission_factor'].to_f * GreenhouseGas[:n2o].global_warming_potential }, :units => 'kilograms_co2e_per_kilowatt_hour'
18
+ store :loss_factor
19
+ end
20
+
21
+ process "Ensure EgridSubregion is populated" do
22
+ EgridSubregion.run_data_miner!
23
+ end
24
+
25
+ process "Derive eGRID subregion electricity mixes" do
26
+ EgridSubregion.safe_find_each do |subregion|
27
+ mix = find_or_create_by_name [subregion.abbreviation, 'egrid subregion electricity'].join(' ')
28
+ mix.update_attributes!(
29
+ :egrid_subregion_abbreviation => subregion.abbreviation,
30
+ :co2_emission_factor => subregion.co2_emission_factor,
31
+ :co2_emission_factor_units => subregion.co2_emission_factor_units,
32
+ :ch4_emission_factor => subregion.ch4_emission_factor,
33
+ :ch4_emission_factor_units => subregion.ch4_emission_factor_units,
34
+ :n2o_emission_factor => subregion.n2o_emission_factor,
35
+ :n2o_emission_factor_units => subregion.n2o_emission_factor_units,
36
+ :loss_factor => subregion.egrid_region.loss_factor
37
+ )
38
+ end
39
+ end
40
+
41
+ process "Derive US electricity mix from EgridSubregion" do
42
+ us = find_by_country_iso_3166_code 'US'
43
+ us.update_attributes!(
44
+ :co2_emission_factor => EgridSubregion.fallback.co2_emission_factor,
45
+ :co2_emission_factor_units => EgridSubregion.fallback.co2_emission_factor_units,
46
+ :ch4_emission_factor => EgridSubregion.fallback.ch4_emission_factor,
47
+ :ch4_emission_factor_units => EgridSubregion.fallback.ch4_emission_factor_units,
48
+ :n2o_emission_factor => EgridSubregion.fallback.n2o_emission_factor,
49
+ :n2o_emission_factor_units => EgridSubregion.fallback.n2o_emission_factor_units,
50
+ :loss_factor => EgridSubregion.fallback.egrid_region.loss_factor
51
+ )
52
+ end
53
+
54
+ process "Ensure State is populated" do
55
+ State.run_data_miner!
56
+ end
57
+
58
+ process "Derive state electricity mixes" do
59
+ State.safe_find_each do |state|
60
+ mix = find_or_create_by_name_and_state_postal_abbreviation(
61
+ [state.postal_abbreviation, 'state electricity'].join(' '), state.postal_abbreviation
62
+ )
63
+
64
+ sub_pops = state.zip_codes.known_subregion.sum(:population, :group => :egrid_subregion)
65
+
66
+ %w{ co2 ch4 n2o }.each do |gas|
67
+ ef = sub_pops.inject(0) do |memo, (subregion, population)|
68
+ memo += subregion.send("#{gas}_emission_factor") * population
69
+ memo
70
+ end / sub_pops.values.sum
71
+
72
+ mix.update_attributes!(
73
+ "#{gas}_emission_factor" => ef,
74
+ "#{gas}_emission_factor_units" => sub_pops.keys.first.send("#{gas}_emission_factor_units")
75
+ )
76
+ end
77
+
78
+ lf = sub_pops.inject(0) do |memo, (subregion, population)|
79
+ memo += subregion.egrid_region.loss_factor * population
80
+ memo
81
+ end / sub_pops.values.sum
82
+
83
+ mix.update_attributes! :loss_factor => lf
84
+ end
85
+ end
86
+ end
87
+ end