Coverage for aisdb/wsa.py: 100%
33 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-30 04:22 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-30 04:22 +0000
1'''
2Compute wetted surface area using denny-mumford regression on vessel summer
3deadweight tonnage
5See table 2 in below paper for coefficient and exponent by ship type
7Reference:
8Moser, Cameron S., et al. "Quantifying the total wetted surface area of the world fleet: a first step in determining the potential extent of ships’ biofouling." Biological Invasions 18.1 (2016): 265-277.
10'''
13def _wsa(dwt, ship_type, ship_type_detailed='', **_):
14 ''' regression of Denny-Mumford WSA formula using ship type '''
16 # None, wing in ground craft, other
17 if (isinstance(ship_type, int)
18 and ship_type < 30) or ship_type == 'Wing In Grnd':
19 return 0
21 # fishing
22 elif (isinstance(ship_type, int)
23 and ship_type == 30) or ship_type == 'Fishing':
24 coef = 15.58
25 exp = 0.602
27 # tugs and port tenders
28 elif (isinstance(ship_type, int)
29 and 52 <= ship_type <= 53) or ship_type == 'Tug':
30 coef = 19.36
31 exp = 0.553
33 # passenger
34 elif (isinstance(ship_type, int)
35 and 60 <= ship_type < 70) or ship_type == 'Passenger':
36 coef = 14.64
37 exp = 0.671
39 # container ships
40 elif 'Container' in ship_type_detailed:
41 coef = 5.39
42 exp = 0.698
44 # bulk carriers
45 # note: cement classified as bulk carrier
46 elif 'Bulk' in ship_type_detailed or 'Cement' in ship_type_detailed:
47 coef = 9.57
48 exp = 0.63
50 # NOTE: no distinction for container ships or bulk carriers when using
51 # numeric ship type
52 # general cargo ship regression is used for these categories
53 elif (isinstance(ship_type, int)
54 and 70 <= ship_type < 80) or (isinstance(ship_type, str)
55 and 'Cargo' in ship_type): # cargo
56 coef = 14.24
57 exp = 0.596
59 # tankers (LNG / LPG)
60 elif (isinstance(ship_type, int) and ship_type == 84) or (
61 (isinstance(ship_type, str) and
62 ('Tanker' in ship_type and
63 ('Oil' in ship_type_detailed or 'LNG' in ship_type_detailed
64 or 'LPG' in ship_type_detailed)))):
65 coef = 5.41
66 exp = 0.699
68 # tankers (general)
69 elif (isinstance(ship_type, int)
70 and 80 <= ship_type < 90) or (isinstance(ship_type, str)
71 and 'Tanker' in ship_type):
72 coef = 9.56
73 exp = 0.63
75 # SAR, law enforcement, towing, dredging, diving, military, sailing,
76 # pleasure craft, etc
77 else:
78 coef = 26.2
79 exp = 0.551
81 return coef * pow(base=dwt, exp=exp)
84def wetted_surface_area(tracks):
85 ''' regression of Denny-Mumford WSA formula using ship type
87 args:
88 tracks (:func:`aisdb.webdata.marinetraffic.vessel_info`)
89 track generator with vessel_info appended
91 yields:
92 track dicts with submerged surface area in square meters appended
93 to key 'submerged_hull_m^2'
94 '''
95 for track in tracks:
96 dwt = track['marinetraffic_info']['summer_dwt'] or 0
97 if 'marinetraffic_info' in track.keys(
98 ) and track['marinetraffic_info']['vesseltype_generic'] is not None:
99 hull = _wsa(dwt, track['marinetraffic_info']['vesseltype_generic'],
100 track['marinetraffic_info']['vesseltype_detailed'])
101 else:
102 if 'ship_type' not in track.keys():
103 raise KeyError(
104 "'ship_type' not in track: try using "
105 "aisdb.database.sqlfcn.crawl_dynamic_static as 'fcn' arg "
106 "for DBQuery.gen_qry()")
107 hull = _wsa(dwt, track['ship_type'] or 0)
109 track['submerged_hull_m^2'] = hull
110 track['static'] = set(track['static']).union(
111 set([
112 'submerged_hull_m^2',
113 ]))
114 yield track