Coverage for aisdb/wsa.py: 100%

33 statements  

« 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 

4 

5See table 2 in below paper for coefficient and exponent by ship type 

6 

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. 

9 

10''' 

11 

12 

13def _wsa(dwt, ship_type, ship_type_detailed='', **_): 

14 ''' regression of Denny-Mumford WSA formula using ship type ''' 

15 

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 

20 

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 

26 

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 

32 

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 

38 

39 # container ships 

40 elif 'Container' in ship_type_detailed: 

41 coef = 5.39 

42 exp = 0.698 

43 

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 

49 

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 

58 

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 

67 

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 

74 

75 # SAR, law enforcement, towing, dredging, diving, military, sailing, 

76 # pleasure craft, etc 

77 else: 

78 coef = 26.2 

79 exp = 0.551 

80 

81 return coef * pow(base=dwt, exp=exp) 

82 

83 

84def wetted_surface_area(tracks): 

85 ''' regression of Denny-Mumford WSA formula using ship type 

86 

87 args: 

88 tracks (:func:`aisdb.webdata.marinetraffic.vessel_info`) 

89 track generator with vessel_info appended 

90 

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) 

108 

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