earth 0.11.12 → 0.11.13

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.
data/earth.gemspec CHANGED
@@ -5,7 +5,7 @@ require "earth/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "earth"
7
7
  s.version = Earth::VERSION
8
- s.date = "2012-02-20"
8
+ s.date = "2012-03-05"
9
9
  s.platform = Gem::Platform::RUBY
10
10
  s.authors = ["Seamus Abshere", "Derek Kastner", "Andy Rossmeissl"]
11
11
  s.email = %q{andy@rossmeissl.net}
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
29
29
 
30
30
  s.add_runtime_dependency 'activerecord'
31
31
  s.add_runtime_dependency 'activesupport'
32
- s.add_runtime_dependency 'cohort_scope'
32
+ s.add_runtime_dependency 'cohort_analysis'
33
33
  s.add_runtime_dependency 'conversions'
34
34
  s.add_runtime_dependency 'data_miner', '>=1.3'
35
35
  s.add_runtime_dependency 'falls_back_on'
@@ -3,9 +3,6 @@ require 'earth/locality'
3
3
  class FlightSegment < ActiveRecord::Base
4
4
  self.primary_key = "row_hash"
5
5
 
6
- extend CohortScope
7
- self.minimum_cohort_size = 1
8
-
9
6
  # Cutting this for now because if iata code is missing we have to look up airports using both city and country; don't know how to do this with ActiveRecord
10
7
  # - Ian 6/12/2011
11
8
  # # If airport iata code is missing, associate with all airports in a city
@@ -1,7 +1,7 @@
1
1
  require 'earth/locality/data_miner'
2
2
  CommercialBuildingEnergyConsumptionSurveyResponse.class_eval do
3
3
  data_miner do
4
- import 'building characteristics from the 2003 EIA Commercial Building Energy Consumption Survey',
4
+ import 'building characteristics from the 2003 EIA CBECS - part 1',
5
5
  :url => 'http://www.eia.gov/emeu/cbecs/cbecs2003/public_use_2003/data/FILE01.csv',
6
6
  :skip => 1,
7
7
  :headers => ["PUBID8", "REGION8", "CENDIV8", "SQFT8", "SQFTC8", "YRCONC8", "PBA8", "ELUSED8", "NGUSED8", "FKUSED8", "PRUSED8", "STUSED8", "HWUSED8", "CLIMATE8", "FREESTN8", "WLCNS8", "RFCNS8", "GLSSPC8", "EQGLSS8", "SUNGLS8", "BLDSHP8", "NFLOOR8", "ELEVTR8", "NELVTR8", "ESCLTR8", "NESLTR8", "YRCON8", "MONCON8", "RENOV8", "RENADD8", "RENRDC8", "RENCOS8", "RENEXT8", "RENINT8", "RENHVC8", "RENLGT8", "RENWIN8", "RENPLB8", "RENINS8", "RENOTH8", "GOVOWN8", "GOVTYP8", "OWNER8", "OWNOCC8", "NOCC8", "NOCCAT8", "MONUSE8", "PORVAC8", "OPEN248", "OPNMF8", "OPNWE8", "WKHRS8", "WKHRSC8", "NWKER8", "NWKERC8", "HT18", "HT28", "COOL8", "WATR8", "COOK8", "MANU8", "GENR8", "ADJWT8", "STRATUM8", "PAIR8"] do
@@ -20,7 +20,7 @@ CommercialBuildingEnergyConsumptionSurveyResponse.class_eval do
20
20
  store 'weighting', :field_name => 'ADJWT8'
21
21
  end
22
22
 
23
- import 'building characteristics from the 2003 EIA Commercial Building Energy Consumption Survey',
23
+ import 'building characteristics from the 2003 EIA CBECS - part 2',
24
24
  :url => 'http://www.eia.gov/emeu/cbecs/cbecs2003/public_use_2003/data/FILE02.csv',
25
25
  :skip => 1,
26
26
  :headers => ["PUBID8","REGION8","CENDIV8","SQFT8","SQFTC8","YRCONC8","PBA8","ELUSED8","NGUSED8","FKUSED8","PRUSED8","STUSED8","HWUSED8","ONEACT8","ACT18","ACT28","ACT38","ACT1PCT8","ACT2PCT8","ACT3PCT8","PBAPLUS8","VACANT8","RWSEAT8","PBSEAT8","EDSEAT8","FDSEAT8","HCBED8","NRSBED8","LODGRM8","FACIL8","FEDFAC8","FACACT8","MANIND8","PLANT8","FACDST8","FACDHW8","FACDCW8","FACELC8","BLDPLT8","ADJWT8","STRATUM8","PAIR8"] do
@@ -35,7 +35,7 @@ CommercialBuildingEnergyConsumptionSurveyResponse.class_eval do
35
35
  store 'lodging_rooms', :field_name => 'LODGRM8'
36
36
  end
37
37
 
38
- import 'building characteristics from the 2003 EIA Commercial Building Energy Consumption Survey',
38
+ import 'building characteristics from the 2003 EIA CBECS - part 3',
39
39
  :url => 'http://www.eia.gov/emeu/cbecs/cbecs2003/public_use_2003/data/FILE03.csv',
40
40
  :skip => 1,
41
41
  :headers => ["PUBID8","REGION8","CENDIV8","SQFT8","SQFTC8","YRCONC8","PBA8","ELUSED8","NGUSED8","FKUSED8","PRUSED8","STUSED8","HWUSED8","HEATP8","HTLS508","FURNAC8","BOILER8","PKGHT8","SLFCON8","HTPMPH8","STHW8","OTHTEQ8","FURNP8","BOILP8","PKGHP8","SLFCNP8","HTPHP8","STHWP8","OTHTP8","MAINHT8","PKGHPS8","SPLHPS8","RMHPS8","AIRHPT8","GRDHPT8","WTRHPT8","NWMNHT8","RDHTNF8","HWRDHT8","COOLP8","PKGCL8","RCAC8","ACWNWL8","HTPMPC8","CHWT8","CHILLR8","EVAPCL8","OTCLEQ8","PKGCP8","RCACP8","ACWNWP8","HTPCP8","CHWTP8","CHILP8","EVAPP8","OTCLP8","MAINCL8","PKGCPS8","SPLCPS8","RMCPS8","AIRCPT8","GRDCPT8","WTRCPT8","NWMNCL8","RDCLNF8","HWRDCL8","VAV8","ECN8","MAINT8","EMCS8","ADJWT8","STRATUM8","PAIR8"] do
@@ -43,7 +43,7 @@ CommercialBuildingEnergyConsumptionSurveyResponse.class_eval do
43
43
  store 'percent_cooled', :synthesize => Proc.new { |row| row['COOLP8'].to_f / 100.0 }
44
44
  end
45
45
 
46
- import 'electricity use from the 2003 EIA Commercial Building Energy Consumption Survey',
46
+ import 'electricity use from the 2003 EIA CBECS',
47
47
  :url => 'http://www.eia.gov/emeu/cbecs/cbecs2003/public_use_2003/data/FILE15.csv',
48
48
  :skip => 1,
49
49
  :headers => ["PUBID8", "REGION8", "CENDIV8", "SQFT8", "SQFTC8", "YRCONC8", "PBA8", "ELUSED8", "NGUSED8", "FKUSED8", "PRUSED8", "STUSED8", "HWUSED8", "ADJWT8", "STRATUM8", "PAIR8", "HDD658", "CDD658", "MFUSED8", "MFBTU8", "MFEXP8", "ELCNS8", "ELBTU8", "ELEXP8", "ZELCNS8", "ZELEXP8"] do
@@ -54,7 +54,7 @@ CommercialBuildingEnergyConsumptionSurveyResponse.class_eval do
54
54
  store 'electricity_energy', :field_name => 'ELBTU8', :from_units => :kbtus, :to_units => :megajoules
55
55
  end
56
56
 
57
- import 'fuel use characteristics from the 2003 EIA Commercial Building Energy Consumption Survey',
57
+ import 'fuel use characteristics from the 2003 EIA CBECS',
58
58
  :url => 'http://www.eia.gov/emeu/cbecs/cbecs2003/public_use_2003/data/FILE16.csv',
59
59
  :skip => 1,
60
60
  :headers => ["PUBID8", "REGION8", "CENDIV8", "SQFT8", "SQFTC8", "YRCONC8", "PBA8", "ELUSED8", "NGUSED8", "FKUSED8", "PRUSED8", "STUSED8", "HWUSED8", "ADJWT8", "STRATUM8", "PAIR8", "NGCNS8", "NGBTU8", "NGEXP8", "ZNGCNS8", "ZNGEXP8", "FKCNS8", "FKBTU8", "FKEXP8", "ZFKCNS8", "ZFKEXP8", "DHUSED8", "DHHT18", "DHHT28", "DHCOOL8", "DHWATR8", "DHCOOK8", "DHMANU8", "DHOTH8", "DHCNS8", "DHBTU8", "DHEXP8", "ZDHCNS8", "ZDHEXP8"] do
@@ -78,5 +78,18 @@ CommercialBuildingEnergyConsumptionSurveyResponse.class_eval do
78
78
  }
79
79
  end
80
80
  end
81
+
82
+ process "Derive fuel intensities per unit area" do
83
+ [:natural_gas, :fuel_oil, :electricity].each do |fuel|
84
+ update_all %{
85
+ #{fuel}_energy_intensity = #{fuel}_energy / area,
86
+ #{fuel}_energy_intensity_units = 'megajoules_per_square_metre'
87
+ }
88
+ update_all %{
89
+ district_heat_energy_intensity = district_heat_use / area,
90
+ district_heat_energy_intensity_units = 'megajoules_per_square_metre'
91
+ }
92
+ end
93
+ end
81
94
  end
82
95
  end
@@ -3,9 +3,6 @@ class CommercialBuildingEnergyConsumptionSurveyResponse < ActiveRecord::Base
3
3
  self.primary_key = "id"
4
4
  self.table_name = :cbecs_responses
5
5
 
6
- extend CohortScope
7
- self.minimum_cohort_size = 8 # CBECS doesn't report averages based on fewer than 20 samples
8
-
9
6
  def self.lodging_records
10
7
  where(:detailed_activity => ['Hotel', 'Motel or inn'], :first_activity => nil)
11
8
  end
@@ -59,4 +56,12 @@ class CommercialBuildingEnergyConsumptionSurveyResponse < ActiveRecord::Base
59
56
  col :fuel_oil_per_room_night_units # for lodging fuzzy weighting
60
57
  col :district_heat_per_room_night, :type => :float # for lodging fuzzy weighting
61
58
  col :district_heat_per_room_night_units # for lodging fuzzy weighting
59
+ col :electricity_energy_intensity, :type => :float
60
+ col :electricity_energy_intensity_units
61
+ col :natural_gas_energy_intensity, :type => :float
62
+ col :natural_gas_energy_intensity_units
63
+ col :fuel_oil_energy_intensity, :type => :float
64
+ col :fuel_oil_energy_intensity_units
65
+ col :district_heat_energy_intensity, :type => :float
66
+ col :district_heat_energy_intensity_units
62
67
  end
@@ -47,16 +47,37 @@ class MecsEnergy < ActiveRecord::Base
47
47
  record
48
48
  end
49
49
 
50
- # TODO make this less paranoid
51
- # for now only return a ratio if no fuels are nil and at least one fuel is nonzero
52
50
  def fuel_ratios
53
- if energy.to_f > 0 # return nil if energy is nil or 0
54
- ratios = FUELS.inject({}) do |r, fuel|
55
- fuel_use = send("#{fuel}")
56
- r[fuel] = fuel_use.present? ? fuel_use / energy : nil
57
- r
51
+ # Don't return a ratio if reported total energy was withheld
52
+ if energy.to_f > 0
53
+ # Calculate the sum of all fuels and note if any were withheld
54
+ withheld = 0
55
+ fuels_sum = MecsEnergy::FUELS.inject(0) do |sum, fuel|
56
+ (value = send("#{fuel}")).nil? ? withheld = 1 : sum += value
57
+ sum
58
+ end
59
+
60
+ # If energy > sum of all fuels and some fuels were withheld, calculate fuel ratios as fraction of energy
61
+ # and attribute the disparity between energy and sum of all fuels to the dirtiest fuel that was withheld
62
+ if energy > fuels_sum and withheld == 1
63
+ ratios = MecsEnergy::FUELS.inject({}) do |r, fuel|
64
+ fuel_use = send("#{fuel}")
65
+ r[fuel] = fuel_use.present? ? fuel_use / energy : nil
66
+ r
67
+ end
68
+
69
+ dirtiest_withheld = ([:coal, :other_fuel, :coke_and_breeze, :residual_fuel_oil, :distillate_fuel_oil, :lpg_and_ngl, :natural_gas] & ratios.select{|k,v| v.nil?}.keys).first
70
+ ratios[dirtiest_withheld] = (energy - fuels_sum) / energy
71
+ ratios.delete_if{ |fuel, ratio| ratio.to_f == 0.0 }
72
+ # Otherwise calculate ratios as fraction of sum of all fuels, skipping any fuels that were withheld
73
+ else
74
+ ratios = MecsEnergy::FUELS.inject({}) do |r, fuel|
75
+ fuel_use = send("#{fuel}")
76
+ r[fuel] = fuel_use / fuels_sum if fuel_use.to_f > 0
77
+ r
78
+ end
79
+ ratios.keys.any? ? ratios : nil
58
80
  end
59
- ratios unless ratios.values.include? nil or ratios.values.all?(&:zero?) # return nil if any fuel uses were missing or all fuel uses were zero
60
81
  end
61
82
  end
62
83
  end
@@ -103,23 +103,20 @@ Country.class_eval do
103
103
  row['electricity_co2_emission_factor'].to_f +
104
104
  (row['electricity_ch4_emission_factor'].to_f * GreenhouseGas[:ch4].global_warming_potential) +
105
105
  (row['electricity_n2o_emission_factor'].to_f * GreenhouseGas[:n2o].global_warming_potential)
106
- ) / (1 - row['loss_factor'].to_f) }, :units => 'kilograms_co2e_per_kilowatt_hour'
106
+ ) }, :units => 'kilograms_co2e_per_kilowatt_hour'
107
+ store 'electricity_loss_factor', :field_name => 'loss_factor'
107
108
  end
108
109
 
109
- process "Ensure EgridSubregion is populated" do
110
+ process "Ensure EgridSubregion and EgridRegion are populated" do
110
111
  EgridSubregion.run_data_miner!
112
+ EgridRegion.run_data_miner!
111
113
  end
112
114
 
113
- process "Derive average US electricity emission factor from eGRID" do
115
+ process "Derive average US electricity emission factor and loss factor from eGRID" do
114
116
  us = united_states
115
- subregion = EgridSubregion.fallback
116
- us.electricity_emission_factor =
117
- (
118
- subregion.electricity_co2_emission_factor +
119
- subregion.electricity_ch4_emission_factor +
120
- subregion.electricity_n2o_emission_factor
121
- ) / (1 - subregion.egrid_region.loss_factor)
122
- us.electricity_emission_factor_units = 'kilograms_co2e_per_kilowatt_hour'
117
+ us.electricity_emission_factor = EgridSubregion.fallback.electricity_emission_factor
118
+ us.electricity_emission_factor_units = EgridSubregion.fallback.electricity_emission_factor_units
119
+ us.electricity_loss_factor = EgridRegion.fallback.loss_factor
123
120
  us.save!
124
121
  end
125
122
 
@@ -18,8 +18,9 @@ class Country < ActiveRecord::Base
18
18
  :automobile_highway_speed_units => lambda { united_states.automobile_highway_speed_units }, # for now assume US represents world
19
19
  :automobile_trip_distance => lambda { united_states.automobile_trip_distance }, # for now assume US represents world
20
20
  :automobile_trip_distance_units => lambda { united_states.automobile_trip_distance_units }, # for now assume US represents world
21
- :electricity_emission_factor => 0.69252, # from ecometrica paper - FIXME TODO calculate this
21
+ :electricity_emission_factor => 0.626089, # from ecometrica paper - FIXME TODO calculate this
22
22
  :electricity_emission_factor_units => 'kilograms_co2e_per_kilowatt_hour', # FIXME TODO derive this
23
+ :electricity_loss_factor => 0.096, # from ecometrica paper - FIXME TODO calculate this
23
24
  :flight_route_inefficiency_factor => lambda { maximum(:flight_route_inefficiency_factor) }, # default to the largest inefficiency factor
24
25
  :lodging_occupancy_rate => lambda { united_states.lodging_occupancy_rate }, # for now assume US represents world
25
26
  :lodging_natural_gas_intensity => lambda { united_states.lodging_natural_gas_intensity }, # for now assume US represents world
@@ -68,6 +69,7 @@ class Country < ActiveRecord::Base
68
69
  col :automobile_trip_distance_units
69
70
  col :electricity_emission_factor, :type => :float
70
71
  col :electricity_emission_factor_units
72
+ col :electricity_loss_factor, :type => :float
71
73
  col :flight_route_inefficiency_factor, :type => :float
72
74
  col :lodging_occupancy_rate, :type => :float
73
75
  col :lodging_natural_gas_intensity, :type => :float
@@ -26,5 +26,35 @@ State.class_eval do
26
26
  key 'postal_abbreviation', :field_name => 'State'
27
27
  store 'petroleum_administration_for_defense_district_code', :field_name => 'Code'
28
28
  end
29
+
30
+ process 'ensure ZipCode, EgridSubregion, and EgridRegion are populated' do
31
+ ZipCode.run_data_miner!
32
+ EgridSubregion.run_data_miner!
33
+ EgridRegion.run_data_miner!
34
+ end
35
+
36
+ process 'derive average electricity emission factor and loss factor from zip code and eGRID data' do
37
+ update_all %{
38
+ electricity_emission_factor = (
39
+ SELECT SUM(zip_codes.population * egrid_subregions.electricity_emission_factor) / SUM(zip_codes.population)
40
+ FROM zip_codes
41
+ INNER JOIN egrid_subregions ON egrid_subregions.abbreviation = zip_codes.egrid_subregion_abbreviation
42
+ WHERE zip_codes.state_postal_abbreviation = states.postal_abbreviation
43
+ ),
44
+ electricity_emission_factor_units = 'kilograms_co2e_per_kilowatt_hour',
45
+ electricity_loss_factor = (
46
+ SELECT SUM(zip_codes.population * egrid_regions.loss_factor) / SUM(zip_codes.population)
47
+ FROM zip_codes
48
+ INNER JOIN egrid_subregions ON egrid_subregions.abbreviation = zip_codes.egrid_subregion_abbreviation
49
+ INNER JOIN egrid_regions ON egrid_regions.name = egrid_subregions.egrid_region_name
50
+ WHERE zip_codes.state_postal_abbreviation = states.postal_abbreviation
51
+ )
52
+ }
53
+ end
54
+
55
+ # TODO import this from US census? would be slightly different: 0.7% for Alaska, 0.2% for New Mexico, etc.
56
+ process 'derive population from zip code data' do
57
+ update_all "population = (SELECT SUM(population) FROM zip_codes WHERE zip_codes.state_postal_abbreviation = states.postal_abbreviation)"
58
+ end
29
59
  end
30
60
  end
@@ -4,8 +4,8 @@ class State < ActiveRecord::Base
4
4
  has_many :climate_divisions, :foreign_key => 'state_postal_abbreviation'
5
5
  has_many :zip_codes, :foreign_key => 'state_postal_abbreviation'
6
6
  belongs_to :census_division, :foreign_key => 'census_division_number'
7
- belongs_to :petroleum_administration_for_defense_district, :foreign_key => 'petroleum_administration_for_defense_district_code'
8
7
  has_one :census_region, :through => :census_division
8
+ belongs_to :petroleum_administration_for_defense_district, :foreign_key => 'petroleum_administration_for_defense_district_code'
9
9
 
10
10
  def country
11
11
  Country.united_states
@@ -16,4 +16,8 @@ class State < ActiveRecord::Base
16
16
  col :name
17
17
  col :census_division_number, :type => :integer
18
18
  col :petroleum_administration_for_defense_district_code
19
+ col :population, :type => :integer
20
+ col :electricity_emission_factor, :type => :float
21
+ col :electricity_emission_factor_units
22
+ col :electricity_loss_factor, :type => :float
19
23
  end
@@ -32,6 +32,20 @@ ZipCode.class_eval do
32
32
  store 'climate_division_name'
33
33
  end
34
34
 
35
- # FIXME TODO verify this
35
+ # TODO: download file directly from US census
36
+ # NOTE: ZCTAs are not zip codes but are based on the most common zip code in the area they cover - see http://www.census.gov/geo/ZCTA/zcta.html
37
+ import 'US Census 2010 zip code tabulation area populations',
38
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdHJsVjlKNXNLNEQyWENjZ1owd2hFS3c&output=csv',
39
+ :skip => 1 do
40
+ key 'name', :field_name => 'Id2', :sprintf => '%05d'
41
+ store 'population', :field_name => 'Total'
42
+ end
43
+
44
+ import 'misc zip code data not included in other sources',
45
+ :url => 'https://docs.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdHFYaUE1cEdHTzZCcTFQOEZOTGVUemc&output=csv' do
46
+ key 'name', :sprintf => '%05d'
47
+ store 'state_postal_abbreviation'
48
+ store 'egrid_subregion_abbreviation'
49
+ end
36
50
  end
37
51
  end
@@ -26,4 +26,5 @@ class ZipCode < ActiveRecord::Base
26
26
  col :longitude
27
27
  col :egrid_subregion_abbreviation
28
28
  col :climate_division_name
29
+ col :population, :type => :integer
29
30
  end
@@ -1,3 +1,4 @@
1
+ require 'cohort_analysis'
1
2
  ClothesMachineUse.class_eval do
2
3
  data_miner do
3
4
  process "Ensure ResidentialEnergyConsumptionSurveyResponse is populated" do
@@ -15,7 +16,7 @@ ClothesMachineUse.class_eval do
15
16
  # sabshere 5/20/10 weird that this uses cohort
16
17
  process "precalculate annual energy use" do
17
18
  find_each do |record|
18
- record.annual_energy_from_electricity_for_clothes_driers = ResidentialEnergyConsumptionSurveyResponse.big_cohort(:clothes_machine_use_id => record.name).weighted_average :annual_energy_from_electricity_for_clothes_driers
19
+ record.annual_energy_from_electricity_for_clothes_driers = ResidentialEnergyConsumptionSurveyResponse.cohort(:clothes_machine_use_id => record.name).weighted_average :annual_energy_from_electricity_for_clothes_driers
19
20
  record.annual_energy_from_electricity_for_clothes_driers_units = 'joules'
20
21
  record.save!
21
22
  end
@@ -1,3 +1,4 @@
1
+ require 'cohort_analysis'
1
2
  DishwasherUse.class_eval do
2
3
  data_miner do
3
4
  process "Ensure ResidentialEnergyConsumptionSurveyResponse is populated" do
@@ -15,7 +16,7 @@ DishwasherUse.class_eval do
15
16
  # sabshere 5/25/10 weird that this uses cohort
16
17
  process "precalculate annual energy" do
17
18
  find_each do |record|
18
- record.annual_energy_from_electricity_for_dishwashers = ResidentialEnergyConsumptionSurveyResponse.big_cohort(:dishwasher_use_id => record.name).weighted_average :annual_energy_from_electricity_for_dishwashers
19
+ record.annual_energy_from_electricity_for_dishwashers = ResidentialEnergyConsumptionSurveyResponse.cohort(:dishwasher_use_id => record.name).weighted_average :annual_energy_from_electricity_for_dishwashers
19
20
  record.annual_energy_from_electricity_for_dishwashers_units = 'joules'
20
21
  record.save!
21
22
  end
@@ -2,9 +2,6 @@ require 'earth/locality'
2
2
  class ResidenceFuelPrice < ActiveRecord::Base
3
3
  self.primary_key = "row_hash"
4
4
 
5
- extend CohortScope
6
- self.minimum_cohort_size = 5 # ? FIXME
7
-
8
5
  belongs_to :fuel, :class_name => 'ResidenceFuelType', :foreign_key => 'residence_fuel_type_name'
9
6
  belongs_to :locatable, :polymorphic => true
10
7
 
@@ -12,10 +12,6 @@ class ResidentialEnergyConsumptionSurveyResponse < ActiveRecord::Base
12
12
  belongs_to :air_conditioner_use
13
13
  belongs_to :clothes_machine_use
14
14
 
15
- extend CohortScope
16
- self.minimum_cohort_size = 5
17
- SUBCOHORT_THRESHOLD = 5 # per Matt
18
-
19
15
  INPUT_CHARACTERISTICS = [
20
16
  :ownership,
21
17
  :construction_year,
data/lib/earth/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Earth
2
- VERSION = "0.11.12"
2
+ VERSION = "0.11.13"
3
3
  end
data/lib/earth.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'active_support/core_ext'
2
2
  require 'active_record'
3
- require 'cohort_scope'
4
3
  require 'earth/conversions_ext'
5
4
  require 'earth/inflectors'
6
5
  require 'data_miner'
@@ -75,17 +75,137 @@ describe MecsEnergy do
75
75
  end
76
76
 
77
77
  describe '#fuel_ratios' do
78
- it 'returns a list of fuel ratios for a given NAICS' do
79
- energy = MecsEnergy.new :energy => 100, :electricity => 20,
80
- :residual_fuel_oil => 1, :distillate_fuel_oil => 2,
81
- :natural_gas => 30, :lpg_and_ngl => 22, :coal => 22,
82
- :coke_and_breeze => 1, :other_fuel => 1
78
+ it 'calculates based on sum of all fuels when no fuels are missing' do
79
+ # Energy < sum all fuels
80
+ energy = MecsEnergy.new(
81
+ :energy => 50,
82
+ :electricity => 25,
83
+ :residual_fuel_oil => 10,
84
+ :distillate_fuel_oil => 10,
85
+ :natural_gas => 25,
86
+ :lpg_and_ngl => 5,
87
+ :coal => 5,
88
+ :coke_and_breeze => 15,
89
+ :other_fuel => 5
90
+ )
83
91
  energy.fuel_ratios.should == {
84
- :electricity => 0.20,
85
- :residual_fuel_oil => 0.01, :distillate_fuel_oil => 0.02,
86
- :natural_gas => 0.3, :lpg_and_ngl => 0.22, :coal => 0.22,
87
- :coke_and_breeze => 0.01, :other_fuel => 0.01
92
+ :electricity => 0.25,
93
+ :residual_fuel_oil => 0.1,
94
+ :distillate_fuel_oil => 0.1,
95
+ :natural_gas => 0.25,
96
+ :lpg_and_ngl => 0.05,
97
+ :coal => 0.05,
98
+ :coke_and_breeze => 0.15,
99
+ :other_fuel => 0.05
88
100
  }
101
+
102
+ # Energy = sum all fuels
103
+ energy = MecsEnergy.new(
104
+ :energy => 100,
105
+ :electricity => 25,
106
+ :residual_fuel_oil => 10,
107
+ :distillate_fuel_oil => 10,
108
+ :natural_gas => 25,
109
+ :lpg_and_ngl => 5,
110
+ :coal => 5,
111
+ :coke_and_breeze => 15,
112
+ :other_fuel => 5
113
+ )
114
+ energy.fuel_ratios.should == {
115
+ :electricity => 0.25,
116
+ :residual_fuel_oil => 0.1,
117
+ :distillate_fuel_oil => 0.1,
118
+ :natural_gas => 0.25,
119
+ :lpg_and_ngl => 0.05,
120
+ :coal => 0.05,
121
+ :coke_and_breeze => 0.15,
122
+ :other_fuel => 0.05
123
+ }
124
+
125
+ # Energy > sum of all fuels
126
+ energy = MecsEnergy.new(
127
+ :energy => 200,
128
+ :electricity => 25,
129
+ :residual_fuel_oil => 75,
130
+ :distillate_fuel_oil => 0,
131
+ :natural_gas => 0,
132
+ :lpg_and_ngl => 0,
133
+ :coal => 0,
134
+ :coke_and_breeze => 0,
135
+ :other_fuel => 0
136
+ )
137
+ energy.fuel_ratios.should == {
138
+ :electricity => 0.25,
139
+ :residual_fuel_oil => 0.75
140
+ }
141
+ end
142
+
143
+ it 'ignores missing fuels when energy <= sum of all fuels' do
144
+ # Energy < sum of all fuels
145
+ energy = MecsEnergy.new(
146
+ :energy => 50,
147
+ :electricity => 25,
148
+ :residual_fuel_oil => 75
149
+ )
150
+ energy.fuel_ratios.should == {
151
+ :electricity => 0.25,
152
+ :residual_fuel_oil => 0.75
153
+ }
154
+
155
+ # Energy = sum of all fuels
156
+ energy = MecsEnergy.new(
157
+ :energy => 100,
158
+ :electricity => 25,
159
+ :residual_fuel_oil => 75
160
+ )
161
+ energy.fuel_ratios.should == {
162
+ :electricity => 0.25,
163
+ :residual_fuel_oil => 0.75
164
+ }
165
+ end
166
+
167
+ it 'adjusts for missing fuels when energy > sum of all fuels' do
168
+ energy = MecsEnergy.new(
169
+ :energy => 200,
170
+ :electricity => 25,
171
+ :residual_fuel_oil => 75
172
+ )
173
+ energy.fuel_ratios.should == {
174
+ :electricity => 0.125,
175
+ :residual_fuel_oil => 0.375,
176
+ :coal => 0.5
177
+ }
178
+ end
179
+
180
+ it 'returns nil if energy is missing or zero' do
181
+ energy = MecsEnergy.new(
182
+ :energy => nil,
183
+ :electricity => 25,
184
+ :residual_fuel_oil => 75
185
+ )
186
+ energy.fuel_ratios.should be_nil
187
+
188
+ energy = MecsEnergy.new(
189
+ :energy => 0,
190
+ :electricity => 25,
191
+ :residual_fuel_oil => 75
192
+ )
193
+ energy.fuel_ratios.should be_nil
194
+ end
195
+
196
+ it 'returns nil if all fuels are zero' do
197
+ energy = MecsEnergy.new(
198
+ :energy => 1,
199
+ :electricity => 0,
200
+ :residual_fuel_oil => 0,
201
+ :distillate_fuel_oil => 0,
202
+ :natural_gas => 0,
203
+ :lpg_and_ngl => 0,
204
+ :coal => 0,
205
+ :coke_and_breeze => 0,
206
+ :other_fuel => 0
207
+ )
208
+ energy.fuel_ratios.should be_nil
89
209
  end
90
210
  end
91
211
  end
@@ -1,13 +1,51 @@
1
1
  require 'spec_helper'
2
- require 'earth/locality'
3
- require 'earth/locality/data_miner'
2
+ require 'earth/locality/country'
4
3
 
5
4
  describe Country do
5
+ before :all do
6
+ Country.auto_upgrade!
7
+ end
8
+
6
9
  describe 'import', :slow => true do
10
+ before do
11
+ require 'earth/locality/country/data_miner'
12
+ end
13
+
7
14
  it 'should import data' do
8
- Earth.init 'locality', :load_data_miner => true, :apply_schemas => true
9
15
  Country.run_data_miner!
10
16
  Country.all.count.should == 249
11
17
  end
12
18
  end
19
+
20
+ describe 'verify imported data', :sanity => true do
21
+ it 'has valid electricity emission factor and electricity loss factor for most countries' do
22
+ Country.where('electricity_emission_factor IS NOT NULL').count.should == 136
23
+ Country.where(:electricity_emission_factor_units => 'kilograms_co2e_per_kilowatt_hour').count.should == 136
24
+ Country.where('electricity_loss_factor IS NOT NULL').count.should == 136
25
+
26
+ Country.minimum(:electricity_emission_factor).should >= 0.0
27
+ Country.minimum(:electricity_loss_factor).should >= 0.0
28
+ Country.maximum(:electricity_loss_factor).should < 0.3
29
+
30
+ Country.find('US').electricity_emission_factor.should be_within(0.00001).of(0.58946)
31
+ Country.find('US').electricity_emission_factor_units.should == 'kilograms_co2e_per_kilowatt_hour'
32
+ Country.find('US').electricity_loss_factor.should be_within(0.001).of(0.062)
33
+
34
+ Country.find('GB').electricity_emission_factor.should be_within(0.00001).of(0.51020)
35
+ Country.find('GB').electricity_emission_factor_units.should == 'kilograms_co2e_per_kilowatt_hour'
36
+ Country.find('GB').electricity_loss_factor.should be_within(0.001).of(0.073)
37
+ end
38
+
39
+ it 'has fallback electricity emission factor and electricity loss factor' do
40
+ Country.fallback.electricity_emission_factor.should be_within(0.00001).of(0.62609)
41
+ Country.fallback.electricity_emission_factor_units.should == 'kilograms_co2e_per_kilowatt_hour'
42
+ Country.fallback.electricity_loss_factor.should be_within(0.001).of(0.096)
43
+ end
44
+ end
45
+
46
+ describe '.united_states' do
47
+ it 'should return the United States' do
48
+ Country.united_states.should == Country.find('US')
49
+ end
50
+ end
13
51
  end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'earth/locality/state'
3
+
4
+ describe State do
5
+ before :all do
6
+ State.auto_upgrade!
7
+ end
8
+
9
+ describe 'when importing data', :slow => true do
10
+ before do
11
+ require 'earth/locality/state/data_miner'
12
+ end
13
+
14
+ it 'imports data' do
15
+ State.run_data_miner!
16
+ State.count.should == 51 # includes DC but not any territories
17
+ end
18
+ end
19
+
20
+ describe 'verify imported data', :sanity => true do
21
+ it 'should have a population' do
22
+ State.find('VT').population.should == 625741
23
+ State.find('CA').population.should == 37249542
24
+ State.find('MT').population.should == 990213
25
+ State.find('NM').population.should == 2056349
26
+ end
27
+
28
+ it 'should have an average electricity emission factor' do
29
+ State.find('VT').electricity_emission_factor.should be_within(0.00001).of(0.37848)
30
+ State.find('VT').electricity_emission_factor_units.should == "kilograms_co2e_per_kilowatt_hour"
31
+ State.find('CA').electricity_emission_factor.should be_within(0.00001).of(0.31315)
32
+ State.find('CA').electricity_emission_factor_units.should == "kilograms_co2e_per_kilowatt_hour"
33
+ State.find('MT').electricity_emission_factor.should be_within(0.00001).of(0.41092)
34
+ State.find('MT').electricity_emission_factor_units.should == "kilograms_co2e_per_kilowatt_hour"
35
+ State.find('NM').electricity_emission_factor.should be_within(0.00001).of(0.57194)
36
+ State.find('NM').electricity_emission_factor_units.should == "kilograms_co2e_per_kilowatt_hour"
37
+ end
38
+
39
+ it 'should have an average electricity loss factor' do
40
+ State.find('VT').electricity_loss_factor.should be_within(0.00001).of(0.0647079)
41
+ State.find('CA').electricity_loss_factor.should be_within(0.00001).of(0.0483723)
42
+ State.find('MT').electricity_loss_factor.should be_within(0.00001).of(0.0491516)
43
+ State.find('NM').electricity_loss_factor.should be_within(0.00001).of(0.0499872)
44
+ end
45
+ end
46
+
47
+ describe '#country' do
48
+ before do
49
+ require 'earth/locality/country'
50
+ end
51
+
52
+ it 'should the United States' do
53
+ State.first.country.should == Country.united_states
54
+ State.last.country.should == Country.united_states
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'earth/locality/zip_code'
3
+
4
+ describe ZipCode do
5
+ before :all do
6
+ ZipCode.auto_upgrade!
7
+ end
8
+
9
+ describe 'when importing data', :slow => true do
10
+ before do
11
+ require 'earth/locality/zip_code/data_miner'
12
+ end
13
+
14
+ it 'imports data' do
15
+ ZipCode.run_data_miner!
16
+ ZipCode.count.should == 43770
17
+ end
18
+ end
19
+
20
+ describe 'verify imported data', :sanity => true do
21
+ it 'has a state for most zip codes' do
22
+ ZipCode.where('state_postal_abbreviation IS NOT NULL').count.should == 43734
23
+ end
24
+
25
+ it 'has a lat and lng for most zip codes' do
26
+ ZipCode.where('latitude IS NOT NULL AND longitude IS NOT NULL').count.should == 43191
27
+ end
28
+
29
+ it 'has an eGRID subregion for most zip codes' do
30
+ ZipCode.where('egrid_subregion_abbreviation IS NOT NULL').count.should == 41297
31
+ end
32
+
33
+ it 'has a climate division for most zip codes' do
34
+ ZipCode.where('climate_division_name IS NOT NULL').count.should == 41358
35
+ end
36
+
37
+ it 'has a population for all 33120 Census 2010 ZCTAs' do
38
+ ZipCode.where('population IS NOT NULL').count.should == 33120
39
+ end
40
+ end
41
+
42
+ describe '#country' do
43
+ before do
44
+ require 'earth/locality/country'
45
+ end
46
+
47
+ it 'should return the US' do
48
+ ZipCode.first.country.should == Country.united_states
49
+ ZipCode.last.country.should == Country.united_states
50
+ end
51
+ end
52
+
53
+ describe '#latitude_longitude' do
54
+ it 'should return the lat and lng as an array of strings' do
55
+ ZipCode.first.latitude_longitude.should == [nil, nil]
56
+ ZipCode.last.latitude_longitude.should == ['55.875767', '-131.46633']
57
+ end
58
+ end
59
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: earth
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.11.12
5
+ version: 0.11.13
6
6
  platform: ruby
7
7
  authors:
8
8
  - Seamus Abshere
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2012-02-20 00:00:00 Z
15
+ date: 2012-03-05 00:00:00 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activerecord
@@ -37,7 +37,7 @@ dependencies:
37
37
  prerelease: false
38
38
  version_requirements: *id002
39
39
  - !ruby/object:Gem::Dependency
40
- name: cohort_scope
40
+ name: cohort_analysis
41
41
  requirement: &id003 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
@@ -623,6 +623,8 @@ files:
623
623
  - spec/earth/industry/naics_2007_spec.rb
624
624
  - spec/earth/industry/sic_1987_spec.rb
625
625
  - spec/earth/locality/country_spec.rb
626
+ - spec/earth/locality/state_spec.rb
627
+ - spec/earth/locality/zip_code_spec.rb
626
628
  - spec/earth/pet/species_spec.rb
627
629
  - spec/earth_spec.rb
628
630
  - spec/spec_helper.rb
@@ -685,7 +687,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
685
687
  requirements:
686
688
  - - ">="
687
689
  - !ruby/object:Gem::Version
688
- hash: -2879856841116714656
690
+ hash: -2326149133598914243
689
691
  segments:
690
692
  - 0
691
693
  version: "0"
@@ -694,7 +696,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
694
696
  requirements:
695
697
  - - ">="
696
698
  - !ruby/object:Gem::Version
697
- hash: -2879856841116714656
699
+ hash: -2326149133598914243
698
700
  segments:
699
701
  - 0
700
702
  version: "0"
@@ -805,6 +807,8 @@ test_files:
805
807
  - spec/earth/industry/naics_2007_spec.rb
806
808
  - spec/earth/industry/sic_1987_spec.rb
807
809
  - spec/earth/locality/country_spec.rb
810
+ - spec/earth/locality/state_spec.rb
811
+ - spec/earth/locality/zip_code_spec.rb
808
812
  - spec/earth/pet/species_spec.rb
809
813
  - spec/earth_spec.rb
810
814
  - spec/spec_helper.rb