earth 0.5.4 → 0.6.0

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 (131) hide show
  1. data/Gemfile +1 -0
  2. data/TODO +2 -0
  3. data/bin/earth_tester.rb +62 -9
  4. data/earth.gemspec +7 -4
  5. data/lib/earth.rb +18 -17
  6. data/lib/earth/air.rb +2 -0
  7. data/lib/earth/air/aircraft.rb +76 -19
  8. data/lib/earth/air/aircraft/data_miner.rb +1 -63
  9. data/lib/earth/air/aircraft_class.rb +48 -12
  10. data/lib/earth/air/aircraft_class/data_miner.rb +3 -46
  11. data/lib/earth/air/aircraft_fuel_use_equation.rb +11 -13
  12. data/lib/earth/air/aircraft_instance.rb +9 -0
  13. data/lib/earth/air/aircraft_instance_seat_class.rb +12 -0
  14. data/lib/earth/air/airline.rb +6 -8
  15. data/lib/earth/air/airline/data_miner.rb +3 -3
  16. data/lib/earth/air/airport.rb +8 -10
  17. data/lib/earth/air/airport/data_miner.rb +1 -1
  18. data/lib/earth/air/bts_aircraft.rb +3 -5
  19. data/lib/earth/air/flight_distance_class.rb +4 -6
  20. data/lib/earth/air/flight_seat_class.rb +5 -7
  21. data/lib/earth/air/flight_segment.rb +58 -42
  22. data/lib/earth/air/flight_segment/data_miner.rb +11 -26
  23. data/lib/earth/automobile.rb +1 -0
  24. data/lib/earth/automobile/automobile_fuel.rb +78 -25
  25. data/lib/earth/automobile/automobile_fuel/data_miner.rb +5 -72
  26. data/lib/earth/automobile/automobile_make.rb +14 -6
  27. data/lib/earth/automobile/automobile_make/data_miner.rb +20 -35
  28. data/lib/earth/automobile/automobile_make_fleet_year.rb +39 -10
  29. data/lib/earth/automobile/automobile_make_fleet_year/data_miner.rb +0 -29
  30. data/lib/earth/automobile/automobile_make_model.rb +30 -9
  31. data/lib/earth/automobile/automobile_make_model/data_miner.rb +11 -26
  32. data/lib/earth/automobile/automobile_make_model_year.rb +41 -12
  33. data/lib/earth/automobile/automobile_make_model_year/data_miner.rb +14 -34
  34. data/lib/earth/automobile/automobile_make_model_year_variant.rb +56 -38
  35. data/lib/earth/automobile/automobile_make_model_year_variant/data_miner.rb +15 -61
  36. data/lib/earth/automobile/automobile_make_year.rb +15 -8
  37. data/lib/earth/automobile/automobile_make_year/data_miner.rb +17 -51
  38. data/lib/earth/automobile/automobile_size_class.rb +78 -14
  39. data/lib/earth/automobile/automobile_size_class/data_miner.rb +0 -66
  40. data/lib/earth/automobile/automobile_size_class_year.rb +38 -10
  41. data/lib/earth/automobile/automobile_size_class_year/data_miner.rb +0 -30
  42. data/lib/earth/automobile/automobile_type_fuel_age.rb +60 -11
  43. data/lib/earth/automobile/automobile_type_fuel_age/data_miner.rb +10 -65
  44. data/lib/earth/automobile/automobile_type_fuel_control.rb +41 -10
  45. data/lib/earth/automobile/automobile_type_fuel_control/data_miner.rb +0 -33
  46. data/lib/earth/automobile/automobile_type_fuel_year.rb +60 -15
  47. data/lib/earth/automobile/automobile_type_fuel_year/data_miner.rb +1 -52
  48. data/lib/earth/automobile/automobile_type_fuel_year_age.rb +64 -12
  49. data/lib/earth/automobile/automobile_type_fuel_year_age/data_miner.rb +1 -59
  50. data/lib/earth/automobile/automobile_type_fuel_year_control.rb +31 -10
  51. data/lib/earth/automobile/automobile_type_fuel_year_control/data_miner.rb +2 -32
  52. data/lib/earth/automobile/automobile_type_year.rb +51 -10
  53. data/lib/earth/automobile/automobile_type_year/data_miner.rb +1 -43
  54. data/lib/earth/automobile/data_miner.rb +1 -0
  55. data/lib/earth/bus/bus_class.rb +108 -28
  56. data/lib/earth/bus/bus_class/data_miner.rb +0 -88
  57. data/lib/earth/bus/bus_fuel.rb +83 -15
  58. data/lib/earth/bus/bus_fuel/data_miner.rb +0 -76
  59. data/lib/earth/bus/bus_fuel_control.rb +8 -10
  60. data/lib/earth/bus/bus_fuel_year_control.rb +7 -9
  61. data/lib/earth/bus/bus_fuel_year_control/data_miner.rb +1 -5
  62. data/lib/earth/computation/computation_carrier.rb +11 -5
  63. data/lib/earth/computation/computation_carrier/data_miner.rb +0 -7
  64. data/lib/earth/computation/computation_carrier_instance_class.rb +25 -8
  65. data/lib/earth/computation/computation_carrier_instance_class/data_miner.rb +0 -18
  66. data/lib/earth/computation/computation_carrier_region.rb +5 -7
  67. data/lib/earth/diet/diet_class.rb +14 -16
  68. data/lib/earth/diet/food_group.rb +7 -9
  69. data/lib/earth/fuel/fuel.rb +14 -16
  70. data/lib/earth/fuel/fuel/data_miner.rb +7 -3
  71. data/lib/earth/fuel/fuel_price.rb +4 -6
  72. data/lib/earth/fuel/fuel_type.rb +12 -14
  73. data/lib/earth/fuel/fuel_year.rb +57 -16
  74. data/lib/earth/fuel/fuel_year/data_miner.rb +0 -43
  75. data/lib/earth/fuel/greenhouse_gas.rb +46 -9
  76. data/lib/earth/fuel/greenhouse_gas/data_miner.rb +0 -38
  77. data/lib/earth/hospitality/lodging_class.rb +10 -12
  78. data/lib/earth/industry/industry.rb +3 -5
  79. data/lib/earth/industry/industry_product.rb +6 -8
  80. data/lib/earth/industry/industry_product_line.rb +5 -7
  81. data/lib/earth/industry/industry_sector.rb +5 -7
  82. data/lib/earth/industry/merchant.rb +4 -6
  83. data/lib/earth/industry/merchant_category.rb +3 -5
  84. data/lib/earth/industry/merchant_category_industry.rb +5 -7
  85. data/lib/earth/industry/product_line.rb +5 -7
  86. data/lib/earth/industry/product_line_industry_product.rb +5 -7
  87. data/lib/earth/industry/sector.rb +5 -7
  88. data/lib/earth/locality/census_division.rb +21 -23
  89. data/lib/earth/locality/census_region.rb +3 -5
  90. data/lib/earth/locality/climate_division.rb +5 -7
  91. data/lib/earth/locality/country.rb +13 -15
  92. data/lib/earth/locality/egrid_region.rb +14 -5
  93. data/lib/earth/locality/egrid_region/data_miner.rb +0 -10
  94. data/lib/earth/locality/egrid_subregion.rb +71 -18
  95. data/lib/earth/locality/egrid_subregion/data_miner.rb +0 -59
  96. data/lib/earth/locality/petroleum_administration_for_defense_district.rb +6 -8
  97. data/lib/earth/locality/state.rb +6 -8
  98. data/lib/earth/locality/urbanity.rb +2 -4
  99. data/lib/earth/locality/urbanity/data_miner.rb +7 -3
  100. data/lib/earth/locality/zip_code.rb +8 -10
  101. data/lib/earth/pet/breed.rb +5 -7
  102. data/lib/earth/pet/breed_gender.rb +6 -8
  103. data/lib/earth/pet/gender.rb +2 -4
  104. data/lib/earth/pet/species.rb +15 -17
  105. data/lib/earth/rail/rail_class.rb +64 -14
  106. data/lib/earth/rail/rail_class/data_miner.rb +0 -51
  107. data/lib/earth/residence/air_conditioner_use.rb +4 -6
  108. data/lib/earth/residence/air_conditioner_use/data_miner.rb +7 -3
  109. data/lib/earth/residence/clothes_machine_use.rb +4 -6
  110. data/lib/earth/residence/clothes_machine_use/data_miner.rb +11 -9
  111. data/lib/earth/residence/dishwasher_use.rb +4 -6
  112. data/lib/earth/residence/dishwasher_use/data_miner.rb +11 -9
  113. data/lib/earth/residence/residence_appliance.rb +4 -6
  114. data/lib/earth/residence/residence_class.rb +2 -4
  115. data/lib/earth/residence/residence_class/data_miner.rb +7 -3
  116. data/lib/earth/residence/residence_fuel_price.rb +12 -14
  117. data/lib/earth/residence/residence_fuel_price/data_miner.rb +7 -0
  118. data/lib/earth/residence/residence_fuel_type.rb +6 -8
  119. data/lib/earth/residence/residential_energy_consumption_survey_response.rb +91 -93
  120. data/lib/earth/residence/residential_energy_consumption_survey_response/data_miner.rb +9 -8
  121. data/lib/earth/shipping/carrier.rb +57 -10
  122. data/lib/earth/shipping/carrier/data_miner.rb +0 -48
  123. data/lib/earth/shipping/carrier_mode.rb +41 -10
  124. data/lib/earth/shipping/carrier_mode/data_miner.rb +0 -33
  125. data/lib/earth/shipping/shipment_mode.rb +30 -7
  126. data/lib/earth/shipping/shipment_mode/data_miner.rb +0 -23
  127. data/lib/earth/utils.rb +45 -0
  128. data/lib/earth/version.rb +1 -1
  129. data/spec/earth/air/aircraft_spec.rb +1 -1
  130. data/vendor/clean_find_in_batches/init.rb +35 -0
  131. metadata +74 -47
@@ -1,56 +1,13 @@
1
1
  AircraftClass.class_eval do
2
2
  data_miner do
3
- process "Ensure Aircraft is populated" do
4
- Aircraft.run_data_miner!
5
- end
6
-
7
3
  process "Derive aircraft classes from Aircraft" do
8
- connection.select_values("SELECT DISTINCT class_code FROM aircraft WHERE aircraft.class_code IS NOT NULL").each do |class_code|
4
+ Aircraft.run_data_miner!
5
+ connection.select_values("SELECT DISTINCT class_code FROM aircraft WHERE class_code IS NOT NULL").each do |class_code|
9
6
  AircraftClass.find_or_create_by_code(class_code)
10
7
  end
11
8
  end
12
9
 
13
- process "Derive some average characteristics from Aircraft" do
14
- AircraftClass.find_each do |aircraft_class|
15
- %w{ m3 m2 m1 b }.each do |coefficient|
16
- value = AircraftFuelUseEquation.where("aircraft.class_code = '#{aircraft_class.code}'").
17
- weighted_average(:"#{coefficient}", :weighted_by => [:aircraft, :passengers])
18
- aircraft_class.send("#{coefficient}=", value)
19
- end
20
- # # do this in sql because we want to preserve nils and weighted_average returns 0 when it gets NULL
21
- # connection.execute %{
22
- # UPDATE aircraft_classes
23
- # SET aircraft_classes.#{coefficient} = (
24
- # SELECT sum(aircraft_fuel_use_equations.#{coefficient} * aircraft.passengers) / sum(aircraft.passengers)
25
- # FROM aircraft_fuel_use_equations
26
- # INNER JOIN aircraft
27
- # ON aircraft.fuel_use_code = aircraft_fuel_use_equations.code
28
- # WHERE aircraft.class_code = '#{aircraft_class.code}'
29
- # AND aircraft_fuel_use_equations.#{coefficient} IS NOT NULL
30
- # )
31
- # WHERE aircraft_classes.code = '#{aircraft_class.code}'
32
- # }
33
- # end
34
-
35
- aircraft_class.seats = aircraft_class.aircraft.weighted_average(:seats, :weighted_by => :passengers)
36
- # # do this in sql because we want to preserve nils and weighted_average returns 0 when it gets NULL
37
- # connection.execute %{
38
- # UPDATE aircraft_classes
39
- # SET aircraft_classes.seats = (
40
- # SELECT sum(aircraft.seats * aircraft.passengers) / sum(aircraft.passengers)
41
- # FROM aircraft
42
- # WHERE aircraft.class_code = '#{aircraft_class.code}'
43
- # )
44
- # WHERE aircraft_classes.code = '#{aircraft_class.code}'
45
- # }
46
-
47
- aircraft_class.m3_units = 'kilograms_per_cubic_nautical_mile'
48
- aircraft_class.m2_units = 'kilograms_per_square_nautical_mile'
49
- aircraft_class.m1_units = 'kilograms_per_nautical_mile'
50
- aircraft_class.b_units = 'kilograms'
51
- aircraft_class.save
52
- end
53
- end
10
+ process :update_averages!
54
11
 
55
12
  # FIXME TODO verify this
56
13
  end
@@ -20,16 +20,14 @@ class AircraftFuelUseEquation < ActiveRecord::Base
20
20
  fuel_use_coefficients.all?(&:present?) and fuel_use_coefficients.any?(&:nonzero?)
21
21
  end
22
22
 
23
- force_schema do
24
- string 'code'
25
- string 'aircraft_description'
26
- float 'm3'
27
- string 'm3_units'
28
- float 'm2'
29
- string 'm2_units'
30
- float 'm1'
31
- string 'm1_units'
32
- float 'b'
33
- string 'b_units'
34
- end
35
- end
23
+ col :code
24
+ col :aircraft_description
25
+ col :m3, :type => :float
26
+ col :m3_units
27
+ col :m2, :type => :float
28
+ col :m2_units
29
+ col :m1, :type => :float
30
+ col :m1_units
31
+ col :b, :type => :float
32
+ col :b_units
33
+ end
@@ -0,0 +1,9 @@
1
+ class AircraftInstance < ActiveRecord::Base
2
+ set_primary_key :id
3
+
4
+ col :id
5
+ col :registration
6
+ col :serial_number
7
+ col :aircraft_description
8
+ col :airline_name
9
+ end
@@ -0,0 +1,12 @@
1
+ class AircraftInstanceSeatClass < ActiveRecord::Base
2
+ set_primary_key :row_hash
3
+
4
+ col :row_hash
5
+ col :seat_class_name
6
+ col :aircraft_instance_id
7
+ col :seats, :type => :integer
8
+ col :seat_pitch, :type => :float
9
+ col :seat_pitch_units
10
+ col :seat_width, :type => :float
11
+ col :seat_width_units
12
+ end
@@ -1,10 +1,8 @@
1
1
  class Airline < ActiveRecord::Base
2
2
  set_primary_key :name
3
-
4
- force_schema do
5
- string 'name'
6
- string 'bts_code'
7
- string 'iata_code'
8
- string 'icao_code'
9
- end
10
- end
3
+
4
+ col :name
5
+ col :bts_code
6
+ col :iata_code
7
+ col :icao_code
8
+ end
@@ -1,10 +1,10 @@
1
1
  Airline.class_eval do
2
2
  data_miner do
3
- import "a Brighter Planet-curated list of airlines",
4
- :url => 'https://spreadsheets.google.com/pub?key=0AoQJbWqPrREqdDhoVHZmSTlZcHBsRUtPR0dPd0prMkE&output=csv' do
3
+ import "a Brighter Planet-curated list of airlines and codes not included in our other sources",
4
+ :url => 'https://spreadsheets.google.com/spreadsheet/pub?key=0AoQJbWqPrREqdGJoaFpENXRqMEM2NW42am5tNURGU2c&output=csv' do
5
5
  key 'name'
6
6
  store 'bts_code', :nullify => true
7
- store 'iata_code', :nullify => true
7
+ store 'iata_code', :nullify => true
8
8
  store 'icao_code', :nullify => true
9
9
  end
10
10
  end
@@ -7,13 +7,11 @@ class Airport < ActiveRecord::Base
7
7
  :lat_column_name => :latitude,
8
8
  :lng_column_name => :longitude
9
9
 
10
- force_schema do
11
- string 'iata_code'
12
- string 'name'
13
- string 'city'
14
- string 'country_name'
15
- string 'country_iso_3166_code'
16
- float 'latitude'
17
- float 'longitude'
18
- end
19
- end
10
+ col :iata_code
11
+ col :name
12
+ col :city
13
+ col :country_name
14
+ col :country_iso_3166_code
15
+ col :latitude, :type => :float
16
+ col :longitude, :type => :float
17
+ end
@@ -46,7 +46,7 @@ Airport.class_eval do
46
46
  process "Fill in blank country codes" do
47
47
  Country.find_each do |country|
48
48
  next unless country.name.present? and country.iso_3166_code.present?
49
- update_all %{country_iso_3166_code = "#{country.iso_3166_code}"}, %{country_name LIKE "#{country.name}"}
49
+ update_all({ :country_iso_3166_code => country.iso_3166_code }, [ "country_name LIKE ?", country.name ])
50
50
  end
51
51
  end
52
52
 
@@ -1,7 +1,5 @@
1
1
  class BtsAircraft < ActiveRecord::Base
2
2
  set_primary_key :bts_code
3
- force_schema do
4
- string 'bts_code'
5
- string 'description'
6
- end
7
- end
3
+ col :bts_code
4
+ col :description
5
+ end
@@ -1,8 +1,6 @@
1
1
  class FlightDistanceClass < ActiveRecord::Base
2
2
  set_primary_key :name
3
- force_schema do
4
- string 'name'
5
- float 'distance'
6
- string 'distance_units'
7
- end
8
- end
3
+ col :name
4
+ col :distance, :type => :float
5
+ col :distance_units
6
+ end
@@ -3,10 +3,8 @@ class FlightSeatClass < ActiveRecord::Base
3
3
 
4
4
  falls_back_on :multiplier => 1
5
5
 
6
- force_schema do
7
- string 'name'
8
- string 'distance_class_name'
9
- string 'seat_class_name'
10
- float 'multiplier'
11
- end
12
- end
6
+ col :name
7
+ col :distance_class_name
8
+ col :seat_class_name
9
+ col :multiplier, :type => :float
10
+ end
@@ -19,46 +19,62 @@ class FlightSegment < ActiveRecord::Base
19
19
  :load_factor => lambda { weighted_average(:load_factor, :weighted_by => :passengers) }, # 0.78073233770097 data1 10-12-2010
20
20
  :freight_share => lambda { weighted_average(:freight_share, :weighted_by => :passengers) } # 0.022567224170157 data1 10-12-2010
21
21
 
22
- force_schema do
23
- string 'row_hash' # auto-generated primary key
24
- string 'origin_airport_iata_code' # iata code
25
- string 'origin_airport_city' # city
26
- string 'origin_country_iso_3166_code' # iso code
27
- string 'destination_airport_iata_code' # iata code
28
- string 'destination_airport_city' # city
29
- string 'destination_country_iso_3166_code' # iso code
30
- string 'airline_bts_code' # bts code
31
- string 'airline_icao_code' # icao code
32
- string 'airline_name' # text description derived from bts or icao code
33
- string 'aircraft_bts_code' # bts code
34
- string 'aircraft_description' # text description derived from BTS T100 or ICAO TFS
35
- integer 'flights' # number of flights over month or year
36
- integer 'passengers' # total passengers on all flights
37
- integer 'seats' # total seats on all flights
38
- float 'seats_per_flight' # average seats per flight; make this a float
39
- float 'load_factor' # passengers / seats
40
- float 'freight_share' # (freight + mail) / (freight + mail + (passengers * average passenger weight))
41
- float 'distance' # flight distance
42
- string 'distance_units' # 'kilometres'
43
- float 'payload_capacity' # aircraft maximum payload capacity rating; float b/c unit conversion
44
- string 'payload_capacity_units' # 'kilograms'
45
- float 'freight' # total freight on all flights performed; float b/c unit conversion
46
- string 'freight_units' # 'kilograms'
47
- float 'mail' # total mail on all flights performed; float b/c unit conversion
48
- string 'mail_units' # 'kilograms'
49
- integer 'month' # month of flight
50
- integer 'year' # year of flight
51
- date 'approximate_date' # assumed 14th day of month
52
- string 'source' # 'BTS T100' or 'ICAO TFS'
53
- index 'origin_airport_iata_code' # index for faster lookup by origin airport
54
- index 'origin_airport_city' # index for faster lookup by origin city
55
- index 'destination_airport_iata_code' # index for faster lookup by destination airport
56
- index 'destination_airport_city' # index for faster lookup by destination city
57
- index 'airline_bts_code' # index for faster lookup by airline bts code
58
- index 'airline_icao_code' # index for faster lookup by airline icao code
59
- index 'airline_name' # index for faster lookup by airline name
60
- index 'aircraft_bts_code' # index for faster lookup by aircraft bts code
61
- index 'aircraft_description' # index for faster lookup by aircraft
62
- index 'year' # index for faster lookup by year
22
+ col :row_hash # auto-generated primary key
23
+ col :origin_airport_iata_code # iata code
24
+ col :origin_airport_city # city
25
+ col :origin_country_iso_3166_code # iso code
26
+ col :destination_airport_iata_code # iata code
27
+ col :destination_airport_city # city
28
+ col :destination_country_iso_3166_code # iso code
29
+ col :airline_bts_code # bts code
30
+ col :airline_icao_code # icao code
31
+ col :airline_name # text description derived from bts or icao code
32
+ col :aircraft_bts_code # bts code
33
+ col :aircraft_description # text description derived from BTS T100 or ICAO TFS
34
+ col :flights, :type => :integer # number of flights over month or year
35
+ col :passengers, :type => :integer # total passengers on all flights
36
+ col :seats, :type => :integer # total seats on all flights
37
+ col :seats_per_flight, :type => :float # average seats per flight; make this a float
38
+ col :load_factor, :type => :float # passengers / seats
39
+ col :freight_share, :type => :float # (freight + mail) / (freight + mail + (passengers * average passenger weight))
40
+ col :distance, :type => :float # flight distance
41
+ col :distance_units # 'kilometres'
42
+ col :payload_capacity, :type => :float # aircraft maximum payload capacity rating; float b/c unit conversion
43
+ col :payload_capacity_units # 'kilograms'
44
+ col :freight, :type => :float # total freight on all flights performed; float b/c unit conversion
45
+ col :freight_units # 'kilograms'
46
+ col :mail, :type => :float # total mail on all flights performed; float b/c unit conversion
47
+ col :mail_units # 'kilograms'
48
+ col :month, :type => :integer # month of flight
49
+ col :year, :type => :integer # year of flight
50
+ col :approximate_date, :type => :date # assumed 14th day of month
51
+ col :source # 'BTS T100' or 'ICAO TFS'
52
+ add_index :origin_airport_iata_code
53
+ add_index :origin_airport_city
54
+ add_index :destination_airport_iata_code
55
+ add_index :destination_airport_city
56
+ add_index :airline_bts_code
57
+ add_index :airline_icao_code
58
+ add_index :airline_name
59
+ add_index :aircraft_bts_code
60
+ add_index :aircraft_description
61
+ add_index :year
62
+
63
+ def self.update_averages!
64
+ # Derive load factor, which is passengers divided by available seats
65
+ update_all 'load_factor = passengers / seats', 'seats > 0'
66
+
67
+ # Assume a load factor of 1 where passengers > available seats
68
+ update_all 'load_factor = 1', 'passengers > seats AND seats > 0'
69
+
70
+ # TODO: what is 90.718474
71
+ # Derive freight share as a fraction of the total weight carried
72
+ update_all 'freight_share = (freight + mail) / (freight + mail + (passengers * 90.718474))', '(freight + mail + passengers) > 0'
73
+
74
+ # Derive average seats per flight
75
+ update_all 'seats_per_flight = seats / flights', 'flights > 0'
76
+
77
+ # Add a useful date field
78
+ update_all 'approximate_date = DATE(year || "-" || month || "-" || "14")', 'month IS NOT NULL'
63
79
  end
64
- end
80
+ end
@@ -10,24 +10,6 @@ FlightSegment.class_eval do
10
10
  end
11
11
  end
12
12
 
13
- def self.update_averages!
14
- # Derive load factor, which is passengers divided by available seats
15
- update_all 'load_factor = passengers / seats', 'seats > 0'
16
-
17
- # Assume a load factor of 1 where passengers > available seats
18
- update_all 'load_factor = 1', 'passengers > seats AND seats > 0'
19
-
20
- # TODO: what is 90.718474
21
- # Derive freight share as a fraction of the total weight carried
22
- update_all 'freight_share = (freight + mail) / (freight + mail + (passengers * 90.718474))', '(freight + mail + passengers) > 0'
23
-
24
- # Derive average seats per flight
25
- update_all 'seats_per_flight = seats / flights', 'flights > 0'
26
-
27
- # Add a useful date field
28
- update_all 'approximate_date = DATE(CONCAT_WS("-", year, month, "14"))', 'month IS NOT NULL'
29
- end
30
-
31
13
  URL = 'http://www.transtats.bts.gov/DownLoad_Table.asp?Table_ID=293&Has_Group=3&Is_Zipped=0'
32
14
  FORM_DATA = %{
33
15
  UserTableName=T_100_Segment__All_Carriers&
@@ -187,11 +169,11 @@ FlightSegment.class_eval do
187
169
  VarType=Char
188
170
  }.gsub /[\s]+/,''
189
171
 
190
- data_miner do
191
- months = Hash.new
192
- (2009..2011).each do |year|
172
+ def self.form_data_per_month(year_range)
173
+ months = {}
174
+ year_range.each do |year|
193
175
  (1..12).each do |month|
194
- time = Time.gm year, month
176
+ time = ::Time.gm year, month
195
177
  form_data = FORM_DATA.dup
196
178
  form_data.gsub! '__YEAR__', time.year.to_s
197
179
  form_data.gsub! '__MONTH_NUMBER__', time.month.to_s
@@ -199,8 +181,11 @@ FlightSegment.class_eval do
199
181
  months[time] = form_data
200
182
  end
201
183
  end
202
-
203
- months.each do |month, form_data|
184
+ months
185
+ end
186
+
187
+ data_miner do
188
+ form_data_per_month(2009..2011).each do |month, form_data|
204
189
  import "T100 flight segment data for #{month.strftime('%B %Y')}",
205
190
  :url => URL,
206
191
  :form_data => form_data,
@@ -237,7 +222,7 @@ FlightSegment.class_eval do
237
222
  process "Look up airline name based on BTS code" do
238
223
  connection.select_values("SELECT DISTINCT airline_bts_code FROM flight_segments WHERE airline_bts_code IS NOT NULL").each do |bts_code|
239
224
  if airline = Airline.find_by_bts_code(bts_code)
240
- update_all %{ airline_name = "#{airline.name}" }, %{ airline_bts_code = "#{bts_code}" }
225
+ update_all({ :airline_name => airline.name }, :airline_bts_code => bts_code)
241
226
  end
242
227
  end
243
228
  end
@@ -245,7 +230,7 @@ FlightSegment.class_eval do
245
230
  process "Look up aircraft description based on BTS code" do
246
231
  connection.select_values("SELECT DISTINCT aircraft_bts_code FROM flight_segments WHERE aircraft_bts_code IS NOT NULL").each do |bts_code|
247
232
  if aircraft = BtsAircraft.find_by_bts_code(bts_code)
248
- update_all %{ aircraft_description = "#{aircraft.description.downcase}" }, %{ aircraft_bts_code = "#{bts_code}" }
233
+ update_all({ :aircraft_description => aircraft.description.downcase }, :aircraft_bts_code => bts_code)
249
234
  end
250
235
  end
251
236
  end
@@ -13,3 +13,4 @@ require 'earth/automobile/automobile_type_fuel_control'
13
13
  require 'earth/automobile/automobile_type_fuel_year'
14
14
  require 'earth/automobile/automobile_type_fuel_year_age'
15
15
  require 'earth/automobile/automobile_type_fuel_year_control'
16
+ require 'earth/fuel'
@@ -1,7 +1,6 @@
1
1
  require 'earth/automobile/automobile_type_fuel_year_age'
2
2
  require 'earth/automobile/automobile_type_fuel_year'
3
3
  require 'earth/automobile/automobile_type_year'
4
- require 'earth/fuel/greenhouse_gas'
5
4
 
6
5
  class AutomobileFuel < ActiveRecord::Base
7
6
  set_primary_key :name
@@ -10,6 +9,62 @@ class AutomobileFuel < ActiveRecord::Base
10
9
  has_many :type_fuel_years, :class_name => 'AutomobileTypeFuelYear', :foreign_key => 'fuel_common_name', :primary_key => 'ef_key'
11
10
  belongs_to :base_fuel, :class_name => 'Fuel', :foreign_key => 'base_fuel_name'
12
11
  belongs_to :blend_fuel, :class_name => 'Fuel', :foreign_key => 'blend_fuel_name'
12
+
13
+ warn_if_blanks_in :distance_key
14
+ warn_if_blanks_in :ef_key
15
+ warn do
16
+ catch :culprit do
17
+ find_each do |record|
18
+ throw :culprit, %{Records exist without base_fuel (possibly invalid key "#{record.base_fuel_name}")} unless record.base_fuel
19
+ end
20
+ false
21
+ end
22
+ end
23
+ warn do
24
+ if exists?(['blend_portion IS NOT NULL AND (blend_portion < ? OR blend_portion > ?)', 0, 1])
25
+ "Blend portions less than 0 or greater than 1"
26
+ end
27
+ end
28
+ warn do
29
+ %w{co2_emission_factor co2_biogenic_emission_factor}.map do |col|
30
+ if exists?(["#{col} IS NULL OR #{col} < ?", 0])
31
+ "Records non-positive #{col}"
32
+ end
33
+ end
34
+ end
35
+
36
+ # FIXME TODO verify that base_fuel_name and blend_fuel_name are found in Fuel if present
37
+ # FIXME TODO verify that distance_key is found in AutomobileTypeFuelYearAge
38
+ # FIXME TODO verify that ef_key is found in AutomobileTypeFuelYear
39
+
40
+ # TODO convert these to warn blocks
41
+ # ["ch4_emission_factor", "n2o_emission_factor", "hfc_emission_factor"].each do |attribute|
42
+ # verify "#{attribute.humanize} should be > 0" do
43
+ # find_each do |fuel|
44
+ # value = fuel.send(attribute)
45
+ # unless value > 0
46
+ # raise "Invalid #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}: #{value} (should be > 0)"
47
+ # end
48
+ # end
49
+ # end
50
+ # end
51
+ #
52
+ # [["co2_emission_factor_units", "kilograms_per_litre"],
53
+ # ["co2_biogenic_emission_factor_units", "kilograms_per_litre"],
54
+ # ["ch4_emission_factor_units", "kilograms_co2e_per_litre"],
55
+ # ["n2o_emission_factor_units", "kilograms_co2e_per_litre"],
56
+ # ["hfc_emission_factor_units", "kilograms_co2e_per_litre"]].each do |pair|
57
+ # attribute = pair[0]
58
+ # proper_units = pair[1]
59
+ # verify "#{attribute.humanize} should be #{proper_units.humanize.downcase}" do
60
+ # find_each do |fuel|
61
+ # units = fuel.send(attribute)
62
+ # unless units == proper_units
63
+ # raise "Invalid #{attribute.humanize.downcase} for AutomobileFuel #{fuel.name}: #{units} (should be #{proper_units})"
64
+ # end
65
+ # end
66
+ # end
67
+ # end
13
68
 
14
69
  class << self
15
70
  def fallback_latest_type_fuel_year_ages
@@ -98,32 +153,30 @@ class AutomobileFuel < ActiveRecord::Base
98
153
  :hfc_emission_factor => lambda { AutomobileFuel.fallback_hfc_emission_factor },
99
154
  :hfc_emission_factor_units => lambda { AutomobileFuel.fallback_hfc_emission_factor_units }
100
155
 
101
- force_schema do
102
- string 'name'
103
- string 'code'
104
- string 'base_fuel_name'
105
- string 'blend_fuel_name'
106
- float 'blend_portion' # the portion of the blend that is the blend fuel
107
- string 'distance_key' # used to look up annual distance from AutomobileTypeFuelYear
108
- string 'ef_key' # used to look up ch4 n2o and hfc emission factors from AutomobileTypeFuelYear
109
- float 'annual_distance'
110
- string 'annual_distance_units'
111
- float 'co2_emission_factor'
112
- string 'co2_emission_factor_units'
113
- float 'co2_biogenic_emission_factor'
114
- string 'co2_biogenic_emission_factor_units'
115
- float 'ch4_emission_factor'
116
- string 'ch4_emission_factor_units'
117
- float 'n2o_emission_factor'
118
- string 'n2o_emission_factor_units'
119
- float 'hfc_emission_factor'
120
- string 'hfc_emission_factor_units'
121
- float 'emission_factor' # DEPRECATED but motorcycle needs this
122
- string 'emission_factor_units' # DEPRECATED but motorcycle needs this
123
- end
156
+ col :name
157
+ col :code
158
+ col :base_fuel_name
159
+ col :blend_fuel_name
160
+ col :blend_portion, :type => :float # the portion of the blend that is the blend fuel
161
+ col :distance_key # used to look up annual distance from AutomobileTypeFuelYear
162
+ col :ef_key # used to look up ch4 n2o and hfc emission factors from AutomobileTypeFuelYear
163
+ col :annual_distance, :type => :float
164
+ col :annual_distance_units
165
+ col :co2_emission_factor, :type => :float
166
+ col :co2_emission_factor_units
167
+ col :co2_biogenic_emission_factor, :type => :float
168
+ col :co2_biogenic_emission_factor_units
169
+ col :ch4_emission_factor, :type => :float
170
+ col :ch4_emission_factor_units
171
+ col :n2o_emission_factor, :type => :float
172
+ col :n2o_emission_factor_units
173
+ col :hfc_emission_factor, :type => :float
174
+ col :hfc_emission_factor_units
175
+ col :emission_factor, :type => :float # DEPRECATED but motorcycle needs this
176
+ col :emission_factor_units # DEPRECATED but motorcycle needs this
124
177
 
125
178
  CODES = {
126
179
  :electricity => 'El',
127
180
  :diesel => 'D'
128
181
  }
129
- end
182
+ end