Blame view

flaskr/laws/travel_emission_linear_fit.py 4.37 KB
2d6b5394   Antoine Goutenoir   Add an example of...
1
2
3
4
import numpy as np
from geopy.distance import great_circle


8c2482e3   Antoine Goutenoir   Grunt! Grunt! GRUNT.
5
class BaseEmissionModel():
1bbf5d52   Antoine Goutenoir   Implement the sca...
6
7
8
    def __init__(self, config):  # Constructor
        self.name = config.name
        self.slug = config.slug
4c862b54   Antoine Goutenoir   Add a grouped bar...
9
        self.color = config.color
1bbf5d52   Antoine Goutenoir   Implement the sca...
10
        self.config = config.config
2d6b5394   Antoine Goutenoir   Add an example of...
11

1bbf5d52   Antoine Goutenoir   Implement the sca...
12
    def __repr__(self):  # Cast to String
2d6b5394   Antoine Goutenoir   Add an example of...
13
14
        return "Emission model\n" + \
               "==============\n" + \
1bbf5d52   Antoine Goutenoir   Implement the sca...
15
               "%s (%s)" % (self.name, self.slug) + \
2d6b5394   Antoine Goutenoir   Add an example of...
16
17
               repr(self.config)

8c2482e3   Antoine Goutenoir   Grunt! Grunt! GRUNT.
18
19
20
21
22
    # def compute_travel_footprint()


class EmissionModel(BaseEmissionModel):
    # @abc
2d6b5394   Antoine Goutenoir   Add an example of...
23
24
    def compute_travel_footprint(
            self,
1bbf5d52   Antoine Goutenoir   Implement the sca...
25
26
27
28
29
30
31
            origin_latitude,        # degrees
            origin_longitude,       # degrees
            destination_latitude,   # degrees
            destination_longitude,  # degrees
            prefer_train_under_distance=0,  # meters
    ):
        footprint = 0.0
2d6b5394   Antoine Goutenoir   Add an example of...
32
33

        #############################################
8c2482e3   Antoine Goutenoir   Grunt! Grunt! GRUNT.
34
        # TODO: find closest airport(s) and pick one
2d6b5394   Antoine Goutenoir   Add an example of...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
        # We're going to need caching here as well.
        from collections import namedtuple
        origin_airport = namedtuple('Position', [
            'latitude',
            'longitude',
            'address',  # perhaps
        ])
        origin_airport.latitude = origin_latitude
        origin_airport.longitude = origin_longitude
        destination_airport = namedtuple('Position', [
            'latitude',
            'longitude',
            'address',  # perhaps
        ])
        destination_airport.latitude = destination_latitude
        destination_airport.longitude = destination_longitude
        #############################################
        #############################################

1bbf5d52   Antoine Goutenoir   Implement the sca...
54
55
56
57
        # I.a Train travel footprint
        # ... TODO

        # I.b Airplane travel footprint
2d6b5394   Antoine Goutenoir   Add an example of...
58
        footprint += self.compute_airplane_footprint(
1bbf5d52   Antoine Goutenoir   Implement the sca...
59
60
61
62
            origin_latitude=origin_airport.latitude,
            origin_longitude=origin_airport.longitude,
            destination_latitude=destination_airport.latitude,
            destination_longitude=destination_airport.longitude,
2d6b5394   Antoine Goutenoir   Add an example of...
63
64
        )

1bbf5d52   Antoine Goutenoir   Implement the sca...
65
66
67
        # II.a Double the footprint if it's a round-trip
        footprint *= 2.0

2d6b5394   Antoine Goutenoir   Add an example of...
68
69
70
71
        return footprint

    def compute_airplane_footprint(
            self,
1bbf5d52   Antoine Goutenoir   Implement the sca...
72
73
74
75
76
77
            origin_latitude,
            origin_longitude,
            destination_latitude,
            destination_longitude
    ):
        config = self.config.plane_emission_linear_fit
2d6b5394   Antoine Goutenoir   Add an example of...
78

1bbf5d52   Antoine Goutenoir   Implement the sca...
79
        great_circle_distance = self.get_distance_between(
2d6b5394   Antoine Goutenoir   Add an example of...
80
81
82
            origin_latitude, origin_longitude,
            destination_latitude, destination_longitude
        )
1bbf5d52   Antoine Goutenoir   Implement the sca...
83

8c2482e3   Antoine Goutenoir   Grunt! Grunt! GRUNT.
84
85
86
87
        distance = great_circle_distance

        distance = config.connecting_flights_scale * distance

4c745e05   Antoine Goutenoir   Rewire the model ...
88
        footprint = self.compute_airplane_distance_footprint(distance, config)
1bbf5d52   Antoine Goutenoir   Implement the sca...
89

4c745e05   Antoine Goutenoir   Rewire the model ...
90
        return footprint
1bbf5d52   Antoine Goutenoir   Implement the sca...
91

4c745e05   Antoine Goutenoir   Rewire the model ...
92
93
94
95
96
    def compute_airplane_distance_footprint(self, distance, config=None):
        if config is None:
            config = self.config.plane_emission_linear_fit
        distance = distance * config.scale_before + config.offset_before
        footprint = self.apply_scaling_law(distance, config)
8c2482e3   Antoine Goutenoir   Grunt! Grunt! GRUNT.
97
98
        footprint = self.adjust_footprint_for_rfi(footprint, config)

1bbf5d52   Antoine Goutenoir   Implement the sca...
99
100
        return footprint

8c2482e3   Antoine Goutenoir   Grunt! Grunt! GRUNT.
101
102
103
104
    def adjust_footprint_for_rfi(self, footprint, config):
        # Todo: grab data from config merged with form input?
        return config.rfi * footprint

c20659f0   Antoine Goutenoir   Freshen up the AP...
105
    def apply_scaling_law(self, distance, config):
1bbf5d52   Antoine Goutenoir   Implement the sca...
106
        footprint = distance
c20659f0   Antoine Goutenoir   Freshen up the AP...
107
        for interval in config.intervals:
1bbf5d52   Antoine Goutenoir   Implement the sca...
108
109
110
111
112
            if interval.dmin <= distance < interval.dmax:
                offset = interval.offset if interval.offset else 0
                scale = interval.scale if interval.scale else 1
                footprint = footprint * scale + offset
                break
2d6b5394   Antoine Goutenoir   Add an example of...
113
114
115
116
117

        return footprint

    def get_distance_between(
            self,
1bbf5d52   Antoine Goutenoir   Implement the sca...
118
119
120
121
122
            origin_latitude,
            origin_longitude,
            destination_latitude,
            destination_longitude
    ):
2d6b5394   Antoine Goutenoir   Add an example of...
123
124
125
126
127
128
129
130
131
132
133
134
135
        """
        :param origin_latitude:
        :param origin_longitude:
        :param destination_latitude:
        :param destination_longitude:
        :return: Distance in meters between the two locations,
                 along Earth's great circles.
        """
        gcd = great_circle(
            (np.float(origin_latitude), np.float(origin_longitude)),
            (np.float(destination_latitude), np.float(destination_longitude))
        ).m
        return gcd