earth 0.12.3 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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