earth 0.11.20 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. data/data/automobile/annual_emission_controls.csv +143 -0
  2. data/data/automobile/annual_fuel_consumption.csv +81 -0
  3. data/data/automobile/annual_sizes.csv +541 -0
  4. data/data/automobile/auto_fuel_data.csv +13 -0
  5. data/data/automobile/auto_fuel_efs.csv +9 -0
  6. data/data/automobile/cafe_data.csv +1449 -0
  7. data/data/automobile/emission_control_techs.csv +21 -0
  8. data/data/automobile/hfc_emissions.csv +31 -0
  9. data/data/automobile/hybridity_multipliers.csv +8 -0
  10. data/data/automobile/sizes.csv +16 -0
  11. data/earth.gemspec +3 -2
  12. data/errata/aircraft/faa_errata.csv +1 -1
  13. data/errata/airline/bts_carrier_codes_errata.csv +44 -0
  14. data/errata/airport/openflights_errata.csv +450 -1
  15. data/errata/automobile_make_model_year_variant/feg_errata.csv +363 -1
  16. data/errata/automobile_make_year_fleet/cafe_errata.csv +69 -1
  17. data/errata/bts_aircraft/bts_errata.csv +1 -1
  18. data/errata/country/wri_errata.csv +1 -1
  19. data/errata/electricity/electric_market/nrel_errata.csv +13 -1
  20. data/errata/electricity/electric_utility/eia_errata.csv +18 -1
  21. data/errata/flight_segment/bts_errata.csv +4 -1
  22. data/lib/earth.rb +1 -0
  23. data/lib/earth/acronyms.rb +12 -0
  24. data/lib/earth/air/aircraft.rb +16 -0
  25. data/lib/earth/air/airline.rb +3 -0
  26. data/lib/earth/air/airline/data_miner.rb +18 -3
  27. data/lib/earth/air/airport.rb +2 -0
  28. data/lib/earth/air/bts_aircraft.rb +2 -0
  29. data/lib/earth/air/flight_distance_class.rb +2 -0
  30. data/lib/earth/air/flight_distance_class_seat_class.rb +2 -0
  31. data/lib/earth/air/flight_seat_class.rb +2 -0
  32. data/lib/earth/air/flight_segment.rb +10 -0
  33. data/lib/earth/air/flight_segment/data_miner.rb +10 -13
  34. data/lib/earth/automobile/automobile_activity_year.rb +21 -0
  35. data/lib/earth/automobile/automobile_activity_year/data_miner.rb +27 -0
  36. data/lib/earth/automobile/automobile_activity_year_type.rb +27 -0
  37. data/lib/earth/automobile/automobile_activity_year_type/data_miner.rb +27 -0
  38. data/lib/earth/automobile/automobile_activity_year_type_fuel.rb +19 -0
  39. data/lib/earth/automobile/automobile_activity_year_type_fuel/data_miner.rb +57 -0
  40. data/lib/earth/automobile/automobile_fuel.rb +93 -86
  41. data/lib/earth/automobile/automobile_fuel/data_miner.rb +64 -70
  42. data/lib/earth/automobile/automobile_make.rb +5 -1
  43. data/lib/earth/automobile/automobile_make/data_miner.rb +10 -37
  44. data/lib/earth/automobile/automobile_make_model.rb +22 -3
  45. data/lib/earth/automobile/automobile_make_model/data_miner.rb +41 -15
  46. data/lib/earth/automobile/automobile_make_model_year.rb +18 -7
  47. data/lib/earth/automobile/automobile_make_model_year/data_miner.rb +43 -27
  48. data/lib/earth/automobile/automobile_make_model_year_variant.rb +44 -8
  49. data/lib/earth/automobile/automobile_make_model_year_variant/data_miner.rb +182 -8
  50. data/lib/earth/automobile/automobile_make_year.rb +4 -2
  51. data/lib/earth/automobile/automobile_make_year/data_miner.rb +16 -15
  52. data/lib/earth/automobile/automobile_make_year_fleet.rb +2 -1
  53. data/lib/earth/automobile/automobile_make_year_fleet/data_miner.rb +5 -2
  54. data/lib/earth/automobile/automobile_model.rb +2 -1
  55. data/lib/earth/automobile/automobile_model/data_miner.rb +1 -2
  56. data/lib/earth/automobile/automobile_size_class.rb +7 -68
  57. data/lib/earth/automobile/automobile_size_class/data_miner.rb +16 -51
  58. data/lib/earth/automobile/automobile_type_fuel.rb +23 -0
  59. data/lib/earth/automobile/automobile_type_fuel/data_miner.rb +52 -0
  60. data/lib/earth/automobile/automobile_type_fuel_control.rb +2 -33
  61. data/lib/earth/automobile/automobile_type_fuel_control/data_miner.rb +19 -4
  62. data/lib/earth/automobile/automobile_type_fuel_year.rb +17 -54
  63. data/lib/earth/automobile/automobile_type_fuel_year/data_miner.rb +40 -94
  64. data/lib/earth/automobile/automobile_type_fuel_year_control.rb +25 -23
  65. data/lib/earth/automobile/automobile_type_fuel_year_control/data_miner.rb +6 -2
  66. data/lib/earth/automobile/automobile_year.rb +38 -1
  67. data/lib/earth/automobile/automobile_year/data_miner.rb +1 -2
  68. data/lib/earth/automobile/dependencies.txt +22 -36
  69. data/lib/earth/bus/bus_class.rb +2 -0
  70. data/lib/earth/bus/bus_fuel.rb +2 -0
  71. data/lib/earth/bus/bus_fuel_control.rb +2 -0
  72. data/lib/earth/bus/bus_fuel_year_control.rb +2 -0
  73. data/lib/earth/computation/computation_carrier.rb +2 -0
  74. data/lib/earth/computation/computation_carrier_instance_class.rb +2 -0
  75. data/lib/earth/computation/computation_carrier_region.rb +2 -0
  76. data/lib/earth/conversions_ext.rb +6 -0
  77. data/lib/earth/diet/diet_class.rb +2 -0
  78. data/lib/earth/diet/food_group.rb +2 -0
  79. data/lib/earth/fuel/fuel.rb +2 -0
  80. data/lib/earth/fuel/fuel/data_miner.rb +15 -0
  81. data/lib/earth/fuel/fuel_price.rb +2 -0
  82. data/lib/earth/fuel/fuel_type.rb +2 -0
  83. data/lib/earth/fuel/fuel_year.rb +2 -0
  84. data/lib/earth/fuel/greenhouse_gas.rb +2 -0
  85. data/lib/earth/hospitality/commercial_building_energy_consumption_survey_response/data_miner.rb +7 -7
  86. data/lib/earth/hospitality/lodging_class.rb +2 -0
  87. data/lib/earth/industry/industry.rb +2 -0
  88. data/lib/earth/industry/mecs_energy/data_miner.rb +1 -1
  89. data/lib/earth/industry/mecs_ratio/data_miner.rb +1 -1
  90. data/lib/earth/locality/census_division.rb +2 -0
  91. data/lib/earth/locality/census_region.rb +2 -0
  92. data/lib/earth/locality/climate_division.rb +2 -0
  93. data/lib/earth/locality/country.rb +4 -0
  94. data/lib/earth/locality/egrid_region.rb +3 -0
  95. data/lib/earth/locality/egrid_subregion.rb +2 -0
  96. data/lib/earth/locality/petroleum_administration_for_defense_district.rb +7 -0
  97. data/lib/earth/locality/state.rb +7 -0
  98. data/lib/earth/locality/zip_code.rb +4 -0
  99. data/lib/earth/pet/breed.rb +7 -0
  100. data/lib/earth/pet/breed/data_miner.rb +1 -1
  101. data/lib/earth/pet/breed_gender.rb +2 -0
  102. data/lib/earth/pet/gender.rb +2 -0
  103. data/lib/earth/pet/species.rb +2 -0
  104. data/lib/earth/rail/country_rail_class.rb +2 -0
  105. data/lib/earth/rail/country_rail_traction.rb +2 -0
  106. data/lib/earth/rail/country_rail_traction_class.rb +2 -0
  107. data/lib/earth/rail/national_transit_database_company.rb +7 -0
  108. data/lib/earth/rail/national_transit_database_mode.rb +2 -0
  109. data/lib/earth/rail/national_transit_database_record.rb +22 -0
  110. data/lib/earth/rail/rail_class.rb +2 -0
  111. data/lib/earth/rail/rail_company.rb +16 -0
  112. data/lib/earth/rail/rail_fuel.rb +2 -0
  113. data/lib/earth/rail/rail_traction.rb +2 -0
  114. data/lib/earth/residence/air_conditioner_use.rb +2 -0
  115. data/lib/earth/residence/clothes_machine_use.rb +2 -0
  116. data/lib/earth/residence/dishwasher_use.rb +2 -0
  117. data/lib/earth/residence/residence_appliance.rb +2 -0
  118. data/lib/earth/residence/residence_class.rb +2 -0
  119. data/lib/earth/residence/residence_fuel_price.rb +2 -0
  120. data/lib/earth/residence/residence_fuel_type.rb +2 -0
  121. data/lib/earth/residence/residential_energy_consumption_survey_response.rb +2 -0
  122. data/lib/earth/residence/urbanity.rb +2 -0
  123. data/lib/earth/shipping/carrier.rb +2 -0
  124. data/lib/earth/shipping/carrier_mode.rb +2 -0
  125. data/lib/earth/shipping/shipment_mode.rb +2 -0
  126. data/lib/earth/version.rb +1 -1
  127. data/spec/earth/air/airline_spec.rb +20 -0
  128. data/spec/earth/air/flight_segment_spec.rb +9 -4
  129. data/spec/earth/automobile/automobile_activity_year_spec.rb +30 -0
  130. data/spec/earth/automobile/automobile_activity_year_type_fuel_spec.rb +25 -0
  131. data/spec/earth/automobile/automobile_activity_year_type_spec.rb +38 -0
  132. data/spec/earth/automobile/automobile_fuel_spec.rb +91 -6
  133. data/spec/earth/automobile/automobile_make_model_spec.rb +74 -0
  134. data/spec/earth/automobile/automobile_make_model_year_spec.rb +90 -0
  135. data/spec/earth/automobile/automobile_make_model_year_variant_spec.rb +139 -90
  136. data/spec/earth/automobile/automobile_make_spec.rb +27 -0
  137. data/spec/earth/automobile/automobile_make_year_fleet_spec.rb +8 -21
  138. data/spec/earth/automobile/automobile_make_year_spec.rb +28 -0
  139. data/spec/earth/automobile/automobile_model_spec.rb +15 -0
  140. data/spec/earth/automobile/automobile_size_class_spec.rb +31 -0
  141. data/spec/earth/automobile/automobile_type_fuel_control_spec.rb +25 -0
  142. data/spec/earth/automobile/automobile_type_fuel_spec.rb +45 -0
  143. data/spec/earth/automobile/automobile_type_fuel_year_control_spec.rb +51 -0
  144. data/spec/earth/automobile/automobile_type_fuel_year_spec.rb +65 -0
  145. data/spec/earth/automobile/automobile_year_spec.rb +23 -0
  146. data/spec/earth/fuel/fuel_spec.rb +1 -1
  147. data/spec/earth/hospitality/commercial_building_energy_consumption_survey_response_spec.rb +11 -3
  148. data/spec/earth_spec.rb +3 -3
  149. data/spec/spec_helper.rb +1 -0
  150. metadata +78 -25
  151. data/lib/earth/automobile/automobile_size_class_year.rb +0 -44
  152. data/lib/earth/automobile/automobile_size_class_year/data_miner.rb +0 -18
  153. data/lib/earth/automobile/automobile_type_fuel_year_age.rb +0 -68
  154. data/lib/earth/automobile/automobile_type_fuel_year_age/data_miner.rb +0 -116
  155. data/lib/earth/automobile/automobile_type_year.rb +0 -58
  156. data/lib/earth/automobile/automobile_type_year/data_miner.rb +0 -30
  157. data/spec/earth/automobile/automobile_type_fuel_year_age_spec.rb +0 -20
@@ -1 +1,18 @@
1
- date,name,email,type,section,action,x,y,condition,notes
1
+ date,name,email,type,section,action,x,y,condition,notes
2
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,meta,Intended use,,EIA form 861
3
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,UTILITY_ID,reject,88888,,,Withheld
4
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,MAIL_STATE,delete,/^CN$/i,,,Canada is not a US state
5
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^AK$/i,ASCC,,ASCC is the alaska NERC region
6
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^ECAR$/i,RFC,,now part of RFC
7
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^ERCOT$/i,TRE,,now called TRE
8
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^Gateway$/i,SERC,,assume this is SERC based on utility location
9
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^GustavusAK$/i,ASCC,,ASCC is the alaska NERC region
10
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^HI$/i,HICC,,HICC is the hawaii NERC region
11
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^MAAC$/i,RFC,,now part of RFC
12
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^MAIN$/i,RFC,,assume this is SERC based on utility location
13
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,MAPP,MRO,,assume this is MRO based on utility location
14
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^MISO$/i,MRO,,assume this is MRO based on utility location
15
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^RFO$/i,RFC,,assume this is typo based on utility location
16
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^SSP$/i,SPP,,assume this is typo based on utility location
17
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^TX$/i,TRE,,assume that TX means TRE rather than one of the NERC regions that makes up a tiny part of texas
18
+ 5/12/12,Ian Hough,myfirstname@brighterplanet.com,technical,NERC_LOCATION,replace,/^WSCC$/i,WECC,,assume this is typo based on utility location
@@ -1 +1,4 @@
1
- date,name,email,type,section,action,x,y,condition,notes
1
+ date,name,email,type,section,action,x,y,condition,notes
2
+ 6/7/11,Ian Hough,ian@brighterplanet.com,meta,Intended use,,http://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=293
3
+ 6/7/11,Ian Hough,ian@brighterplanet.com,technical,UNIQUE_CARRIER,replace,/^$/i,0OQ,in may 2009,unique carrier code for OpenSkies is missing in May 2009
4
+ 6/7/11,Ian Hough,ian@brighterplanet.com,technical,UNIQUE_CARRIER,replace,/^$/i,0OQ,in july 2009,unique carrier code for OpenSkies is missing in July 2009
data/lib/earth.rb CHANGED
@@ -19,6 +19,7 @@ module Earth
19
19
  TAPS_DESCRIPTION = "Brighter Planet's reference data web service"
20
20
  VENDOR_DIR = ::File.expand_path '../../vendor', __FILE__
21
21
  LIB_DIR = ::File.expand_path '../earth', __FILE__
22
+ DATA_DIR = ::File.expand_path '../../data', __FILE__
22
23
  ERRATA_DIR = ::File.expand_path '../../errata', __FILE__
23
24
 
24
25
  def Earth.domains
@@ -0,0 +1,12 @@
1
+ AMMYV = AutomobileMakeModelYearVariant if defined? AutomobileMakeModelYearVariant
2
+ AMMY = AutomobileMakeModelYear if defined? AutomobileMakeModelYear
3
+ AMM = AutomobileMakeModel if defined? AutomobileMakeModel
4
+ AMYF = AutomobileMakeYearFleet if defined? AutomobileMakeYearFleet
5
+ AMY = AutomobileMakeYear if defined? AutomobileMakeYear
6
+ ATFYC = AutomobileTypeFuelYearControl if defined? AutomobileTypeFuelYearControl
7
+ ATFY = AutomobileTypeFuelYear if defined? AutomobileTypeFuelYear
8
+ ATFC = AutomobileTypeFuelControl if defined? AutomobileTypeFuelControl
9
+ ATFA = AutomobileTypeFuelAge if defined? AutomobileTypeFuelAge
10
+ AAYTF = AutomobileActivityYearTypeFuel if defined? AutomobileActivityYearTypeFuel
11
+ AAYT = AutomobileActivityYearType if defined? AutomobileActivityYearType
12
+ AAY = AutomobileActivityYear if defined? AutomobileActivityYear
@@ -143,4 +143,20 @@ class Aircraft < ActiveRecord::Base
143
143
  col :b, :type => :float
144
144
  col :b_units
145
145
  col :fuel_use_specificity
146
+
147
+ warn_if_nulls_except(
148
+ :seats,
149
+ :seats_specificity,
150
+ :m3,
151
+ :m3_units,
152
+ :m2,
153
+ :m2_units,
154
+ :m1,
155
+ :m1_units,
156
+ :b,
157
+ :b_units,
158
+ :fuel_use_specificity,
159
+ )
160
+
161
+ warn_unless_size 437
146
162
  end
@@ -2,7 +2,10 @@ class Airline < ActiveRecord::Base
2
2
  self.primary_key = "name"
3
3
 
4
4
  col :name
5
+ col :secondary_name
5
6
  col :bts_code
6
7
  col :iata_code
7
8
  col :icao_code
9
+
10
+ warn_unless_size 504
8
11
  end
@@ -1,15 +1,30 @@
1
1
  Airline.class_eval do
2
+ # for errata
3
+ class Airline::Guru
4
+ def not_expressjet?(row)
5
+ not row['Description'] =~ /expressjet/i
6
+ end
7
+ end
8
+
2
9
  data_miner do
3
10
  process "Start from scratch" do
4
11
  delete_all
5
12
  end
6
13
 
14
+ import "the BTS unique carrier code lookup table",
15
+ :url => 'http://www.transtats.bts.gov/Download_Lookup.asp?Lookup=L_UNIQUE_CARRIERS',
16
+ :errata => { :url => "file://#{Earth::ERRATA_DIR}/airline/bts_carrier_codes_errata.csv", :responder => 'Airline::Guru' } do
17
+ key 'name', :synthesize => proc { |row| row['Description'].split("|")[0] }
18
+ store 'secondary_name', :synthesize => proc { |row| row['Description'].split("|")[1] }
19
+ store 'bts_code', :field_name => 'Code'
20
+ end
21
+
7
22
  import "a Brighter Planet-curated list of airlines and codes not included in our proprietary sources",
8
23
  :url => 'https://spreadsheets.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdGJoaFpENXRqMEM2NW42am5tNURGU2c&output=csv' do
9
24
  key 'name'
10
- store 'bts_code', :nullify => true
11
- store 'iata_code', :nullify => true
12
- store 'icao_code', :nullify => true
25
+ store 'secondary_name', :nullify => true
26
+ store 'iata_code', :nullify => true
27
+ store 'icao_code', :nullify => true
13
28
  end
14
29
  end
15
30
  end
@@ -17,4 +17,6 @@ class Airport < ActiveRecord::Base
17
17
  col :country_iso_3166_code
18
18
  col :latitude, :type => :float
19
19
  col :longitude, :type => :float
20
+
21
+ warn_unless_size 5149
20
22
  end
@@ -2,4 +2,6 @@ class BtsAircraft < ActiveRecord::Base
2
2
  self.primary_key = "bts_code"
3
3
  col :bts_code
4
4
  col :description
5
+
6
+ warn_unless_size 376
5
7
  end
@@ -12,4 +12,6 @@ class FlightDistanceClass < ActiveRecord::Base
12
12
  col :min_distance_units
13
13
  col :max_distance, :type => :float
14
14
  col :max_distance_units
15
+
16
+ warn_unless_size 2
15
17
  end
@@ -11,4 +11,6 @@ class FlightDistanceClassSeatClass < ActiveRecord::Base
11
11
  col :distance_class_name
12
12
  col :seat_class_name
13
13
  col :multiplier, :type => :float
14
+
15
+ warn_unless_size 7
14
16
  end
@@ -2,4 +2,6 @@ class FlightSeatClass < ActiveRecord::Base
2
2
  self.primary_key = "name"
3
3
 
4
4
  col :name
5
+
6
+ warn_unless_size 4
5
7
  end
@@ -75,4 +75,14 @@ class FlightSegment < ActiveRecord::Base
75
75
  add_index :aircraft_bts_code
76
76
  add_index :aircraft_description
77
77
  add_index :year
78
+
79
+ warn_if_nulls_except(
80
+ :origin_airport_city,
81
+ :destination_airport_city,
82
+ :airline_icao_code,
83
+ :load_factor,
84
+ :freight_share
85
+ )
86
+
87
+ warn_unless_size 966913
78
88
  end
@@ -1,3 +1,4 @@
1
+ require 'timeframe'
1
2
  require 'earth/locality/data_miner'
2
3
 
3
4
  FlightSegment.class_eval do
@@ -167,26 +168,22 @@ FlightSegment.class_eval do
167
168
  VarType=Char
168
169
  }.gsub /[\s]+/,''
169
170
 
170
- def self.form_data_per_month(year_range)
171
- months = {}
172
- year_range.each do |year|
173
- (1..12).each do |month|
174
- time = ::Time.gm year, month
175
- form_data = FORM_DATA.dup
176
- form_data.gsub! '__YEAR__', time.year.to_s
177
- form_data.gsub! '__MONTH_NUMBER__', time.month.to_s
178
- form_data.gsub! '__MONTH_NAME__', time.strftime('%B')
179
- months[time] = form_data
180
- end
171
+ def self.form_data_per_month
172
+ Timeframe.new(Date.parse('2009-01-01'), Date.today).first_days_of_months.inject({}) do |memo, day|
173
+ form_data = FORM_DATA.dup
174
+ form_data.gsub! '__YEAR__', day.year.to_s
175
+ form_data.gsub! '__MONTH_NUMBER__', day.month.to_s
176
+ form_data.gsub! '__MONTH_NAME__', day.strftime('%B')
177
+ memo[day] = form_data
178
+ memo
181
179
  end
182
- months
183
180
  end
184
181
 
185
182
  data_miner do
186
183
  process "Start from scratch" do
187
184
  delete_all
188
185
  end
189
- FlightSegment.form_data_per_month(2009..::Time.now.year).each do |month, form_data|
186
+ FlightSegment.form_data_per_month.each do |month, form_data|
190
187
  import "T100 flight segment data for #{month.strftime('%B %Y')}",
191
188
  :url => URL,
192
189
  :form_data => form_data,
@@ -0,0 +1,21 @@
1
+ class AutomobileActivityYear < ActiveRecord::Base
2
+ self.primary_key = "activity_year"
3
+
4
+ # for calculating hfc ef
5
+ has_many :activity_year_types, :foreign_key => :activity_year, :primary_key => :activity_year, :class_name => 'AutomobileActivityYearType'
6
+
7
+ # Used by Automobile and AutomobileTrip
8
+ def self.find_by_closest_year(year)
9
+ if year > maximum(:activity_year)
10
+ where(:activity_year => maximum(:activity_year)).first
11
+ else
12
+ where(:activity_year => [year, minimum(:activity_year)].max).first
13
+ end
14
+ end
15
+
16
+ col :activity_year, :type => :integer
17
+ col :hfc_emission_factor, :type => :float
18
+ col :hfc_emission_factor_units
19
+
20
+ warn_unless_size 15
21
+ end
@@ -0,0 +1,27 @@
1
+ AutomobileActivityYear.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ delete_all
5
+ end
6
+
7
+ process "Ensure AutomobileActivityYearType is populated" do
8
+ AutomobileActivityYearType.run_data_miner!
9
+ end
10
+
11
+ process "Derive from AutomobileActivityYearType" do
12
+ ::Earth::Utils.insert_ignore(
13
+ :src => AutomobileActivityYearType,
14
+ :dest => AutomobileActivityYear,
15
+ :cols => { :activity_year => :activity_year }
16
+ )
17
+ end
18
+
19
+ process "Derive hfc emission factor from AutomobileActivityYearType" do
20
+ find_each do |ay|
21
+ ay.hfc_emission_factor = ay.activity_year_types.sum(&:hfc_emissions) / ay.activity_year_types.sum{ |ayt| ayt.activity_year_type_fuels.sum(&:distance) }
22
+ ay.hfc_emission_factor_units = ay.activity_year_types.first.hfc_emission_factor_units
23
+ ay.save!
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ class AutomobileActivityYearType < ActiveRecord::Base
2
+ self.primary_key = "name"
3
+
4
+ # Used by Automobile and AutomobileTrip
5
+ def self.find_by_type_name_and_closest_year(type_name, year)
6
+ if year > maximum(:activity_year)
7
+ where(:type_name => type_name, :activity_year => maximum(:activity_year)).first
8
+ else
9
+ where(:type_name => type_name, :activity_year => [year, minimum(:activity_year)].max).first
10
+ end
11
+ end
12
+
13
+ # for calculating hfc ef
14
+ def activity_year_type_fuels
15
+ AutomobileActivityYearTypeFuel.where(:activity_year => activity_year, :type_name => type_name)
16
+ end
17
+
18
+ col :name
19
+ col :activity_year, :type => :integer
20
+ col :type_name
21
+ col :hfc_emissions, :type => :float
22
+ col :hfc_emissions_units
23
+ col :hfc_emission_factor, :type => :float
24
+ col :hfc_emission_factor_units
25
+
26
+ warn_unless_size 30
27
+ end
@@ -0,0 +1,27 @@
1
+ AutomobileActivityYearType.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ delete_all
5
+ end
6
+
7
+ import "annual automobile air conditioning emissions derived from the 2010 EPA GHG Inventory",
8
+ :url => "file://#{Earth::DATA_DIR}/automobile/hfc_emissions.csv" do
9
+ key 'name'
10
+ store 'activity_year'
11
+ store 'type_name'
12
+ store 'hfc_emissions', :from_units => :teragrams_co2e, :to_units => :kilograms_co2e
13
+ end
14
+
15
+ process "Ensure AutomobileActivityYearTypeFuel is populated" do
16
+ AutomobileActivityYearTypeFuel.run_data_miner!
17
+ end
18
+
19
+ process "Derive hfc emission factor from AutomobileActivityYearTypeFuel" do
20
+ find_each do |ayt|
21
+ ayt.hfc_emission_factor = ayt.hfc_emissions / ayt.activity_year_type_fuels.sum(:distance)
22
+ ayt.hfc_emission_factor_units = ayt.hfc_emissions_units + '_per_' + ayt.activity_year_type_fuels.first.distance_units.singularize
23
+ ayt.save!
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ class AutomobileActivityYearTypeFuel < ActiveRecord::Base
2
+ self.primary_key = "name"
3
+
4
+ # Used by AutomobileFuel to get records from latest activity year
5
+ def self.latest
6
+ where(:activity_year => maximum(:activity_year))
7
+ end
8
+
9
+ col :name
10
+ col :activity_year, :type => :integer
11
+ col :type_name
12
+ col :fuel_common_name
13
+ col :distance, :type => :float
14
+ col :distance_units
15
+ col :fuel_consumption, :type => :float
16
+ col :fuel_consumption_units
17
+
18
+ warn_unless_size 120
19
+ end
@@ -0,0 +1,57 @@
1
+ AutomobileActivityYearTypeFuel.class_eval do
2
+ data_miner do
3
+ process "Start from scratch" do
4
+ delete_all
5
+ end
6
+
7
+ ['Passenger cars', 'Light-duty trucks'].each do |type|
8
+ import "annual vehicle miles travelled by gasoline #{type.downcase} from the 2011 EPA GHG Inventory",
9
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads11/Annex%20Tables.zip',
10
+ :filename => 'Annex Tables/Table A-89.csv',
11
+ :skip => 1,
12
+ :headers => ['Year', 'Passenger cars', 'Light-duty trucks', 'ignore', 'ignore'],
13
+ :select => proc { |row| row['Year'].to_i.to_s == row['Year'] } do
14
+ key 'name', :synthesize => proc { |row| "#{row['Year']} #{type} gasoline" }
15
+ store 'activity_year', :field_name => 'Year'
16
+ store 'type_name', :static => type
17
+ store 'fuel_common_name', :static => 'gasoline'
18
+ store 'distance', :field_name => type, :from_units => :billion_miles, :to_units => :kilometres
19
+ end
20
+
21
+ import "annual vehicle miles travelled by diesel #{type.downcase} from the 2011 EPA GHG Inventory",
22
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads11/Annex%20Tables.zip',
23
+ :filename => 'Annex Tables/Table A-90.csv',
24
+ :skip => 1,
25
+ :headers => ['Year', 'Passenger cars', 'Light-duty trucks', 'ignore', 'ignore'],
26
+ :select => proc { |row| row['Year'].to_i.to_s == row['Year'] } do
27
+ key 'name', :synthesize => proc { |row| "#{row['Year']} #{type} diesel" }
28
+ store 'activity_year', :field_name => 'Year'
29
+ store 'type_name', :static => type
30
+ store 'fuel_common_name', :static => 'diesel'
31
+ store 'distance', :field_name => type, :from_units => :billion_miles, :to_units => :kilometres
32
+ end
33
+
34
+ import "annual vehicle miles travelled by alternative fuel #{type.downcase} from the 2011 EPA GHG Inventory",
35
+ :url => 'http://www.epa.gov/climatechange/emissions/downloads11/Annex%20Tables.zip',
36
+ :filename => 'Annex Tables/Table A-91.csv',
37
+ :skip => 1,
38
+ :headers => ['Year', 'Passenger cars', 'Light-duty trucks', 'ignore', 'ignore'],
39
+ :select => proc { |row| row['Year'].to_i.to_s == row['Year'] } do
40
+ key 'name', :synthesize => proc { |row| "#{row['Year']} #{type} alternative" }
41
+ store 'activity_year', :field_name => 'Year'
42
+ store 'type_name', :static => type
43
+ store 'fuel_common_name', :static => 'alternative'
44
+ store 'distance', :field_name => type, :from_units => :billion_miles, :to_units => :kilometres
45
+ end
46
+ end
47
+
48
+ import "fuel consumption derived from 2012 EPA GHG Inventory",
49
+ :url => "file://#{Earth::DATA_DIR}/automobile/annual_fuel_consumption.csv" do
50
+ key 'name'
51
+ store 'activity_year'
52
+ store 'type_name'
53
+ store 'fuel_common_name'
54
+ store 'fuel_consumption', :from_units => :million_gallons, :to_units => :litres
55
+ end
56
+ end
57
+ end
@@ -3,115 +3,122 @@ require 'earth/fuel'
3
3
  class AutomobileFuel < ActiveRecord::Base
4
4
  self.primary_key = "name"
5
5
 
6
- has_many :type_fuel_year_ages, :class_name => 'AutomobileTypeFuelYearAge', :foreign_key => 'fuel_common_name', :primary_key => 'distance_key'
7
- has_many :type_fuel_years, :class_name => 'AutomobileTypeFuelYear', :foreign_key => 'fuel_common_name', :primary_key => 'ef_key'
8
- belongs_to :base_fuel, :class_name => 'Fuel', :foreign_key => 'base_fuel_name'
9
- belongs_to :blend_fuel, :class_name => 'Fuel', :foreign_key => 'blend_fuel_name'
10
-
11
- warn_if_blanks_in :distance_key
12
- warn_if_blanks_in :ef_key
13
- warn do
14
- catch :culprit do
15
- find_each do |record|
16
- throw :culprit, %{Records exist without base_fuel (possibly invalid key "#{record.base_fuel_name}")} unless record.base_fuel
17
- end
18
- false
19
- end
20
- end
21
- warn do
22
- if exists?(['blend_portion IS NOT NULL AND (blend_portion < ? OR blend_portion > ?)', 0, 1])
23
- "Blend portions less than 0 or greater than 1"
24
- end
25
- end
26
- warn do
27
- %w{co2_emission_factor co2_biogenic_emission_factor}.map do |col|
28
- if exists?(["#{col} IS NULL OR #{col} < ?", 0])
29
- "Records non-positive #{col}"
30
- end
31
- end
32
- end
6
+ # for calculating energy content and co2 efs
7
+ belongs_to :base_fuel, :class_name => 'Fuel', :foreign_key => 'base_fuel_name'
8
+ belongs_to :blend_fuel, :class_name => 'Fuel', :foreign_key => 'blend_fuel_name'
9
+
10
+ # for calculating gas and diesel annual distance and ch4 + n2o efs
11
+ has_many :type_fuels, :foreign_key => :fuel_common_name, :primary_key => :common_name, :class_name => 'AutomobileTypeFuel'
33
12
 
13
+ # for fallback
34
14
  class << self
35
- def fallback_type_fuel_year_ages
36
- AutomobileTypeFuelYearAge.where(:year => AutomobileTypeFuelYearAge.maximum('year'))
15
+ def diesel
16
+ AutomobileFuel.find 'diesel'
37
17
  end
38
18
 
39
- def fallback_type_fuel_years
40
- AutomobileTypeFuelYear.where(:year => AutomobileTypeFuelYear.maximum('year'))
19
+ def gasoline
20
+ AutomobileFuel.find 'gasoline'
41
21
  end
42
22
 
43
- def fallback_type_years
44
- AutomobileTypeYear.where(:year => AutomobileTypeYear.maximum('year'))
23
+ def fallback_blend_portion
24
+ diesel.total_consumption / (diesel.total_consumption + gasoline.total_consumption)
45
25
  end
46
26
 
47
- # FIXME TODO for some reason this causes the fallbacks calculation to hang (infinite loop?) if it's defined as a fallback
48
- def fallback_blend_portion
49
- gas_use = fallback_type_fuel_years.where(:fuel_common_name => 'gasoline').sum('fuel_consumption').to_f
50
- diesel_use = fallback_type_fuel_years.where(:fuel_common_name => 'diesel').sum('fuel_consumption').to_f
51
- diesel_use / (gas_use + diesel_use)
27
+ def determine_fallback(method)
28
+ if method =~ /units/
29
+ gasoline.send(method)
30
+ else
31
+ (fallback_blend_portion * diesel.send(method)) + ((1 - fallback_blend_portion) * gasoline.send(method))
32
+ end
33
+ end
34
+ end
35
+
36
+ # Used by Automobile and AutomobileTrip to determine whether need to convert fuel efficiency units
37
+ def non_liquid?
38
+ energy_content_units != 'megajoules_per_litre'
39
+ end
40
+
41
+ # Used by Automobile and AutomobileTrip to check whether user-input fuel matches one of the vehicle's fuels
42
+ def same_as?(other_auto_fuel)
43
+ unless other_auto_fuel.nil?
44
+ if ['G', 'R', 'P'].include? self.code
45
+ ['G', 'R', 'P'].include? other_auto_fuel.code
46
+ else
47
+ self == other_auto_fuel
48
+ end
52
49
  end
53
50
  end
54
51
 
55
52
  falls_back_on :name => 'fallback',
56
- :annual_distance => lambda { fallback_type_fuel_year_ages.weighted_average(:annual_distance, :weighted_by => :vehicles) },
57
- :annual_distance_units => lambda { fallback_type_fuel_year_ages.first.annual_distance_units },
58
- :energy_content => lambda {
59
- (Fuel.find_by_name('Motor Gasoline').energy_content * (1 - fallback_blend_portion)) +
60
- (Fuel.find_by_name('Distillate Fuel Oil No. 2').energy_content * fallback_blend_portion)
61
- },
62
- :co2_emission_factor => lambda {
63
- (Fuel.find_by_name("Motor Gasoline").co2_emission_factor * (1 - fallback_blend_portion)) +
64
- (Fuel.find_by_name("Distillate Fuel Oil No. 2").co2_emission_factor * fallback_blend_portion)
65
- },
66
- :co2_emission_factor_units => lambda { Fuel.find_by_name("Motor Gasoline").co2_emission_factor_units },
67
- :co2_biogenic_emission_factor => lambda {
68
- (Fuel.find_by_name("Motor Gasoline").co2_biogenic_emission_factor * (1 - AutomobileFuel.fallback_blend_portion)) +
69
- (Fuel.find_by_name("Distillate Fuel Oil No. 2").co2_biogenic_emission_factor * AutomobileFuel.fallback_blend_portion)
70
- },
71
- :co2_biogenic_emission_factor_units => lambda { Fuel.find_by_name("Motor Gasoline").co2_biogenic_emission_factor_units },
72
- :ch4_emission_factor => lambda { fallback_type_fuel_years.weighted_average(:ch4_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:ch4].global_warming_potential },
73
- :ch4_emission_factor_units => lambda {
74
- prefix = fallback_type_fuel_years.first.ch4_emission_factor_units.split("_per_")[0]
75
- suffix = fallback_type_fuel_years.first.ch4_emission_factor_units.split("_per_")[1]
76
- prefix + "_co2e_per_" + suffix
77
- },
78
- :n2o_emission_factor => lambda {
79
- fallback_type_fuel_years.weighted_average(:n2o_emission_factor, :weighted_by => :total_travel) * GreenhouseGas[:n2o].global_warming_potential
80
- },
81
- :n2o_emission_factor_units => lambda {
82
- prefix = fallback_type_fuel_years.first.n2o_emission_factor_units.split("_per_")[0]
83
- suffix = fallback_type_fuel_years.first.n2o_emission_factor_units.split("_per_")[1]
84
- prefix + "_co2e_per_" + suffix
85
- },
86
- :hfc_emission_factor => lambda { fallback_type_years.weighted_average(:hfc_emission_factor, :weighted_by => [:type_fuel_years, :total_travel]) },
87
- :hfc_emission_factor_units => lambda { fallback_type_years.first.hfc_emission_factor_units }
53
+ :base_fuel_name => 'Motor Gasoline',
54
+ :blend_fuel_name => 'Distillate Fuel Oil No. 2',
55
+ :blend_portion => proc { AutomobileFuel.fallback_blend_portion },
56
+ :annual_distance => proc { AutomobileFuel.determine_fallback 'annual_distance' },
57
+ :annual_distance_units => proc { AutomobileFuel.determine_fallback 'annual_distance_units' },
58
+ :energy_content => proc { AutomobileFuel.determine_fallback 'energy_content' },
59
+ :energy_content_units => proc { AutomobileFuel.determine_fallback 'energy_content_units' },
60
+ :co2_emission_factor => proc { AutomobileFuel.determine_fallback 'co2_emission_factor' },
61
+ :co2_emission_factor_units => proc { AutomobileFuel.determine_fallback 'co2_emission_factor_units' },
62
+ :co2_biogenic_emission_factor => proc { AutomobileFuel.determine_fallback 'co2_biogenic_emission_factor' },
63
+ :co2_biogenic_emission_factor_units => proc { AutomobileFuel.determine_fallback 'co2_biogenic_emission_factor_units' },
64
+ :ch4_emission_factor => proc { AutomobileFuel.determine_fallback 'ch4_emission_factor' },
65
+ :ch4_emission_factor_units => proc { AutomobileFuel.determine_fallback 'ch4_emission_factor_units' },
66
+ :n2o_emission_factor => proc { AutomobileFuel.determine_fallback 'n2o_emission_factor' },
67
+ :n2o_emission_factor_units => proc { AutomobileFuel.determine_fallback 'n2o_emission_factor_units' }
88
68
 
89
69
  col :name
90
70
  col :code
71
+ col :common_name
72
+ col :distance_key
91
73
  col :base_fuel_name
92
74
  col :blend_fuel_name
93
- col :blend_portion, :type => :float # the portion of the blend that is the blend fuel
94
- col :distance_key # used to look up annual distance from AutomobileTypeFuelYear
95
- col :ef_key # used to look up ch4 n2o and hfc emission factors from AutomobileTypeFuelYear
96
- col :annual_distance, :type => :float
75
+ col :blend_portion, :type => :float # the portion of the blend that is the blend fuel
76
+ col :annual_distance, :type => :float
97
77
  col :annual_distance_units
98
- col :energy_content, :type => :float
78
+ col :energy_content, :type => :float
99
79
  col :energy_content_units
100
- col :co2_emission_factor, :type => :float
80
+ col :co2_emission_factor, :type => :float
101
81
  col :co2_emission_factor_units
102
82
  col :co2_biogenic_emission_factor, :type => :float
103
83
  col :co2_biogenic_emission_factor_units
104
- col :ch4_emission_factor, :type => :float
84
+ col :ch4_emission_factor, :type => :float
105
85
  col :ch4_emission_factor_units
106
- col :n2o_emission_factor, :type => :float
86
+ col :n2o_emission_factor, :type => :float
107
87
  col :n2o_emission_factor_units
108
- col :hfc_emission_factor, :type => :float
109
- col :hfc_emission_factor_units
110
- col :emission_factor, :type => :float # DEPRECATED but motorcycle needs this
111
- col :emission_factor_units # FIXME TODO DEPRECATED but motorcycle needs this
88
+ col :total_consumption, :type => :float # for calculating fallback blend_portion
89
+ col :total_consumption_units
112
90
 
113
- CODES = {
114
- :electricity => 'El',
115
- :diesel => 'D'
116
- }
91
+ warn_unless_size 12
92
+ warn_if_blanks :code, :common_name, :distance_key
93
+ warn_if do
94
+ if exists?("name != 'electricity' AND base_fuel_name IS NULL")
95
+ "Records missing #{col}"
96
+ end
97
+ end
98
+ warn_if do
99
+ if exists?(['blend_fuel_name IS NOT NULL AND (blend_portion IS NULL OR blend_portion <= ? OR blend_portion >= ?)', 0, 1])
100
+ "Blend portions not between 0 and 1"
101
+ end
102
+ end
103
+ warn_if do
104
+ %w{annual_distance energy_content}.map do |col|
105
+ if exists?(["#{col} IS NULL OR #{col} <= ?", 0])
106
+ "Records not > 0 #{col}"
107
+ end
108
+ end
109
+ end
110
+ warn_if do
111
+ %w{ co2_emission_factor co2_biogenic_emission_factor}.map do |col|
112
+ if exists?(["name != 'electricity' AND (#{col} IS NULL OR #{col} < ?)", 0])
113
+ "Records non-positive #{col}"
114
+ end
115
+ end
116
+ end
117
+ warn_if do
118
+ %w{ch4_emission_factor n2o_emission_factor}.map do |col|
119
+ if exists?(["#{col} IS NULL OR #{col} < ?", 0])
120
+ "Records non-positive #{col}"
121
+ end
122
+ end
123
+ end
117
124
  end