earth-ruby19 0.2.3

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 (187) hide show
  1. data/Gemfile +5 -0
  2. data/Gemfile.lock +138 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +38 -0
  5. data/lib/earth.rb +146 -0
  6. data/lib/earth/active_record_ext.rb +9 -0
  7. data/lib/earth/air.rb +13 -0
  8. data/lib/earth/air/aircraft.rb +21 -0
  9. data/lib/earth/air/aircraft/data_miner.rb +184 -0
  10. data/lib/earth/air/aircraft_class.rb +10 -0
  11. data/lib/earth/air/aircraft_class/data_miner.rb +42 -0
  12. data/lib/earth/air/aircraft_manufacturer.rb +9 -0
  13. data/lib/earth/air/aircraft_manufacturer/data_miner.rb +20 -0
  14. data/lib/earth/air/airline.rb +16 -0
  15. data/lib/earth/air/airline/data_miner.rb +57 -0
  16. data/lib/earth/air/airport.rb +44 -0
  17. data/lib/earth/air/airport/data_miner.rb +80 -0
  18. data/lib/earth/air/data_miner.rb +15 -0
  19. data/lib/earth/air/flight_configuration.rb +7 -0
  20. data/lib/earth/air/flight_configuration/data_miner.rb +16 -0
  21. data/lib/earth/air/flight_distance_class.rb +7 -0
  22. data/lib/earth/air/flight_distance_class/data_miner.rb +16 -0
  23. data/lib/earth/air/flight_domesticity.rb +6 -0
  24. data/lib/earth/air/flight_domesticity/data_miner.rb +57 -0
  25. data/lib/earth/air/flight_fuel_type.rb +12 -0
  26. data/lib/earth/air/flight_fuel_type/data_miner.rb +12 -0
  27. data/lib/earth/air/flight_propulsion.rb +7 -0
  28. data/lib/earth/air/flight_propulsion/data_miner.rb +16 -0
  29. data/lib/earth/air/flight_seat_class.rb +12 -0
  30. data/lib/earth/air/flight_seat_class/data_miner.rb +36 -0
  31. data/lib/earth/air/flight_segment.rb +29 -0
  32. data/lib/earth/air/flight_segment/data_miner.rb +330 -0
  33. data/lib/earth/air/flight_service.rb +7 -0
  34. data/lib/earth/air/flight_service/data_miner.rb +16 -0
  35. data/lib/earth/all.rb +11 -0
  36. data/lib/earth/automobile.rb +8 -0
  37. data/lib/earth/automobile/automobile_fuel_type.rb +18 -0
  38. data/lib/earth/automobile/automobile_fuel_type/data_miner.rb +45 -0
  39. data/lib/earth/automobile/automobile_make.rb +14 -0
  40. data/lib/earth/automobile/automobile_make/data_miner.rb +68 -0
  41. data/lib/earth/automobile/automobile_make_fleet_year.rb +15 -0
  42. data/lib/earth/automobile/automobile_make_fleet_year/data_miner.rb +29 -0
  43. data/lib/earth/automobile/automobile_make_year.rb +14 -0
  44. data/lib/earth/automobile/automobile_make_year/data_miner.rb +45 -0
  45. data/lib/earth/automobile/automobile_model.rb +14 -0
  46. data/lib/earth/automobile/automobile_model/data_miner.rb +38 -0
  47. data/lib/earth/automobile/automobile_model_year.rb +15 -0
  48. data/lib/earth/automobile/automobile_model_year/data_miner.rb +51 -0
  49. data/lib/earth/automobile/automobile_size_class.rb +14 -0
  50. data/lib/earth/automobile/automobile_size_class/data_miner.rb +43 -0
  51. data/lib/earth/automobile/automobile_variant.rb +17 -0
  52. data/lib/earth/automobile/automobile_variant/data_miner.rb +460 -0
  53. data/lib/earth/automobile/data_miner.rb +8 -0
  54. data/lib/earth/base.rb +7 -0
  55. data/lib/earth/bus.rb +1 -0
  56. data/lib/earth/bus/bus_class.rb +19 -0
  57. data/lib/earth/bus/bus_class/data_miner.rb +41 -0
  58. data/lib/earth/bus/data_miner.rb +1 -0
  59. data/lib/earth/conversions_ext.rb +45 -0
  60. data/lib/earth/data_miner.rb +10 -0
  61. data/lib/earth/diet.rb +2 -0
  62. data/lib/earth/diet/data_miner.rb +2 -0
  63. data/lib/earth/diet/diet_class.rb +15 -0
  64. data/lib/earth/diet/diet_class/data_miner.rb +36 -0
  65. data/lib/earth/diet/food_group.rb +17 -0
  66. data/lib/earth/diet/food_group/data_miner.rb +26 -0
  67. data/lib/earth/fuel.rb +2 -0
  68. data/lib/earth/fuel/data_miner.rb +2 -0
  69. data/lib/earth/fuel/fuel_price.rb +13 -0
  70. data/lib/earth/fuel/fuel_price/data_miner.rb +20 -0
  71. data/lib/earth/fuel/fuel_type.rb +18 -0
  72. data/lib/earth/fuel/fuel_type/data_miner.rb +37 -0
  73. data/lib/earth/hospitality.rb +1 -0
  74. data/lib/earth/hospitality/data_miner.rb +1 -0
  75. data/lib/earth/hospitality/lodging_class.rb +9 -0
  76. data/lib/earth/hospitality/lodging_class/data_miner.rb +30 -0
  77. data/lib/earth/industry.rb +10 -0
  78. data/lib/earth/industry/industry.rb +23 -0
  79. data/lib/earth/industry/industry_product.rb +22 -0
  80. data/lib/earth/industry/industry_product_line.rb +20 -0
  81. data/lib/earth/industry/industry_sector.rb +20 -0
  82. data/lib/earth/industry/merchant.rb +18 -0
  83. data/lib/earth/industry/merchant_category.rb +22 -0
  84. data/lib/earth/industry/merchant_category_industry.rb +20 -0
  85. data/lib/earth/industry/product_line.rb +22 -0
  86. data/lib/earth/industry/product_line_industry_product.rb +20 -0
  87. data/lib/earth/industry/sector.rb +19 -0
  88. data/lib/earth/inflectors.rb +9 -0
  89. data/lib/earth/locality.rb +10 -0
  90. data/lib/earth/locality/census_division.rb +22 -0
  91. data/lib/earth/locality/census_division/data_miner.rb +64 -0
  92. data/lib/earth/locality/census_region.rb +13 -0
  93. data/lib/earth/locality/census_region/data_miner.rb +17 -0
  94. data/lib/earth/locality/climate_division.rb +17 -0
  95. data/lib/earth/locality/climate_division/data_miner.rb +20 -0
  96. data/lib/earth/locality/country.rb +13 -0
  97. data/lib/earth/locality/country/data_miner.rb +19 -0
  98. data/lib/earth/locality/data_miner.rb +10 -0
  99. data/lib/earth/locality/egrid_region.rb +15 -0
  100. data/lib/earth/locality/egrid_region/data_miner.rb +35 -0
  101. data/lib/earth/locality/egrid_subregion.rb +16 -0
  102. data/lib/earth/locality/egrid_subregion/data_miner.rb +65 -0
  103. data/lib/earth/locality/petroleum_administration_for_defense_district.rb +13 -0
  104. data/lib/earth/locality/petroleum_administration_for_defense_district/data_miner.rb +21 -0
  105. data/lib/earth/locality/state.rb +22 -0
  106. data/lib/earth/locality/state/data_miner.rb +37 -0
  107. data/lib/earth/locality/urbanity.rb +10 -0
  108. data/lib/earth/locality/urbanity/data_miner.rb +15 -0
  109. data/lib/earth/locality/zip_code.rb +23 -0
  110. data/lib/earth/locality/zip_code/data_miner.rb +43 -0
  111. data/lib/earth/pet.rb +4 -0
  112. data/lib/earth/pet/breed.rb +15 -0
  113. data/lib/earth/pet/breed/data_miner.rb +25 -0
  114. data/lib/earth/pet/breed_gender.rb +14 -0
  115. data/lib/earth/pet/breed_gender/data_miner.rb +21 -0
  116. data/lib/earth/pet/data_miner.rb +4 -0
  117. data/lib/earth/pet/gender.rb +10 -0
  118. data/lib/earth/pet/gender/data_miner.rb +13 -0
  119. data/lib/earth/pet/species.rb +40 -0
  120. data/lib/earth/pet/species/data_miner.rb +42 -0
  121. data/lib/earth/rail.rb +1 -0
  122. data/lib/earth/rail/data_miner.rb +1 -0
  123. data/lib/earth/rail/rail_class.rb +16 -0
  124. data/lib/earth/rail/rail_class/data_miner.rb +36 -0
  125. data/lib/earth/residence.rb +8 -0
  126. data/lib/earth/residence/air_conditioner_use.rb +13 -0
  127. data/lib/earth/residence/air_conditioner_use/data_miner.rb +22 -0
  128. data/lib/earth/residence/clothes_machine_use.rb +10 -0
  129. data/lib/earth/residence/clothes_machine_use/data_miner.rb +28 -0
  130. data/lib/earth/residence/data_miner.rb +8 -0
  131. data/lib/earth/residence/dishwasher_use.rb +10 -0
  132. data/lib/earth/residence/dishwasher_use/data_miner.rb +28 -0
  133. data/lib/earth/residence/residence_appliance.rb +16 -0
  134. data/lib/earth/residence/residence_appliance/data_miner.rb +20 -0
  135. data/lib/earth/residence/residence_class.rb +16 -0
  136. data/lib/earth/residence/residence_class/data_miner.rb +15 -0
  137. data/lib/earth/residence/residence_fuel_price.rb +18 -0
  138. data/lib/earth/residence/residence_fuel_price/data_miner.rb +200 -0
  139. data/lib/earth/residence/residence_fuel_type.rb +32 -0
  140. data/lib/earth/residence/residence_fuel_type/data_miner.rb +18 -0
  141. data/lib/earth/residence/residential_energy_consumption_survey_response.rb +39 -0
  142. data/lib/earth/residence/residential_energy_consumption_survey_response/data_miner.rb +283 -0
  143. data/spec/lib/earth_spec.rb +25 -0
  144. data/spec/spec_helper.rb +11 -0
  145. data/vendor/geokit-rails/CHANGELOG.rdoc +46 -0
  146. data/vendor/geokit-rails/MIT-LICENSE +20 -0
  147. data/vendor/geokit-rails/README.markdown +561 -0
  148. data/vendor/geokit-rails/Rakefile +18 -0
  149. data/vendor/geokit-rails/about.yml +9 -0
  150. data/vendor/geokit-rails/assets/api_keys_template +61 -0
  151. data/vendor/geokit-rails/init.rb +1 -0
  152. data/vendor/geokit-rails/install.rb +14 -0
  153. data/vendor/geokit-rails/lib/geokit-rails.rb +24 -0
  154. data/vendor/geokit-rails/lib/geokit-rails/acts_as_mappable.rb +456 -0
  155. data/vendor/geokit-rails/lib/geokit-rails/adapters/abstract.rb +31 -0
  156. data/vendor/geokit-rails/lib/geokit-rails/adapters/mysql.rb +22 -0
  157. data/vendor/geokit-rails/lib/geokit-rails/adapters/postgresql.rb +22 -0
  158. data/vendor/geokit-rails/lib/geokit-rails/adapters/sqlserver.rb +43 -0
  159. data/vendor/geokit-rails/lib/geokit-rails/defaults.rb +22 -0
  160. data/vendor/geokit-rails/lib/geokit-rails/geocoder_control.rb +16 -0
  161. data/vendor/geokit-rails/lib/geokit-rails/ip_geocode_lookup.rb +46 -0
  162. data/vendor/geokit-rails/test/acts_as_mappable_test.rb +474 -0
  163. data/vendor/geokit-rails/test/boot.rb +25 -0
  164. data/vendor/geokit-rails/test/database.yml +20 -0
  165. data/vendor/geokit-rails/test/fixtures/companies.yml +7 -0
  166. data/vendor/geokit-rails/test/fixtures/custom_locations.yml +54 -0
  167. data/vendor/geokit-rails/test/fixtures/locations.yml +54 -0
  168. data/vendor/geokit-rails/test/fixtures/mock_addresses.yml +17 -0
  169. data/vendor/geokit-rails/test/fixtures/mock_families.yml +2 -0
  170. data/vendor/geokit-rails/test/fixtures/mock_houses.yml +9 -0
  171. data/vendor/geokit-rails/test/fixtures/mock_organizations.yml +5 -0
  172. data/vendor/geokit-rails/test/fixtures/mock_people.yml +5 -0
  173. data/vendor/geokit-rails/test/fixtures/stores.yml +0 -0
  174. data/vendor/geokit-rails/test/ip_geocode_lookup_test.rb +77 -0
  175. data/vendor/geokit-rails/test/models/company.rb +3 -0
  176. data/vendor/geokit-rails/test/models/custom_location.rb +12 -0
  177. data/vendor/geokit-rails/test/models/location.rb +4 -0
  178. data/vendor/geokit-rails/test/models/mock_address.rb +4 -0
  179. data/vendor/geokit-rails/test/models/mock_family.rb +3 -0
  180. data/vendor/geokit-rails/test/models/mock_house.rb +3 -0
  181. data/vendor/geokit-rails/test/models/mock_organization.rb +4 -0
  182. data/vendor/geokit-rails/test/models/mock_person.rb +4 -0
  183. data/vendor/geokit-rails/test/models/store.rb +3 -0
  184. data/vendor/geokit-rails/test/schema.rb +60 -0
  185. data/vendor/geokit-rails/test/tasks.rake +31 -0
  186. data/vendor/geokit-rails/test/test_helper.rb +23 -0
  187. metadata +476 -0
@@ -0,0 +1,42 @@
1
+ Species.class_eval do
2
+ data_miner do
3
+ schema Earth.database_options do
4
+ string 'name'
5
+ integer 'population'
6
+ float 'diet_emission_intensity'
7
+ string 'diet_emission_intensity_units'
8
+ float 'weight'
9
+ string 'weight_units'
10
+ float 'marginal_dietary_requirement'
11
+ string 'marginal_dietary_requirement_units'
12
+ float 'fixed_dietary_requirement'
13
+ string 'fixed_dietary_requirement_units'
14
+ float 'minimum_weight'
15
+ string 'minimum_weight_units'
16
+ float 'maximum_weight'
17
+ string 'maximum_weight_units'
18
+ end
19
+
20
+ process "Define some unit conversions" do
21
+ # 1 (kilocalories per pound) = 9 224.14105 joules per kilogram
22
+ Conversions.register :kilocalories_per_pound, :joules_per_kilogram, 9_224.14105
23
+ # 1 (grams per kilocalories) = 2.39005736 × 10-7 kilograms per joules
24
+ Conversions.register :grams_per_kilocalorie, :kilograms_per_joule, 2.39005736e-7
25
+ # 1 joule = 0.000239005736 kilocalories
26
+ Conversions.register :joules, :kilocalories, 0.000239005736
27
+ end
28
+
29
+ import "a list of pet species weights, dietary requirements, and diet emissions intensities",
30
+ :url => 'http://static.brighterplanet.com/science/data/consumables/pets/species.csv' do
31
+ key 'name', :field_name => 'species'
32
+ store 'population'
33
+ store 'weight', :from_units => :pounds, :to_units => :kilograms
34
+ store 'marginal_dietary_requirement', :from_units => :kilocalories_per_pound, :to_units => :joules_per_kilogram
35
+ store 'fixed_dietary_requirement', :from_units => :kilocalories, :to_units => :joules
36
+ store 'diet_emission_intensity', :from_units => :grams_per_kilocalorie, :to_units => :kilograms_per_joule
37
+ store 'minimum_weight', :from_units => :pounds, :to_units => :kilograms
38
+ store 'maximum_weight', :from_units => :pounds, :to_units => :kilograms
39
+ end
40
+ end
41
+ end
42
+
data/lib/earth/rail.rb ADDED
@@ -0,0 +1 @@
1
+ require 'earth/rail/rail_class'
@@ -0,0 +1 @@
1
+ require 'earth/rail/rail_class/data_miner'
@@ -0,0 +1,16 @@
1
+ class RailClass < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :rail_trips
5
+
6
+ data_miner do
7
+ tap "Brighter Planet's rail class data", Earth.taps_server
8
+ end
9
+
10
+ # speed is missing
11
+ # https://brighterplanet.sifterapp.com/projects/30/issues/455
12
+ falls_back_on :passengers => 25.06,
13
+ :distance => 8.57.miles.to(:kilometres),
14
+ :diesel_intensity => 0.05.gallons_per_mile.to(:litres_per_kilometre),
15
+ :electricity_intensity => 8.89.miles.to(:kilometres)
16
+ end
@@ -0,0 +1,36 @@
1
+ RailClass.class_eval do
2
+ data_miner do
3
+ schema Earth.database_options do
4
+ string 'name'
5
+ float 'distance'
6
+ string 'distance_units'
7
+ float 'passengers'
8
+ float 'speed'
9
+ string 'speed_units'
10
+ float 'duration'
11
+ string 'duration_units'
12
+ float 'electricity_intensity'
13
+ string 'electricity_intensity_units'
14
+ float 'diesel_intensity'
15
+ string 'diesel_intensity_units'
16
+ string 'description'
17
+ end
18
+
19
+ process "Define some unit conversions" do
20
+ Conversions.register :gallons_per_mile, :litres_per_kilometre, 2.35214583
21
+ end
22
+
23
+ import "a list of rail classes and pre-calculated trip and fuel use characteristics",
24
+ :url => 'http://static.brighterplanet.com/science/data/transport/rail/rail_classes.csv' do
25
+ key 'name'
26
+ store 'description'
27
+ store 'distance', :from_units => :miles, :to_units => :kilometres
28
+ store 'speed', :from_units => :miles, :to_units => :kilometres
29
+ store 'duration'
30
+ store 'passengers'
31
+ store 'electricity_intensity', :field_name => 'electricity_per_vehicle_mile', :from_units => :miles, :to_units => :kilometres
32
+ store 'diesel_intensity', :field_name => 'diesel_per_vehicle_mile', :from_units => :gallons_per_mile, :to_units => :litres_per_kilometre
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,8 @@
1
+ require 'earth/residence/air_conditioner_use'
2
+ require 'earth/residence/clothes_machine_use'
3
+ require 'earth/residence/dishwasher_use'
4
+ require 'earth/residence/residence_appliance'
5
+ require 'earth/residence/residence_class'
6
+ require 'earth/residence/residence_fuel_price'
7
+ require 'earth/residence/residence_fuel_type'
8
+ require 'earth/residence/residential_energy_consumption_survey_response'
@@ -0,0 +1,13 @@
1
+ class AirConditionerUse < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :residences
5
+ has_many :residential_energy_consumption_survey_responses
6
+
7
+ falls_back_on :fugitive_emission => 0.102295.pounds_per_square_foot.to(:kilograms_per_square_metre), # https://brighterplanet.sifterapp.com/projects/30/issues/430
8
+ :fugitive_emission_units => 'kilograms_per_square_metre'
9
+
10
+ data_miner do
11
+ tap "Brighter Planet's sanitized flight service data", Earth.taps_server
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ AirConditionerUse.class_eval do
2
+ data_miner do
3
+ schema do
4
+ string 'name'
5
+ float 'fugitive_emission'
6
+ string 'fugitive_emission_units'
7
+ end
8
+
9
+ process "derive from ResidentialEnergyConsumptionSurveyResponse" do
10
+ ResidentialEnergyConsumptionSurveyResponse.run_data_miner!
11
+ connection.execute %{
12
+ INSERT IGNORE INTO air_conditioner_uses(name)
13
+ SELECT DISTINCT residential_energy_consumption_survey_responses.central_ac_use FROM residential_energy_consumption_survey_responses WHERE LENGTH(residential_energy_consumption_survey_responses.central_ac_use) > 0
14
+ }
15
+ end
16
+
17
+ import "Ian's precalculated fugitive emissions values", :url => 'http://spreadsheets.google.com/pub?key=ri_380yQZAqBKeqie_TECgg' do
18
+ key 'name', :field_name => 'air_conditioner_use_name'
19
+ store 'fugitive_emission', :units_field_name => 'unit', :to_units => :kilograms_per_square_metre
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ class ClothesMachineUse < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :residences
5
+ has_many :residential_energy_consumption_survey_responses
6
+
7
+ data_miner do
8
+ tap "Brighter Planet's sanitized clothes machine use data", Earth.taps_server
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ ClothesMachineUse.class_eval do
2
+ data_miner do
3
+ schema do
4
+ string 'name'
5
+ float 'annual_energy_from_electricity_for_clothes_driers'
6
+ string 'annual_energy_from_electricity_for_clothes_driers_units'
7
+ end
8
+
9
+ process "derive from ResidentialEnergyConsumptionSurveyResponse" do
10
+ ResidentialEnergyConsumptionSurveyResponse.run_data_miner!
11
+ connection.execute %{
12
+ INSERT IGNORE INTO clothes_machine_uses(name)
13
+ SELECT DISTINCT residential_energy_consumption_survey_responses.clothes_washer_use FROM residential_energy_consumption_survey_responses WHERE LENGTH(residential_energy_consumption_survey_responses.clothes_washer_use) > 0
14
+ }
15
+ end
16
+
17
+ # sabshere 5/20/10 weird that this uses cohort
18
+ process "precalculate annual energy use" do
19
+ find_in_batches do |batch|
20
+ batch.each do |record|
21
+ record.annual_energy_from_electricity_for_clothes_driers = ResidentialEnergyConsumptionSurveyResponse.big_cohort(:clothes_machine_use => record).weighted_average :annual_energy_from_electricity_for_clothes_driers
22
+ record.annual_energy_from_electricity_for_clothes_driers_units = 'joules'
23
+ record.save!
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ require 'earth/residence/air_conditioner_use/data_miner'
2
+ require 'earth/residence/clothes_machine_use/data_miner'
3
+ require 'earth/residence/dishwasher_use/data_miner'
4
+ require 'earth/residence/residence_appliance/data_miner'
5
+ require 'earth/residence/residence_class/data_miner'
6
+ require 'earth/residence/residence_fuel_price/data_miner'
7
+ require 'earth/residence/residence_fuel_type/data_miner'
8
+ require 'earth/residence/residential_energy_consumption_survey_response/data_miner'
@@ -0,0 +1,10 @@
1
+ class DishwasherUse < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :residences
5
+ has_many :residential_energy_consumption_survey_responses
6
+
7
+ data_miner do
8
+ tap "Brighter Planet's sanitized dishwasher use data", Earth.taps_server
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ DishwasherUse.class_eval do
2
+ data_miner do
3
+ schema do
4
+ string 'name'
5
+ float 'annual_energy_from_electricity_for_dishwashers'
6
+ string 'annual_energy_from_electricity_for_dishwashers_units'
7
+ end
8
+
9
+ process "derive from ResidentialEnergyConsumptionSurveyResponse" do
10
+ ResidentialEnergyConsumptionSurveyResponse.run_data_miner!
11
+ connection.execute %{
12
+ INSERT IGNORE INTO dishwasher_uses(name)
13
+ SELECT DISTINCT residential_energy_consumption_survey_responses.dishwasher_use_id FROM residential_energy_consumption_survey_responses WHERE LENGTH(residential_energy_consumption_survey_responses.dishwasher_use_id) > 0
14
+ }
15
+ end
16
+
17
+ # sabshere 5/25/10 weird that this uses cohort
18
+ process "precalculate annual energy" do
19
+ find_in_batches do |batch|
20
+ batch.each do |record|
21
+ record.annual_energy_from_electricity_for_dishwashers = ResidentialEnergyConsumptionSurveyResponse.big_cohort(:dishwasher_use => record).weighted_average :annual_energy_from_electricity_for_dishwashers
22
+ record.annual_energy_from_electricity_for_dishwashers_units = 'joules'
23
+ record.save!
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ class ResidenceAppliance < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ class << self
5
+ def annual_energy_from_electricity_for(appliance_plural)
6
+ appliance_name = appliance_plural.to_s.singularize
7
+ if appliance = find_by_name(appliance_name)
8
+ appliance.annual_energy_from_electricity
9
+ end
10
+ end
11
+ end
12
+
13
+ data_miner do
14
+ tap "Brighter Planet's residence appliance energy information", Earth.taps_server
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ ResidenceAppliance.class_eval do
2
+ data_miner do
3
+ schema Earth.database_options do
4
+ string 'name'
5
+ float 'annual_energy_from_electricity'
6
+ string 'annual_energy_from_electricity_units'
7
+ end
8
+
9
+ process "Derive from residential energy consumption survey responses" do
10
+ ResidentialEnergyConsumptionSurveyResponse.run_data_miner!
11
+ ResidentialEnergyConsumptionSurveyResponse.column_names.grep(/_count$/).each do |column_name|
12
+ appliance_name = column_name.sub '_count', ''
13
+ appliance = find_or_create_by_name appliance_name
14
+ appliance.annual_energy_from_electricity = ResidentialEnergyConsumptionSurveyResponse.weighted_average "annual_energy_from_electricity_for_#{appliance_name.pluralize}"
15
+ appliance.save!
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,16 @@
1
+ class ResidenceClass < ActiveRecord::Base
2
+ set_primary_key :name
3
+
4
+ has_many :residences
5
+ has_many :residential_energy_consumption_survey_responses
6
+
7
+ CLASSIFICATIONS = ['mobile home', 'house', 'apartment']
8
+
9
+ def classification
10
+ CLASSIFICATIONS.detect { |c| name.downcase.include? c }
11
+ end
12
+
13
+ data_miner do
14
+ tap "Brighter Planet's sanitized residence class data", Earth.taps_server
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ ResidenceClass.class_eval do
2
+ data_miner do
3
+ schema do
4
+ string :name
5
+ end
6
+
7
+ process "derive from ResidentialEnergyConsumptionSurveyResponse" do
8
+ ResidentialEnergyConsumptionSurveyResponse.run_data_miner!
9
+ connection.execute %{
10
+ INSERT IGNORE INTO residence_classes(name)
11
+ SELECT DISTINCT residential_energy_consumption_survey_responses.residence_class_id FROM residential_energy_consumption_survey_responses WHERE LENGTH(residential_energy_consumption_survey_responses.residence_class_id) > 0
12
+ }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ class ResidenceFuelPrice < ActiveRecord::Base
2
+ set_primary_key :row_hash
3
+
4
+ extend CohortScope
5
+ self.minimum_cohort_size = 5 # ? FIXME
6
+
7
+ belongs_to :fuel, :class_name => 'ResidenceFuelType', :foreign_key => 'residence_fuel_type_name'
8
+ belongs_to :locatable, :polymorphic => true
9
+
10
+ data_miner do
11
+ tap "Brighter Planet's residence fuel price data", Earth.taps_server
12
+
13
+ process "pull dependencies" do
14
+ run_data_miner_on_belongs_to_associations
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,200 @@
1
+ ResidenceFuelPrice.class_eval do
2
+ class FuelOilParser
3
+ def initialize(options = {})
4
+ # nothing
5
+ end
6
+ def add_hints!(bus)
7
+ bus[:sheet] = 'Data 1'
8
+ bus[:skip] = 2
9
+ bus[:select] = lambda { |row| row['year'].to_i > 1989 }
10
+ end
11
+ def apply(row)
12
+ virtual_rows = []
13
+ row.keys.grep(/(.*) Residual Fuel Oil/) do |location_column_name|
14
+ match_1 = $1
15
+ next if (price = row[location_column_name]).blank? or (date = row['Date']).blank?
16
+ if match_1.starts_with?('U.S.')
17
+ locatable_id = 'US'
18
+ locatable_type = 'Country'
19
+ elsif match_1.include?('PADD')
20
+ /\(PADD (.*)\)/.match match_1
21
+ match_2 = $1
22
+ next if match_2 == '1' # skip PADD 1 because we always prefer subdistricts
23
+ locatable_id = match_2
24
+ locatable_type = 'PetroleumAdministrationForDefenseDistrict'
25
+ else
26
+ locatable_id = match_1
27
+ locatable_type = 'State'
28
+ end
29
+ date = Time.parse(date)
30
+ new_row = ActiveSupport::OrderedHash.new
31
+ new_row['locatable_id'] = locatable_id
32
+ new_row['locatable_type'] = locatable_type
33
+ new_row['price'] = price.to_f.cents.to(:dollars)
34
+ new_row['year'] = date.year
35
+ new_row['month'] = date.month
36
+ row_hash = RemoteTable::Transform.row_hash new_row
37
+ new_row['row_hash'] = row_hash
38
+ virtual_rows << new_row
39
+ end
40
+ virtual_rows
41
+ end
42
+ end
43
+
44
+ class PropaneParser
45
+ def initialize(options = {})
46
+ # nothing
47
+ end
48
+ def add_hints!(bus)
49
+ bus[:sheet] = 'Data 1'
50
+ bus[:skip] = 2
51
+ bus[:select] = lambda { |row| row['year'].to_i > 1989 }
52
+ end
53
+ def apply(row)
54
+ virtual_rows = []
55
+ row.keys.grep(/(.*) Propane Residential Price/) do |location_column_name|
56
+ match_1 = $1
57
+ next if (price = row[location_column_name]).blank? or (date = row['Date']).blank?
58
+ if match_1.starts_with?('U.S.')
59
+ locatable_id = 'US'
60
+ locatable_type = 'Country'
61
+ else
62
+ /\(PADD (.*)\)/.match match_1
63
+ match_2 = $1
64
+ next if match_2 == '1' # skip PADD 1 because we always prefer subdistricts
65
+ locatable_id = match_2
66
+ locatable_type = 'PetroleumAdministrationForDefenseDistrict'
67
+ end
68
+ date = Time.parse(date)
69
+ new_row = ActiveSupport::OrderedHash.new
70
+ new_row['locatable_id'] = locatable_id
71
+ new_row['locatable_type'] = locatable_type
72
+ new_row['price'] = price.to_f.cents.to(:dollars)
73
+ new_row['year'] = date.year
74
+ new_row['month'] = date.month
75
+ row_hash = RemoteTable::Transform.row_hash new_row
76
+ new_row['row_hash'] = row_hash
77
+ virtual_rows << new_row
78
+ end
79
+ virtual_rows
80
+ end
81
+ end
82
+
83
+ class NaturalGasParser
84
+ def initialize(options = {})
85
+ # nothing
86
+ end
87
+ def add_hints!(bus)
88
+ bus[:sheet] = 'Data 1'
89
+ bus[:skip] = 2
90
+ bus[:select] = lambda { |row| row['year'].to_i > 1989 }
91
+ end
92
+ def apply(row)
93
+ virtual_rows = []
94
+ row.keys.grep(/\A(.*) Natural Gas/) do |location_column_name|
95
+ match_1 = $1
96
+ next if (price = row[location_column_name]).blank? or (date = row['Date']).blank?
97
+ if match_1 == 'U.S.'
98
+ locatable_id = 'US'
99
+ locatable_type = 'Country'
100
+ else
101
+ locatable_id = match_1 # name
102
+ locatable_type = 'State'
103
+ end
104
+ date = Time.parse(date)
105
+ new_row = ActiveSupport::OrderedHash.new
106
+ new_row['locatable_id'] = locatable_id
107
+ new_row['locatable_type'] = locatable_type
108
+ new_row['price'] = price
109
+ new_row['year'] = date.year
110
+ new_row['month'] = date.month
111
+ row_hash = RemoteTable::Transform.row_hash new_row
112
+ new_row['row_hash'] = row_hash
113
+ virtual_rows << new_row
114
+ end
115
+ virtual_rows
116
+ end
117
+ end
118
+
119
+ data_miner do
120
+ schema Earth.database_options do
121
+ string 'row_hash'
122
+ string 'residence_fuel_type_name'
123
+ integer 'year'
124
+ integer 'month'
125
+ float 'price'
126
+ string 'price_units'
127
+ string 'price_description'
128
+ string 'locatable_id'
129
+ string 'locatable_type'
130
+ index ['price', 'residence_fuel_type_name', 'month', 'year', 'locatable_type', 'locatable_id']
131
+ index ['price', 'residence_fuel_type_name']
132
+ end
133
+
134
+ process "Define some unit conversions" do
135
+ Conversions.register :dollars, :cents, 100
136
+ Conversions.register :cubic_feet, :cubic_metres, 0.0283168466 # TODO conversions gem has 'cubic_metres'
137
+ end
138
+
139
+ # electricity in dollars per kWh
140
+ import 'residential electricity prices from the EIA',
141
+ :url => 'http://www.eia.doe.gov/cneaf/electricity/page/sales_revenue.xls',
142
+ :select => lambda { |row| row['Year'].to_s.first(4).to_i > 1989 } do
143
+ key 'row_hash'
144
+ store 'residence_fuel_type_name', :static => 'electricity'
145
+ store 'locatable_id', :field_name => 'State' # postal abbrev
146
+ store 'locatable_type', :static => 'State'
147
+ store 'price', :field_name => 'Average Retail Price Residential (c/kWh)', :from_units => :cents, :to_units => :dollars
148
+ store 'price_description', :static => 'dollars_per_kilowatt_hour'
149
+ store 'year', :field_name => 'Year'
150
+ store 'month', :field_name => 'Month'
151
+ end
152
+
153
+ # natural gas in dollars per cubic metre
154
+ # breaks if date-performance is enabled because DateTime.parse(...1899...) dies
155
+ import 'residential natural gas prices from the EIA',
156
+ :url => 'http://tonto.eia.doe.gov/dnav/ng/xls/ng_pri_sum_a_EPG0_FWA_DMcf_a.xls',
157
+ :transform => { :class => NaturalGasParser } do
158
+ key 'row_hash'
159
+ store 'residence_fuel_type_name', :static => 'natural gas'
160
+ store 'locatable_id'
161
+ store 'locatable_type'
162
+ store 'price', :from_units => :cubic_metres, :to_units => :cubic_feet # denominator
163
+ store 'price_description', :static => 'dollars_per_cubic_metre'
164
+ store 'year'
165
+ store 'month'
166
+ end
167
+
168
+ # dollars per litre
169
+ import "residential fuel oil prices from the EIA",
170
+ :url => 'http://tonto.eia.doe.gov/dnav/pet/xls/PET_PRI_RESID_A_EPPR_PTA_CPGAL_M.xls',
171
+ :transform => { :class => FuelOilParser } do
172
+ key 'row_hash'
173
+ store 'residence_fuel_type_name', :static => 'fuel oil'
174
+ store 'locatable_id'
175
+ store 'locatable_type'
176
+ store 'price', :from_units => :litres, :to_units => :gallons # denominator
177
+ store 'price_description', :static => 'dollars_per_litre'
178
+ store 'year'
179
+ store 'month'
180
+ end
181
+
182
+ # dollars per litre
183
+ import "residential propane prices from the EIA",
184
+ :url => 'http://tonto.eia.doe.gov/dnav/pet/xls/PET_PRI_PROP_A_EPLLPA_PRT_CPGAL_M.xls',
185
+ :transform => { :class => PropaneParser } do
186
+ key 'row_hash'
187
+ store 'residence_fuel_type_name', :static => 'propane'
188
+ store 'locatable_id'
189
+ store 'locatable_type'
190
+ store 'price', :from_units => :litres, :to_units => :gallons # denominator
191
+ store 'price_description', :static => 'dollars_per_litre'
192
+ store 'year'
193
+ store 'month'
194
+ end
195
+
196
+ # per Matt in https://brighterplanet.sifterapp.com/projects/30/issues/410/comments
197
+ # "For coal and kerosene, there isn't good residential price data available, because hardly anybody actually uses them residentially."
198
+ end
199
+ end
200
+