flight 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/features/flight_committees.feature +92 -130
- data/features/flight_emissions.feature +18 -18
- data/lib/flight/carbon_model.rb +339 -247
- data/lib/flight/data.rb +4 -5
- data/lib/flight/relationships.rb +9 -9
- metadata +19 -4
    
        data/lib/flight/carbon_model.rb
    CHANGED
    
    | @@ -2,33 +2,47 @@ | |
| 2 2 | 
             
            # See LICENSE for details.
         | 
| 3 3 | 
             
            # Contact Brighter Planet for dual-license arrangements.
         | 
| 4 4 |  | 
| 5 | 
            +
            require 'leap'
         | 
| 6 | 
            +
            require 'timeframe'
         | 
| 7 | 
            +
            require 'date'
         | 
| 5 8 | 
             
            require 'weighted_average'
         | 
| 6 9 | 
             
            require 'builder'
         | 
| 7 10 |  | 
| 8 | 
            -
            ## Flight | 
| 9 | 
            -
            # This  | 
| 11 | 
            +
            ## Flight carbon model
         | 
| 12 | 
            +
            # This model is used by [Brighter Planet](http://brighterplanet.com)'s carbon emission [web service](http://carbon.brighterplanet.com) to estimate the **greenhouse gas emissions of passenger air travel**.
         | 
| 10 13 | 
             
            #
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            #  | 
| 14 | 
            +
            ##### Timeframe and date
         | 
| 15 | 
            +
            # The model estimates the emissions that occur during a particular `timeframe`. To do this it needs to know the `date` on which the flight occurred. For example, if the `timeframe` is January 2010, a flight that occured on January 5, 2010 will have emissions but a flight that occured on February 1, 2010 will not. If no `timeframe` is specified, the default is the current year. If no `date` is specified, the default is the first day of the `timeframe`.
         | 
| 13 16 | 
             
            #
         | 
| 14 | 
            -
             | 
| 17 | 
            +
            ##### Calculations
         | 
| 18 | 
            +
            # The final estimate is the result of the **calculations** detailed below. These calculations are performed in reverse order, starting with the last calculation listed and finishing with the `emission` calculation. Each calculation is named according to the value it returns.
         | 
| 19 | 
            +
            #
         | 
| 20 | 
            +
            ##### Methods
         | 
| 21 | 
            +
            # To accomodate varying client input, each calculation may have one or more **methods**. These are listed under each calculation in order from most to least preferred. Each method is named according to the values it requires. If any of these values is not available the method will be ignored. If all the methods for a calculation are ignored, the calculation will not return a value. "Default" methods do not require any values, and so a calculation with a default method will always return a value.
         | 
| 22 | 
            +
            #
         | 
| 23 | 
            +
            ##### Standard compliance
         | 
| 24 | 
            +
            # Each method lists any established calculation standards with which it **complies**. When compliance with a standard is requested, all methods that do not comply with that standard are ignored. This means that any values a particular method requires will have been calculated using a compliant method, because those are the only methods available. If any value did not have a compliant method in its calculation then it would be undefined, and the current method would have been ignored.
         | 
| 25 | 
            +
            #
         | 
| 26 | 
            +
            ##### Collaboration
         | 
| 27 | 
            +
            # Contributions to this carbon model are actively encouraged and warmly welcomed. This library includes a comprehensive test suite to ensure that your changes do not cause regressions. All changes shold include test coverage for new functionality. Please see [sniff](http://github.com/brighterplanet/sniff#readme), our emitter testing framework, for more information.
         | 
| 15 28 | 
             
            module BrighterPlanet
         | 
| 16 29 | 
             
              module Flight
         | 
| 17 30 | 
             
                module CarbonModel
         | 
| 18 31 | 
             
                  def self.included(base)
         | 
| 19 32 | 
             
                    base.extend FastTimestamp
         | 
| 20 33 | 
             
                    base.decide :emission, :with => :characteristics do
         | 
| 21 | 
            -
                      ### Emission
         | 
| 22 | 
            -
                      #  | 
| 23 | 
            -
                      #  | 
| 34 | 
            +
                      ### Emission calculation
         | 
| 35 | 
            +
                      # Returns the `emission` estimate in *kg CO<sub>2</sub>e*.
         | 
| 36 | 
            +
                      # This is the passenger's share of the total flight emissions that occured during the `timeframe`.
         | 
| 24 37 | 
             
                      committee :emission do
         | 
| 25 | 
            -
                         | 
| 26 | 
            -
                        #  | 
| 38 | 
            +
                        #### Emission from fuel, emission factor, freight share, passengers, multipliers, and date
         | 
| 39 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 27 40 | 
             
                        #
         | 
| 28 | 
            -
                        #  | 
| 29 | 
            -
                        #  | 
| 30 | 
            -
                        #  | 
| 31 | 
            -
                        #  | 
| 41 | 
            +
                        # - Checks whether the flight occured during the `timeframe`
         | 
| 42 | 
            +
                        # - Multiplies `fuel use` (*kg fuel*) by an `emission factor` (*kg CO<sub>2</sub>e / kg fuel*) and an `aviation multiplier` to give total flight emissions in *kg CO<sub>2</sub>e*
         | 
| 43 | 
            +
                        # - Multiplies by (1 - `freight share`) to take out emissions attributed to freight cargo and mail, leaving emissions attributed to passengers and their baggage
         | 
| 44 | 
            +
                        # - Divides by the number of `passengers` and multiplies by a `seat class multiplier` to give `emission` for the passenger
         | 
| 45 | 
            +
                        # - If the flight did not occur during the `timeframe`, `emission` is zero
         | 
| 32 46 | 
             
                        quorum 'from fuel, emission factor, freight share, passengers, multipliers, and date',
         | 
| 33 47 | 
             
                          :needs => [:fuel, :emission_factor, :freight_share, :passengers, :seat_class_multiplier, :aviation_multiplier, :date], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics, timeframe|
         | 
| 34 48 | 
             
                          date = characteristics[:date].is_a?(Date) ?
         | 
| @@ -36,52 +50,60 @@ module BrighterPlanet | |
| 36 50 | 
             
                            Date.parse(characteristics[:date].to_s)
         | 
| 37 51 | 
             
                          if timeframe.include? date
         | 
| 38 52 | 
             
                            characteristics[:fuel] * characteristics[:emission_factor] * characteristics[:aviation_multiplier] * (1 - characteristics[:freight_share]) / characteristics[:passengers] * characteristics[:seat_class_multiplier]
         | 
| 39 | 
            -
                          # If the flight did not occur during the `timeframe`, `emission` is zero.
         | 
| 40 53 | 
             
                          else
         | 
| 41 54 | 
             
                            0
         | 
| 42 55 | 
             
                          end
         | 
| 43 56 | 
             
                        end
         | 
| 44 | 
            -
                        
         | 
| 45 | 
            -
                        quorum 'default' do
         | 
| 46 | 
            -
                          raise "The emission committee's default quorum should never be called"
         | 
| 47 | 
            -
                        end
         | 
| 48 57 | 
             
                      end
         | 
| 49 58 |  | 
| 50 | 
            -
                      ### Emission factor
         | 
| 51 | 
            -
                      #  | 
| 59 | 
            +
                      ### Emission factor calculation
         | 
| 60 | 
            +
                      # Returns the `emission factor` in *kg CO<sub>2</sub>e / kg fuel*.
         | 
| 52 61 | 
             
                      committee :emission_factor do
         | 
| 53 | 
            -
                         | 
| 54 | 
            -
                        #  | 
| 62 | 
            +
                        #### Emission factor from fuel type
         | 
| 63 | 
            +
                        # Complies: GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 64 | 
            +
                        #
         | 
| 65 | 
            +
                        # Looks up the [fuel type](http://data.brighterplanet.com/fuel_types) and divides its `emission factor` (*kg CO<sub>2</sub> / litre fuel*) by its `density` (*kg fuel / litre fuel*) to give *kg CO<sub>2</sub>e / kg fuel*.
         | 
| 55 66 | 
             
                        quorum 'from fuel type', :needs => :fuel_type, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 56 67 | 
             
                          characteristics[:fuel_type].emission_factor.to_f / characteristics[:fuel_type].density.to_f
         | 
| 57 68 | 
             
                        end
         | 
| 58 69 | 
             
                      end
         | 
| 59 70 |  | 
| 60 | 
            -
                      ### Aviation multiplier
         | 
| 61 | 
            -
                      #  | 
| 71 | 
            +
                      ### Aviation multiplier calculation
         | 
| 72 | 
            +
                      # Returns the `aviation multiplier`. This approximates the extra climate impact of emissions high in the atmosphere.
         | 
| 62 73 | 
             
                      committee :aviation_multiplier do
         | 
| 63 | 
            -
                         | 
| 64 | 
            -
                        #  | 
| 74 | 
            +
                        #### Aviation multiplier from client input
         | 
| 75 | 
            +
                        # **Complies:** All
         | 
| 76 | 
            +
                        #
         | 
| 77 | 
            +
                        # Uses the client-input `aviation multiplier`.
         | 
| 78 | 
            +
                        
         | 
| 79 | 
            +
                        #### Default aviation multiplier
         | 
| 80 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 81 | 
            +
                        #
         | 
| 82 | 
            +
                        # Uses an `aviation multiplier` of **2.0** after [Kolmuss and Crimmins (2009)](http://sei-us.org/publications/id/13).
         | 
| 65 83 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 66 | 
            -
                           | 
| 84 | 
            +
                          2.0
         | 
| 67 85 | 
             
                        end
         | 
| 68 86 | 
             
                      end
         | 
| 69 87 |  | 
| 70 | 
            -
                      ### Fuel
         | 
| 71 | 
            -
                      #  | 
| 88 | 
            +
                      ### Fuel calculation
         | 
| 89 | 
            +
                      # Returns the flight's total `fuel` use in *kg fuel*.
         | 
| 72 90 | 
             
                      committee :fuel do
         | 
| 73 | 
            -
                         | 
| 74 | 
            -
                        #  | 
| 91 | 
            +
                        #### Fuel from fuel per segment and segments per trip and trips
         | 
| 92 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 93 | 
            +
                        #
         | 
| 94 | 
            +
                        # Multiplies the `fuel per segment` (*kg fuel*) by the `segments per trip` and the number of `trips` to give *kg fuel*.
         | 
| 75 95 | 
             
                        quorum 'from fuel per segment and segments per trip and trips', :needs => [:fuel_per_segment, :segments_per_trip, :trips], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 76 96 | 
             
                          characteristics[:fuel_per_segment] * characteristics[:segments_per_trip].to_f * characteristics[:trips].to_f
         | 
| 77 97 | 
             
                        end
         | 
| 78 98 | 
             
                      end
         | 
| 79 99 |  | 
| 80 | 
            -
                      ### Fuel per segment
         | 
| 81 | 
            -
                      #  | 
| 100 | 
            +
                      ### Fuel per segment calculation
         | 
| 101 | 
            +
                      # Returns the `fuel per segment` in *kg fuel*.
         | 
| 82 102 | 
             
                      committee :fuel_per_segment do
         | 
| 83 | 
            -
                         | 
| 84 | 
            -
                        #  | 
| 103 | 
            +
                        #### Fuel per segment from adjusted distance per segment and fuel use coefficients
         | 
| 104 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 105 | 
            +
                        #
         | 
| 106 | 
            +
                        # Uses a third-order polynomial equation to calculate the fuel used per segment:
         | 
| 85 107 | 
             
                        #
         | 
| 86 108 | 
             
                        # (m<sub>3</sub> * d^3 ) + (m<sub>2</sub> * d^2 ) + (m<sub>1</sub> * d) + endpoint fuel
         | 
| 87 109 | 
             
                        #
         | 
| @@ -94,32 +116,38 @@ module BrighterPlanet | |
| 94 116 | 
             
                        end
         | 
| 95 117 | 
             
                      end
         | 
| 96 118 |  | 
| 97 | 
            -
                      ### Adjusted distance per segment
         | 
| 98 | 
            -
                      #  | 
| 119 | 
            +
                      ### Adjusted distance per segment calculation
         | 
| 120 | 
            +
                      # Returns the `adjusted distance per segment` in *nautical miles*.
         | 
| 99 121 | 
             
                      committee :adjusted_distance_per_segment do
         | 
| 100 | 
            -
                         | 
| 101 | 
            -
                        #  | 
| 122 | 
            +
                        #### Adjusted distance per segment from adjusted distance and segments per trip
         | 
| 123 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 124 | 
            +
                        #
         | 
| 125 | 
            +
                        # Divides the `adjusted distance` (*nautical miles*) by `segments per trip` to give *nautical miles*.
         | 
| 102 126 | 
             
                        quorum 'from adjusted distance and segments per trip', :needs => [:adjusted_distance, :segments_per_trip], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 103 127 | 
             
                          characteristics[:adjusted_distance] / characteristics[:segments_per_trip]
         | 
| 104 128 | 
             
                        end
         | 
| 105 129 | 
             
                      end
         | 
| 106 130 |  | 
| 107 | 
            -
                      ### Adjusted distance
         | 
| 108 | 
            -
                      #  | 
| 131 | 
            +
                      ### Adjusted distance calculation
         | 
| 132 | 
            +
                      # Returns the `adjusted distance` in *nautical miles*.
         | 
| 109 133 | 
             
                      # The `adjusted distance` accounts for factors that increase the actual distance traveled by real world flights.
         | 
| 110 134 | 
             
                      committee :adjusted_distance do
         | 
| 111 | 
            -
                         | 
| 112 | 
            -
                        #  | 
| 135 | 
            +
                        #### Adjusted distance from distance, route inefficiency factor, and dogleg factor
         | 
| 136 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 137 | 
            +
                        #
         | 
| 138 | 
            +
                        # Multiplies `distance` (*nautical miles*) by a `route inefficiency factor` and a `dogleg factor` to give *nautical miles*.
         | 
| 113 139 | 
             
                        quorum 'from distance, route inefficiency factor, and dogleg factor', :needs => [:distance, :route_inefficiency_factor, :dogleg_factor], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 114 140 | 
             
                          characteristics[:distance] * characteristics[:route_inefficiency_factor] * characteristics[:dogleg_factor]
         | 
| 115 141 | 
             
                        end
         | 
| 116 142 | 
             
                      end
         | 
| 117 143 |  | 
| 118 | 
            -
                      ### Distance
         | 
| 119 | 
            -
                      #  | 
| 144 | 
            +
                      ### Distance calculation
         | 
| 145 | 
            +
                      # Returns the flight's base `distance` in *nautical miles*.
         | 
| 120 146 | 
             
                      committee :distance do
         | 
| 121 | 
            -
                         | 
| 122 | 
            -
                        #  | 
| 147 | 
            +
                        #### Distance from airports
         | 
| 148 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 149 | 
            +
                        #
         | 
| 150 | 
            +
                        # Calculates the great circle distance between the `origin airport` and `destination airport` and converts from *km* to *nautical miles*.
         | 
| 123 151 | 
             
                        quorum 'from airports', :needs => [:origin_airport, :destination_airport], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 124 152 | 
             
                          if  characteristics[:origin_airport].latitude and
         | 
| 125 153 | 
             
                              characteristics[:origin_airport].longitude and
         | 
| @@ -129,70 +157,88 @@ module BrighterPlanet | |
| 129 157 | 
             
                          end
         | 
| 130 158 | 
             
                        end
         | 
| 131 159 |  | 
| 132 | 
            -
                         | 
| 133 | 
            -
                        #  | 
| 160 | 
            +
                        #### Distance from distance estimate
         | 
| 161 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 162 | 
            +
                        #
         | 
| 163 | 
            +
                        # Converts the `distance_estimate` in *km* to *nautical miles*.
         | 
| 134 164 | 
             
                        quorum 'from distance estimate', :needs => :distance_estimate, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 135 165 | 
             
                          characteristics[:distance_estimate].kilometres.to :nautical_miles
         | 
| 136 166 | 
             
                        end
         | 
| 137 167 |  | 
| 138 | 
            -
                         | 
| 139 | 
            -
                        #  | 
| 168 | 
            +
                        #### Distance from distance class
         | 
| 169 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 170 | 
            +
                        #
         | 
| 171 | 
            +
                        # Looks up the [distance class](http://data.brighterplanet.com/flight_distance_classes)' `distance` and converts from *km* to *nautical miles*.
         | 
| 140 172 | 
             
                        quorum 'from distance class', :needs => :distance_class, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 141 173 | 
             
                          characteristics[:distance_class].distance.kilometres.to :nautical_miles
         | 
| 142 174 | 
             
                        end
         | 
| 143 175 |  | 
| 144 | 
            -
                         | 
| 145 | 
            -
                        #  | 
| 176 | 
            +
                        #### Distance from cohort
         | 
| 177 | 
            +
                        # **Complies:**
         | 
| 178 | 
            +
                        #
         | 
| 179 | 
            +
                        # Calculates the average `distance` of the `cohort` segments, weighted by their passengers, and converts from *km* to *nautical miles*.
         | 
| 146 180 | 
             
                        quorum 'from cohort', :needs => :cohort do |characteristics| # cohort here will be some combo of origin, airline, and aircraft
         | 
| 147 181 | 
             
                          distance = characteristics[:cohort].weighted_average(:distance, :weighted_by => :passengers).kilometres.to(:nautical_miles)
         | 
| 148 182 | 
             
                          distance > 0 ? distance : nil
         | 
| 149 183 | 
             
                        end
         | 
| 150 184 |  | 
| 151 | 
            -
                         | 
| 152 | 
            -
                        #  | 
| 185 | 
            +
                        #### Default distance
         | 
| 186 | 
            +
                        # **Complies:**
         | 
| 187 | 
            +
                        #
         | 
| 188 | 
            +
                        # Calculates the average `distance` of [all segments in the T-100 database](http://data.brighterplanet.com/flight_segments), weighted by their passengers, and converts from *km* to *nautical miles*.
         | 
| 153 189 | 
             
                        quorum 'default' do
         | 
| 154 190 | 
             
                          FlightSegment.fallback.distance.kilometres.to :nautical_miles
         | 
| 155 191 | 
             
                        end
         | 
| 156 192 | 
             
                      end
         | 
| 157 193 |  | 
| 158 | 
            -
                      ### Route inefficiency factor
         | 
| 159 | 
            -
                      # This calculation returns the `route inefficiency factor | 
| 194 | 
            +
                      ### Route inefficiency factor calculation
         | 
| 195 | 
            +
                      # This calculation returns the `route inefficiency factor`.
         | 
| 196 | 
            +
                      # This is a measure of how much farther real world flights travel than the great circle distance between their origin and destination.
         | 
| 160 197 | 
             
                      # It accounts for factors like flight path routing around controlled airspace and circling while waiting for clearance to land.
         | 
| 161 198 | 
             
                      committee :route_inefficiency_factor do
         | 
| 162 | 
            -
                         | 
| 163 | 
            -
                        #  | 
| 199 | 
            +
                        #### Route inefficiency factor from country
         | 
| 200 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 201 | 
            +
                        #
         | 
| 202 | 
            +
                        # Looks up the `route inefficiency factor` for the [country](http://data.brighterplanet.com/countries) in which the flight occurs.
         | 
| 164 203 | 
             
                        quorum 'from country', :needs => :country, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 165 204 | 
             
                          characteristics[:country].andand.flight_route_inefficiency_factor
         | 
| 166 205 | 
             
                        end
         | 
| 167 206 |  | 
| 168 | 
            -
                         | 
| 169 | 
            -
                        #  | 
| 207 | 
            +
                        #### Default route inefficiency factor
         | 
| 208 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 209 | 
            +
                        #
         | 
| 210 | 
            +
                        # Uses a `route inefficiency factor` of **10%** based on [Kettunen et al. (2005)](http://www.atmseminar.org/seminarContent/seminar6/papers/p_055_MPM.pdf)
         | 
| 170 211 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 171 212 | 
             
                          Country.fallback.flight_route_inefficiency_factor
         | 
| 172 213 | 
             
                        end
         | 
| 173 214 | 
             
                      end
         | 
| 174 215 |  | 
| 175 | 
            -
                      ### Dogleg factor
         | 
| 176 | 
            -
                      #  | 
| 216 | 
            +
                      ### Dogleg factor calculation
         | 
| 217 | 
            +
                      # Returns the `dogleg factor`.
         | 
| 218 | 
            +
                      # This is a measure of how far out of the way the average layover is compared to a direct flight.
         | 
| 177 219 | 
             
                      committee :dogleg_factor do
         | 
| 178 | 
            -
                         | 
| 179 | 
            -
                        #  | 
| 220 | 
            +
                        #### Dogleg factor from segments per trip
         | 
| 221 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 222 | 
            +
                        #
         | 
| 223 | 
            +
                        # Assumes that each layover increases the total flight distance by **25%**.
         | 
| 180 224 | 
             
                        quorum 'from segments per trip', :needs => :segments_per_trip, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 181 | 
            -
                           | 
| 225 | 
            +
                          1.25 ** (characteristics[:segments_per_trip] - 1)
         | 
| 182 226 | 
             
                        end
         | 
| 183 227 | 
             
                      end
         | 
| 184 228 |  | 
| 185 | 
            -
                      ### Distance estimate
         | 
| 186 | 
            -
                      #  | 
| 229 | 
            +
                      ### Distance estimate calculation
         | 
| 230 | 
            +
                      # Returns the client-input `distance estimate` in *km*.
         | 
| 187 231 |  | 
| 188 | 
            -
                      ### Distance class
         | 
| 189 | 
            -
                      #  | 
| 232 | 
            +
                      ### Distance class calculation
         | 
| 233 | 
            +
                      # Returns the client-input [distance class](http://data.brighterplanet.com/distance_classes).
         | 
| 190 234 |  | 
| 191 | 
            -
                      ### Fuel use coefficients
         | 
| 192 | 
            -
                      #  | 
| 235 | 
            +
                      ### Fuel use coefficients calculation
         | 
| 236 | 
            +
                      # Returns the `fuel use coefficients`. These are the coefficients of the third-order polynomial equation that describes aircraft fuel use.
         | 
| 193 237 | 
             
                      committee :fuel_use_coefficients do
         | 
| 194 | 
            -
                         | 
| 195 | 
            -
                        #  | 
| 238 | 
            +
                        #### Fuel use coefficients from aircraft
         | 
| 239 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 240 | 
            +
                        #
         | 
| 241 | 
            +
                        # Looks up the [aircraft](http://data.brighterplanet.com/aircraft)'s `fuel use coefficients`.
         | 
| 196 242 | 
             
                        quorum 'from aircraft', :needs => :aircraft, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 197 243 | 
             
                          aircraft = characteristics[:aircraft]
         | 
| 198 244 | 
             
                          fuel_use = FuelUseEquation.new aircraft.m3, aircraft.m2, aircraft.m1, aircraft.endpoint_fuel
         | 
| @@ -203,15 +249,20 @@ module BrighterPlanet | |
| 203 249 | 
             
                          end
         | 
| 204 250 | 
             
                        end
         | 
| 205 251 |  | 
| 206 | 
            -
                         | 
| 207 | 
            -
                        #  | 
| 252 | 
            +
                        #### Fuel use coefficients from aircraft class
         | 
| 253 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 254 | 
            +
                        #
         | 
| 255 | 
            +
                        # Looks up the [aircraft class](http://data.brighterplanet.com/aircraft_classes)' `fuel use coefficients`.
         | 
| 208 256 | 
             
                        quorum 'from aircraft class', :needs => :aircraft_class, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 209 257 | 
             
                          aircraft_class = characteristics[:aircraft_class]
         | 
| 210 258 | 
             
                          FuelUseEquation.new aircraft_class.m3, aircraft_class.m2, aircraft_class.m1, aircraft_class.endpoint_fuel
         | 
| 211 259 | 
             
                        end
         | 
| 212 260 |  | 
| 213 | 
            -
                         | 
| 214 | 
            -
                        #  | 
| 261 | 
            +
                        #### Fuel use coefficients from cohort
         | 
| 262 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 263 | 
            +
                        #
         | 
| 264 | 
            +
                        # Calculates the average `fuel use coefficients` of the aircraft used by the `cohort` segments, weighted by the segment passengers.
         | 
| 265 | 
            +
                        # If an aircraft does not have `fuel use coefficients`, it takes the `fuel use coefficients` for the aircraft's [aircraft class](http://data.brighterplanet.com/aircraft_classes).
         | 
| 215 266 | 
             
                        quorum 'from cohort', :needs => :cohort, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 216 267 | 
             
                          flight_segments = characteristics[:cohort]
         | 
| 217 268 |  | 
| @@ -219,119 +270,102 @@ module BrighterPlanet | |
| 219 270 | 
             
                            passengers + flight_segment.passengers
         | 
| 220 271 | 
             
                          end
         | 
| 221 272 |  | 
| 222 | 
            -
                          bts_codes = flight_segments.map(&: | 
| 223 | 
            -
                          relevant_aircraft = Aircraft. | 
| 224 | 
            -
                            hsh[aircraft. | 
| 273 | 
            +
                          bts_codes = flight_segments.map(&:aircraft_bts_code).uniq
         | 
| 274 | 
            +
                          relevant_aircraft = Aircraft.find_all_by_bts_code(bts_codes).inject({}) do |hsh, aircraft|
         | 
| 275 | 
            +
                            hsh[aircraft.bts_code] = aircraft
         | 
| 225 276 | 
             
                            hsh
         | 
| 226 277 | 
             
                          end
         | 
| 227 | 
            -
             | 
| 228 | 
            -
             | 
| 229 | 
            -
                             | 
| 230 | 
            -
             | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 233 | 
            -
             | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 236 | 
            -
             | 
| 237 | 
            -
                              aircraft = flight_segment_aircraft[flight_segment.row_hash]
         | 
| 238 | 
            -
                              aircraft_m3 = aircraft.andand.m3 || 0
         | 
| 239 | 
            -
                              m3 + (aircraft_m3 * flight_segment.passengers)
         | 
| 240 | 
            -
                            end
         | 
| 241 | 
            -
                          else
         | 
| 242 | 
            -
                            m3 = Aircraft.fallback.m3
         | 
| 243 | 
            -
                          end
         | 
| 244 | 
            -
                          
         | 
| 245 | 
            -
                          if flight_segment_aircraft.values.map(&:m2).any?
         | 
| 246 | 
            -
                            m2 = flight_segments.inject(0) do |m2, flight_segment|
         | 
| 247 | 
            -
                              aircraft = flight_segment_aircraft[flight_segment.row_hash]
         | 
| 248 | 
            -
                              aircraft_m2 = aircraft.andand.m2 || 0
         | 
| 249 | 
            -
                              m2 + (aircraft_m2 * flight_segment.passengers)
         | 
| 250 | 
            -
                            end
         | 
| 251 | 
            -
                          else
         | 
| 252 | 
            -
                            m2 = Aircraft.fallback.m2
         | 
| 253 | 
            -
                          end
         | 
| 254 | 
            -
                          
         | 
| 255 | 
            -
                          if flight_segment_aircraft.values.map(&:m1).any?
         | 
| 256 | 
            -
                            m1 = flight_segments.inject(0) do |m1, flight_segment|
         | 
| 257 | 
            -
                              aircraft = flight_segment_aircraft[flight_segment.row_hash]
         | 
| 258 | 
            -
                              aircraft_m1 = aircraft.andand.m1 || 0
         | 
| 259 | 
            -
                              m1 + (aircraft_m1 * flight_segment.passengers)
         | 
| 260 | 
            -
                            end
         | 
| 261 | 
            -
                          else
         | 
| 262 | 
            -
                            m1 = Aircraft.fallback.m1
         | 
| 263 | 
            -
                          end
         | 
| 264 | 
            -
                          
         | 
| 265 | 
            -
                          if flight_segment_aircraft.values.map(&:endpoint_fuel).any?
         | 
| 266 | 
            -
                            endpoint_fuel = flight_segments.inject(0) do |endpoint_fuel, flight_segment|
         | 
| 267 | 
            -
                              aircraft = flight_segment_aircraft[flight_segment.row_hash]
         | 
| 268 | 
            -
                              aircraft_epfuel = aircraft.andand.endpoint_fuel || 0
         | 
| 269 | 
            -
                              endpoint_fuel + (aircraft_epfuel * flight_segment.passengers)
         | 
| 278 | 
            +
             | 
| 279 | 
            +
                          sum_coefficients = lambda do |name|
         | 
| 280 | 
            +
                            flight_segments.inject(0) do |coefficient, flight_segment|
         | 
| 281 | 
            +
                              bts_code = flight_segment.aircraft_bts_code.to_s
         | 
| 282 | 
            +
                              aircraft = relevant_aircraft[bts_code]
         | 
| 283 | 
            +
                              aircraft_coefficient = aircraft.send(name)
         | 
| 284 | 
            +
                              if aircraft_coefficient.nil? or aircraft_coefficient.zero?
         | 
| 285 | 
            +
                                aircraft_coefficient = aircraft.aircraft_class.send(name)
         | 
| 286 | 
            +
                              end
         | 
| 287 | 
            +
                              coefficient + (aircraft_coefficient * flight_segment.passengers)
         | 
| 270 288 | 
             
                            end
         | 
| 271 | 
            -
                          else
         | 
| 272 | 
            -
                            endpoint_fuel = Aircraft.fallback.endpoint_fuel
         | 
| 273 289 | 
             
                          end
         | 
| 290 | 
            +
             | 
| 291 | 
            +
                          m3 = sum_coefficients.call(:m3) / passengers
         | 
| 292 | 
            +
                          m2 = sum_coefficients.call(:m2) / passengers
         | 
| 293 | 
            +
                          m1 = sum_coefficients.call(:m1) / passengers
         | 
| 294 | 
            +
                          endpoint_fuel = sum_coefficients.call(:endpoint_fuel) / passengers
         | 
| 274 295 |  | 
| 275 | 
            -
                           | 
| 276 | 
            -
                            m3 = m3 / passengers
         | 
| 277 | 
            -
                            m2 = m2 / passengers
         | 
| 278 | 
            -
                            m1 = m1 / passengers
         | 
| 279 | 
            -
                            endpoint_fuel = endpoint_fuel / passengers
         | 
| 280 | 
            -
                            
         | 
| 281 | 
            -
                            FuelUseEquation.new m3, m2, m1, endpoint_fuel
         | 
| 282 | 
            -
                          end
         | 
| 296 | 
            +
                          FuelUseEquation.new m3, m2, m1, endpoint_fuel
         | 
| 283 297 | 
             
                        end
         | 
| 284 298 |  | 
| 285 | 
            -
                         | 
| 286 | 
            -
                        #  | 
| 299 | 
            +
                        #### Default fuel use coefficients
         | 
| 300 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 301 | 
            +
                        #
         | 
| 302 | 
            +
                        # Calculates the average `fuel use coefficients` of the aircraft used by [all segments in the T-100 database](http://data.brighterplanet.com/flight_segments), weighted by the segment passengers.
         | 
| 303 | 
            +
                        # If an aircraft does not have `fuel use coefficients`, it takes the `fuel use coefficients` for the aircraft's [aircraft class](http://data.brighterplanet.com/aircraft_classes).
         | 
| 287 304 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 288 | 
            -
                          fallback  | 
| 289 | 
            -
                          if fallback
         | 
| 290 | 
            -
                            FuelUseEquation.new fallback.m3, fallback.m2, fallback.m1, fallback.endpoint_fuel
         | 
| 291 | 
            -
                          end
         | 
| 305 | 
            +
                          FuelUseEquation.new Aircraft.fallback.m3, Aircraft.fallback.m2, Aircraft.fallback.m1, Aircraft.fallback.endpoint_fuel
         | 
| 292 306 | 
             
                        end
         | 
| 293 307 | 
             
                      end
         | 
| 294 308 |  | 
| 295 | 
            -
                      ### Fuel type
         | 
| 296 | 
            -
                      #  | 
| 309 | 
            +
                      ### Fuel type calculation
         | 
| 310 | 
            +
                      # Returns the `fuel type`.
         | 
| 297 311 | 
             
                      committee :fuel_type do
         | 
| 298 | 
            -
                         | 
| 299 | 
            -
                        #  | 
| 312 | 
            +
                        #### Fuel type from client input
         | 
| 313 | 
            +
                        # **Complies:** All
         | 
| 314 | 
            +
                        #
         | 
| 315 | 
            +
                        # Uses the client-input [fuel type](http://data.brighterplanet.com/fuel_types).
         | 
| 300 316 |  | 
| 301 | 
            -
                         | 
| 302 | 
            -
                        #  | 
| 303 | 
            -
                         | 
| 317 | 
            +
                        #### Default fuel type
         | 
| 318 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 319 | 
            +
                        #
         | 
| 320 | 
            +
                        # Assumes the flight uses **Jet Fuel**.
         | 
| 321 | 
            +
                        quorum 'default', :complies => [:ghg_protocol, :ico, :tcr] do
         | 
| 304 322 | 
             
                          FuelType.find_by_name 'Jet Fuel'
         | 
| 305 323 | 
             
                        end
         | 
| 306 324 | 
             
                      end
         | 
| 307 325 |  | 
| 308 | 
            -
                      ### Passengers
         | 
| 309 | 
            -
                      #  | 
| 326 | 
            +
                      ### Passengers calculation
         | 
| 327 | 
            +
                      # Returns the number of `passengers`.
         | 
| 310 328 | 
             
                      committee :passengers do
         | 
| 311 | 
            -
                         | 
| 312 | 
            -
                        #  | 
| 329 | 
            +
                        #### Passengers from seats and load factor
         | 
| 330 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 331 | 
            +
                        #
         | 
| 332 | 
            +
                        # Multiplies the number of `seats` by the `load factor`.
         | 
| 313 333 | 
             
                        quorum 'from seats and load factor', :needs => [:seats, :load_factor], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 314 334 | 
             
                          (characteristics[:seats] * characteristics[:load_factor]).round
         | 
| 315 335 | 
             
                        end
         | 
| 316 336 | 
             
                      end
         | 
| 317 337 |  | 
| 318 | 
            -
                      ### Seats
         | 
| 319 | 
            -
                      #  | 
| 338 | 
            +
                      ### Seats calculation
         | 
| 339 | 
            +
                      # Returns the number of `seats`.
         | 
| 320 340 | 
             
                      committee :seats do
         | 
| 321 | 
            -
                         | 
| 322 | 
            -
                        #  | 
| 341 | 
            +
                        #### Seats from seats estimate
         | 
| 342 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 343 | 
            +
                        #
         | 
| 344 | 
            +
                        # Uses the client-input estimate of the number of `seats`.
         | 
| 345 | 
            +
                        quorum 'from seats estimate', :needs => :seats_estimate, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 346 | 
            +
                          characteristics[:seats_estimate]
         | 
| 347 | 
            +
                        end
         | 
| 348 | 
            +
                        
         | 
| 349 | 
            +
                        #### Seats from aircraft
         | 
| 350 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 351 | 
            +
                        #
         | 
| 352 | 
            +
                        # Looks up the [aircraft](http://data.brighterplanet.com/aircraft)'s average number of `seats`.
         | 
| 323 353 | 
             
                        quorum 'from aircraft', :needs => :aircraft, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 324 354 | 
             
                          characteristics[:aircraft].seats
         | 
| 325 355 | 
             
                        end
         | 
| 326 356 |  | 
| 327 | 
            -
                         | 
| 328 | 
            -
                        #  | 
| 329 | 
            -
                         | 
| 330 | 
            -
             | 
| 357 | 
            +
                        #### Seats from aircraft class
         | 
| 358 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 359 | 
            +
                        #
         | 
| 360 | 
            +
                        # Looks up the [aircraft class](http://data.brighterplanet.com/aircraft_classes)' average number of `seats`.
         | 
| 361 | 
            +
                        quorum 'from aircraft class', :needs => :aircraft_class, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 362 | 
            +
                          characteristics[:aircraft_class].seats
         | 
| 331 363 | 
             
                        end
         | 
| 332 364 |  | 
| 333 | 
            -
                         | 
| 334 | 
            -
                        #  | 
| 365 | 
            +
                        #### Seats from cohort
         | 
| 366 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 367 | 
            +
                        #
         | 
| 368 | 
            +
                        # Calculates the average number of `seats` of the `cohort` segments, weighted by their passengers.
         | 
| 335 369 | 
             
                        quorum 'from cohort', :needs => :cohort, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 336 370 | 
             
                          seats = characteristics[:cohort].weighted_average :seats, :weighted_by => :passengers
         | 
| 337 371 | 
             
                          if seats.nil? or seats.zero?
         | 
| @@ -341,121 +375,156 @@ module BrighterPlanet | |
| 341 375 | 
             
                          end
         | 
| 342 376 | 
             
                        end
         | 
| 343 377 |  | 
| 344 | 
            -
                         | 
| 345 | 
            -
                        #  | 
| 346 | 
            -
                         | 
| 347 | 
            -
             | 
| 348 | 
            -
                         | 
| 349 | 
            -
             | 
| 350 | 
            -
                        ##### Default
         | 
| 351 | 
            -
                        # This default method calculates the average number of `seats` of [all segments in the T-100 database](http://data.brighterplanet.com/flight_segments), weighted by their passengers.
         | 
| 352 | 
            -
                        quorum 'default' do
         | 
| 353 | 
            -
                          FlightSegment.fallback.seats.to_f # need before_type_cast b/c seats is an integer but the fallback value is a float
         | 
| 378 | 
            +
                        #### Default seats
         | 
| 379 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 380 | 
            +
                        #
         | 
| 381 | 
            +
                        # Calculates the average number of `seats` of [all segments in the T-100 database](http://data.brighterplanet.com/flight_segments), weighted by their passengers.
         | 
| 382 | 
            +
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 383 | 
            +
                          FlightSegment.fallback.seats
         | 
| 354 384 | 
             
                        end
         | 
| 355 385 | 
             
                      end
         | 
| 356 386 |  | 
| 357 | 
            -
                      ### Seats estimate
         | 
| 358 | 
            -
                      #  | 
| 387 | 
            +
                      ### Seats estimate calculation
         | 
| 388 | 
            +
                      # Returns the client-input `seats estimate`.
         | 
| 359 389 |  | 
| 360 | 
            -
                      ### Load factor
         | 
| 361 | 
            -
                      #  | 
| 362 | 
            -
                      #  | 
| 390 | 
            +
                      ### Load factor calculation
         | 
| 391 | 
            +
                      # Returns the `load factor`.
         | 
| 392 | 
            +
                      # This is the portion of available seats that are occupied.
         | 
| 363 393 | 
             
                      committee :load_factor do
         | 
| 364 | 
            -
                         | 
| 365 | 
            -
                        #  | 
| 394 | 
            +
                        #### Load factor from client input
         | 
| 395 | 
            +
                        # **Complies:** All
         | 
| 396 | 
            +
                        #
         | 
| 397 | 
            +
                        # Uses the client-input `load factor`.
         | 
| 366 398 |  | 
| 367 | 
            -
                         | 
| 368 | 
            -
                        #  | 
| 399 | 
            +
                        #### Load factor from cohort
         | 
| 400 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 401 | 
            +
                        #
         | 
| 402 | 
            +
                        # Calculates the average `load factor` of the `cohort` segments, weighted by their passengers.
         | 
| 369 403 | 
             
                        quorum 'from cohort', :needs => :cohort, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 370 404 | 
             
                          characteristics[:cohort].weighted_average(:load_factor, :weighted_by => :passengers)
         | 
| 371 405 | 
             
                        end
         | 
| 372 406 |  | 
| 373 | 
            -
                         | 
| 374 | 
            -
                        #  | 
| 407 | 
            +
                        #### Default load factor
         | 
| 408 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 409 | 
            +
                        #
         | 
| 410 | 
            +
                        # Calculates the average `load factor` of [all segments in the T-100 database](http://data.brighterplanet.com/flight_segments), weighted by their passengers.
         | 
| 375 411 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 376 412 | 
             
                          FlightSegment.fallback.load_factor
         | 
| 377 413 | 
             
                        end
         | 
| 378 414 | 
             
                      end
         | 
| 379 415 |  | 
| 380 | 
            -
                      ### Freight share
         | 
| 381 | 
            -
                      #  | 
| 382 | 
            -
                      #  | 
| 416 | 
            +
                      ### Freight share calculation
         | 
| 417 | 
            +
                      # Returns the `freight share`.
         | 
| 418 | 
            +
                      # This is the percent of the total aircraft weight that is freight cargo and mail (as opposed to passengers and their baggage).
         | 
| 383 419 | 
             
                      committee :freight_share do
         | 
| 384 | 
            -
                         | 
| 385 | 
            -
                        #  | 
| 420 | 
            +
                        #### Freight share from cohort
         | 
| 421 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 422 | 
            +
                        #
         | 
| 423 | 
            +
                        # Calculates the average `freight share` of the `cohort` segments, weighted by their passengers.
         | 
| 386 424 | 
             
                        quorum 'from cohort', :needs => :cohort, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 387 425 | 
             
                          characteristics[:cohort].weighted_average(:freight_share, :weighted_by => :passengers)
         | 
| 388 426 | 
             
                        end
         | 
| 389 427 |  | 
| 390 | 
            -
                         | 
| 391 | 
            -
                        #  | 
| 428 | 
            +
                        #### Default freight share
         | 
| 429 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 430 | 
            +
                        #
         | 
| 431 | 
            +
                        # Calculates the average `freight share` of [all segments in the T-100 database](http://data.brighterplanet.com/flight_segments), weighted by their passengers.
         | 
| 392 432 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 393 433 | 
             
                          FlightSegment.fallback.freight_share
         | 
| 394 434 | 
             
                        end
         | 
| 395 435 | 
             
                      end
         | 
| 396 436 |  | 
| 397 | 
            -
                      ### Trips
         | 
| 398 | 
            -
                      #  | 
| 437 | 
            +
                      ### Trips calculation
         | 
| 438 | 
            +
                      # Returns the number of `trips`.
         | 
| 399 439 | 
             
                      # A one-way flight has one trip; a round-trip flight has two trips.
         | 
| 400 440 | 
             
                      committee :trips do
         | 
| 401 | 
            -
                         | 
| 402 | 
            -
                        #  | 
| 441 | 
            +
                        #### Trips from client input
         | 
| 442 | 
            +
                        # **Complies:** All
         | 
| 443 | 
            +
                        #
         | 
| 444 | 
            +
                        # Uses the client-input number of `trips`.
         | 
| 403 445 |  | 
| 404 | 
            -
                         | 
| 405 | 
            -
                        #  | 
| 446 | 
            +
                        #### Default trips
         | 
| 447 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 448 | 
            +
                        #
         | 
| 449 | 
            +
                        # Uses an average number of `trips` of **1.941**, taken from the [U.S. National Household Travel Survey](http://www.bts.gov/publications/america_on_the_go/long_distance_transportation_patterns/html/table_07.html).
         | 
| 406 450 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 407 | 
            -
                           | 
| 451 | 
            +
                          1.941
         | 
| 408 452 | 
             
                        end
         | 
| 409 453 | 
             
                      end
         | 
| 410 454 |  | 
| 411 | 
            -
                      ### Seat class multiplier
         | 
| 412 | 
            -
                      #  | 
| 455 | 
            +
                      ### Seat class multiplier calculation
         | 
| 456 | 
            +
                      # Returns the `seat class multiplier`. This reflects the amount of cabin space occupied by the passenger's seat.
         | 
| 413 457 | 
             
                      committee :seat_class_multiplier do
         | 
| 414 | 
            -
                         | 
| 415 | 
            -
                        #  | 
| 458 | 
            +
                        #### Seat class multiplier from seat class
         | 
| 459 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 460 | 
            +
                        #
         | 
| 461 | 
            +
                        # Looks up the [seat class](http://data.brighterplanet.com/flight_seat_classes)' `seat class multiplier`.
         | 
| 416 462 | 
             
                        quorum 'from seat class', :needs => :seat_class, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 417 463 | 
             
                          characteristics[:seat_class].multiplier
         | 
| 418 464 | 
             
                        end
         | 
| 419 465 |  | 
| 420 | 
            -
                         | 
| 421 | 
            -
                        #  | 
| 466 | 
            +
                        #### Default seat class multiplier
         | 
| 467 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 468 | 
            +
                        #
         | 
| 469 | 
            +
                        # Uses a `seat class multiplier` of **1**.
         | 
| 422 470 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 423 471 | 
             
                          FlightSeatClass.fallback.multiplier
         | 
| 424 472 | 
             
                        end
         | 
| 425 473 | 
             
                      end
         | 
| 426 474 |  | 
| 427 | 
            -
                      ### Seat class
         | 
| 428 | 
            -
                      #  | 
| 475 | 
            +
                      ### Seat class calculation
         | 
| 476 | 
            +
                      # Returns the client-input [seat class](http://data.brighterplanet.com/seat_classes).
         | 
| 429 477 |  | 
| 430 | 
            -
                      ### Country
         | 
| 431 | 
            -
                      #  | 
| 478 | 
            +
                      ### Country calculation
         | 
| 479 | 
            +
                      # Returns the [country](http://data.brighterplanet.com/countries) in which a flight occurs.
         | 
| 432 480 | 
             
                      committee :country do
         | 
| 433 | 
            -
                         | 
| 434 | 
            -
                        #  | 
| 481 | 
            +
                        #### Country from client input
         | 
| 482 | 
            +
                        # **Complies:** All
         | 
| 483 | 
            +
                        #
         | 
| 484 | 
            +
                        # Uses the client-input [country](http://data.brighterplanet.com/countries).
         | 
| 485 | 
            +
                        
         | 
| 486 | 
            +
                        #### Country from origin airport and destination airport
         | 
| 487 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 488 | 
            +
                        #
         | 
| 489 | 
            +
                        # Checks whether the flight's `origin airport` and `destination airport` are within the same country.
         | 
| 435 490 | 
             
                        # If so, that country is the `country`.
         | 
| 436 491 | 
             
                        quorum 'from origin airport and destination airport', :needs => [:origin_airport, :destination_airport], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 437 492 | 
             
                          if characteristics[:origin_airport].country == characteristics[:destination_airport].country
         | 
| 438 493 | 
             
                            characteristics[:origin_airport].country
         | 
| 439 494 | 
             
                          end
         | 
| 440 495 | 
             
                        end
         | 
| 496 | 
            +
                      end
         | 
| 497 | 
            +
                      
         | 
| 498 | 
            +
                      ### Aircraft Class calculation
         | 
| 499 | 
            +
                      # This calculation returns the [aircraft class](http://data.brighterplanet.com/aircraft_classes).
         | 
| 500 | 
            +
                      committee :aircraft_class do
         | 
| 501 | 
            +
                        #### Aircraft class from client input
         | 
| 502 | 
            +
                        # **Complies:** All
         | 
| 503 | 
            +
                        #
         | 
| 504 | 
            +
                        # Uses the client-input [aircraft_class](http://data.brighterplanet.com/aircraft_classes).
         | 
| 441 505 |  | 
| 442 | 
            -
                         | 
| 443 | 
            -
                        #  | 
| 506 | 
            +
                        #### Aircraft class from aircraft
         | 
| 507 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 508 | 
            +
                        #
         | 
| 509 | 
            +
                        # Looks up the [aircraft](http://data.brighterplanet.com/aircraft)'s [aircraft_class](http://data.brighterplanet.com/aircraft_classes).
         | 
| 510 | 
            +
                        quorum 'from aircraft', :needs => :aircraft, :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 511 | 
            +
                          characteristics[:aircraft].aircraft_class
         | 
| 512 | 
            +
                        end
         | 
| 444 513 | 
             
                      end
         | 
| 445 514 |  | 
| 446 | 
            -
                      ### Cohort
         | 
| 447 | 
            -
                      #  | 
| 515 | 
            +
                      ### Cohort calculation
         | 
| 516 | 
            +
                      # Returns the `cohort`.
         | 
| 517 | 
            +
                      # This is a set of flight segment records in the [T-100 database](http://data.brighterplanet.com/flight_segments) that match certain client-input values.
         | 
| 448 518 | 
             
                      committee :cohort do
         | 
| 449 | 
            -
                         | 
| 450 | 
            -
                        #  | 
| 451 | 
            -
                        #
         | 
| 452 | 
            -
                        # 1. Checks that the flight is direct
         | 
| 453 | 
            -
                        # 2. Takes the input values for `origin airport`, `destination airport`, `aircraft`, and `airline`
         | 
| 454 | 
            -
                        # 3. Selects all the records in the T-100 database that match the available input values
         | 
| 455 | 
            -
                        # 4. Drops the last input value (initially `airline`, then `aircraft`, etc.) if no records match all of the available input values
         | 
| 456 | 
            -
                        # 5. Repeats steps 3 and 4 until some records match or no input values remain
         | 
| 519 | 
            +
                        #### Cohort from segments per trip and input
         | 
| 520 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 457 521 | 
             
                        #
         | 
| 458 | 
            -
                        #  | 
| 522 | 
            +
                        # - Checks whether the flight is direct
         | 
| 523 | 
            +
                        # - Takes the input values for `origin airport`, `destination airport`, `aircraft`, and `airline`
         | 
| 524 | 
            +
                        # - Selects all the records in the T-100 database that match the available input values
         | 
| 525 | 
            +
                        # - Drops the last input value (initially `airline`, then `aircraft`, etc.) if no records match all of the available input values
         | 
| 526 | 
            +
                        # - Repeats steps 3 and 4 until some records match or no input values remain
         | 
| 527 | 
            +
                        # - If no records match any of the input values, or if the flight is indirect, then `cohort` is undefined.
         | 
| 459 528 | 
             
                        quorum 'from segments per trip and input', :needs => :segments_per_trip, :appreciates => [:origin_airport, :destination_airport, :aircraft, :airline], :complies => [:ghg_protocol, :iso, :tcr] do |characteristics|
         | 
| 460 529 | 
             
                          cohort = {}
         | 
| 461 530 | 
             
                          if characteristics[:segments_per_trip] == 1
         | 
| @@ -474,53 +543,76 @@ module BrighterPlanet | |
| 474 543 | 
             
                        end
         | 
| 475 544 | 
             
                      end
         | 
| 476 545 |  | 
| 477 | 
            -
                      ### Origin airport
         | 
| 478 | 
            -
                      #  | 
| 546 | 
            +
                      ### Origin airport calculation
         | 
| 547 | 
            +
                      # Returns the client-input [origin airport](http://data.brighterplanet.com/airports).
         | 
| 479 548 |  | 
| 480 | 
            -
                      ### Destination airport
         | 
| 481 | 
            -
                      #  | 
| 549 | 
            +
                      ### Destination airport calculation
         | 
| 550 | 
            +
                      # Returns the client-input [destination airport](http://data.brighterplanet.com/airports).
         | 
| 482 551 |  | 
| 483 | 
            -
                      ### Aircraft
         | 
| 484 | 
            -
                      #  | 
| 552 | 
            +
                      ### Aircraft calculation
         | 
| 553 | 
            +
                      # Returns the client-input type of [aircraft](http://data.brighterplanet.com/aircraft).
         | 
| 485 554 |  | 
| 486 | 
            -
                      ###  | 
| 487 | 
            -
                      #  | 
| 555 | 
            +
                      ### Airline calculation
         | 
| 556 | 
            +
                      # Returns the client-input [airline](http://data.brighterplanet.com/airlines) operating the flight.
         | 
| 488 557 |  | 
| 489 | 
            -
                      ###  | 
| 490 | 
            -
                      #  | 
| 491 | 
            -
                      
         | 
| 492 | 
            -
                      ### Segments per trip
         | 
| 493 | 
            -
                      # This calculation returns the `segments per trip`.
         | 
| 558 | 
            +
                      ### Segments per trip calculation
         | 
| 559 | 
            +
                      # Returns the `segments per trip`.
         | 
| 494 560 | 
             
                      # Direct flights have a single segment per trip. Indirect flights with one or more layovers have two or more segments per trip.
         | 
| 495 561 | 
             
                      committee :segments_per_trip do
         | 
| 496 | 
            -
                         | 
| 497 | 
            -
                        #  | 
| 562 | 
            +
                        #### Segments per trip from client input
         | 
| 563 | 
            +
                        # **Complies:** All
         | 
| 564 | 
            +
                        #
         | 
| 565 | 
            +
                        # Uses the client-input `segments per trip`.
         | 
| 498 566 |  | 
| 499 | 
            -
                         | 
| 500 | 
            -
                        #  | 
| 567 | 
            +
                        #### Default segments per trip
         | 
| 568 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 569 | 
            +
                        #
         | 
| 570 | 
            +
                        # Uses an average `segments per trip` of **1.67**, calculated from the [U.S. National Household Travel Survey](http://nhts.ornl.gov/).
         | 
| 501 571 | 
             
                        quorum 'default', :complies => [:ghg_protocol, :iso, :tcr] do
         | 
| 502 | 
            -
                           | 
| 572 | 
            +
                          1.67
         | 
| 503 573 | 
             
                        end
         | 
| 504 574 | 
             
                      end
         | 
| 505 575 |  | 
| 506 | 
            -
                      ### Date
         | 
| 507 | 
            -
                      #  | 
| 576 | 
            +
                      ### Date calculation
         | 
| 577 | 
            +
                      # Returns the `date` on which the flight occured.
         | 
| 508 578 | 
             
                      committee :date do
         | 
| 509 | 
            -
                         | 
| 510 | 
            -
                        #  | 
| 579 | 
            +
                        #### Date from client input
         | 
| 580 | 
            +
                        # **Complies:** All
         | 
| 581 | 
            +
                        #
         | 
| 582 | 
            +
                        # Uses the client-input value for `date`.
         | 
| 511 583 |  | 
| 512 | 
            -
                         | 
| 513 | 
            -
                        #  | 
| 584 | 
            +
                        #### Date from timeframe
         | 
| 585 | 
            +
                        # **Complies:** GHG Protocol, ISO-14064-1, Climate Registry Protocol
         | 
| 586 | 
            +
                        #
         | 
| 587 | 
            +
                        # Assumes the flight occured on the first day of the `timeframe`.
         | 
| 514 588 | 
             
                        quorum 'from timeframe', :complies => [:ghg_protocol, :iso, :tcr] do |characteristics, timeframe|
         | 
| 515 589 | 
             
                          timeframe.from
         | 
| 516 590 | 
             
                        end
         | 
| 517 591 | 
             
                      end
         | 
| 592 | 
            +
                      
         | 
| 593 | 
            +
                      ### Timeframe calculation
         | 
| 594 | 
            +
                      # Returns the `timeframe`.
         | 
| 595 | 
            +
                      # This is the period over which to calculate emissions.
         | 
| 596 | 
            +
                        
         | 
| 597 | 
            +
                        #### Timeframe from client input
         | 
| 598 | 
            +
                        # **Complies:** All
         | 
| 599 | 
            +
                        #
         | 
| 600 | 
            +
                        # Uses the client-input value for `timeframe`.
         | 
| 601 | 
            +
                        
         | 
| 602 | 
            +
                        #### Default timeframe
         | 
| 603 | 
            +
                        # **Complies:** All
         | 
| 604 | 
            +
                        #
         | 
| 605 | 
            +
                        # Uses the current calendar year.
         | 
| 518 606 | 
             
                    end
         | 
| 519 607 | 
             
                  end
         | 
| 520 608 |  | 
| 521 609 | 
             
                  class FuelUseEquation < Struct.new(:m3, :m2, :m1, :endpoint_fuel)
         | 
| 522 610 | 
             
                    def empty?
         | 
| 523 | 
            -
                       | 
| 611 | 
            +
                      values.all?(&:nil?) or values.all?(&:zero?)
         | 
| 612 | 
            +
                    end
         | 
| 613 | 
            +
             | 
| 614 | 
            +
                    def values
         | 
| 615 | 
            +
                      [m3, m2, m1, endpoint_fuel]
         | 
| 524 616 | 
             
                    end
         | 
| 525 617 |  | 
| 526 618 | 
             
                    def to_xml(options = {})
         |