earth 0.11.12 → 0.11.13

Sign up to get free protection for your applications and to get access to all the features.
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