1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

# http://pyrocko.org - GPLv3 

# 

# The Pyrocko Developers, 21st Century 

# ---|P------/S----------~Lg---------- 

from __future__ import absolute_import 

 

import csv 

import logging 

import numpy as num 

from os import path as op 

from collections import OrderedDict 

 

from pyrocko import config, util 

from .util import get_download_callback 

 

 

logger = logging.getLogger('volcanoes') 

 

citation = ''' 

Global Volcanism Program, 2013. Volcanoes of the World, 

v. 4.8.5. Venzke, E (ed.). Smithsonian Institution. Downloaded 29 Jan 2020. 

https://doi.org/10.5479/si.GVP.VOTW4-2013 ''' 

 

 

class Volcano(object): 

age = None 

 

__fields__ = OrderedDict() 

__slots__ = list(__fields__.keys()) 

 

def __init__(self, *args): 

for (attr, attr_type), value in zip(self.__fields__.items(), args): 

if attr_type in (int, float): 

if not value or value == '?': 

value = 0. 

try: 

setattr(self, attr, attr_type(value)) 

except ValueError as e: 

print(list(zip(self.__fields__.keys(), args))) 

raise e 

 

def __str__(self): 

d = {attr: getattr(self, attr) for attr in self.__fields__.keys()} 

return '\n'.join(['%s: %s' % (attr, val) for attr, val in d.items()]) 

 

 

class VolcanoHolocene(Volcano): 

age = 'holocene' 

 

__fields__ = OrderedDict([ 

('fid', str), 

('volcano_number', int), 

('volcano_name', str), 

('primary_volcano_type', str), 

('last_eruption_year', int), 

('country', str), 

('geological_summary', str), 

('region', str), 

('subregion', str), 

('lat', float), 

('lon', float), 

('elevation', float), 

('tectonic_setting', str), 

('geologic_epoch', str), 

('evidence_category', str), 

('primary_photo_link', str), 

('primary_photo_caption', str), 

('primary_photo_credit', str), 

('major_rock_type', str), 

('geolocation', str), 

]) 

 

 

class VolcanoPleistocene(Volcano): 

age = 'pleistocene' 

 

__fields__ = OrderedDict([ 

('fid', str), 

('volcano_number', int), 

('volcano_name', str), 

('primary_volcano_type', str), 

('country', str), 

('geological_summary', str), 

('region', str), 

('subregion', str), 

('lat', float), 

('lon', float), 

('elevation', float), 

('geologic_epoch', str), 

('geolocation', str), 

]) 

 

 

class Volcanoes(object): 

URL_HOLOCENE = 'https://mirror.pyrocko.org/smithsonian/smithsonian-holocene.csv' # noqa 

URL_PLEISTOCENE = 'https://mirror.pyrocko.org/smithsonian/smithsonian-pleistocene.csv' # noqa 

 

def __init__(self): 

self.fname_holocene = op.join( 

config.config().volcanoes_dir, 'smithsonian-holocene.csv') 

self.fname_pleistocene = op.join( 

config.config().volcanoes_dir, 'smithsonian-pleistocene.csv') 

 

if not op.exists(self.fname_holocene) \ 

or not op.exists(self.fname_pleistocene): 

self.download() 

 

self.volcanoes = [] 

self._load_volcanoes(self.fname_holocene, VolcanoHolocene) 

self._load_volcanoes(self.fname_pleistocene, VolcanoPleistocene) 

 

def _load_volcanoes(self, fname, cls): 

with open(fname, 'r') as f: 

next(f) # skip header 

reader = csv.reader(f, dialect='unix') 

for row in reader: 

volcano = cls(*row) 

self.volcanoes.append(volcano) 

logger.debug('loaded %d volcanoes', self.nvolcanoes) 

 

def download(self): 

logger.info('Downloading Holocene volcanoes...') 

util.download_file( 

self.URL_HOLOCENE, self.fname_holocene, 

status_callback=get_download_callback( 

'Downloading Holocene volcanoe database...')) 

 

logger.info('Downloading Pleistocene volcanoes...') 

util.download_file( 

self.URL_PLEISTOCENE, self.fname_pleistocene, 

status_callback=get_download_callback( 

'Downloading Pleistocene volcanoe database...')) 

 

@property 

def volcanoes_holocene(self): 

return [v for v in self.volcanoes if isinstance(v, VolcanoHolocene)] 

 

@property 

def volcanoes_pleistocene(self): 

return [v for v in self.volcanoes if isinstance(v, VolcanoPleistocene)] 

 

@property 

def nvolcanoes(self): 

return len(self.volcanoes) 

 

@property 

def nvolcanoes_holocene(self): 

return len(self.volcanoes_holocene) 

 

@property 

def nvolcanoes_pleistocene(self): 

return len(self.volcanoes_pleistocene) 

 

def get_coords(self): 

return num.array([(v.lat, v.lon) for v in self.volcanoes]) 

 

def get_names(self): 

return [v.volcano_name for v in self.volcanoes] 

 

 

if __name__ == '__main__': 

logging.basicConfig(level=logging.DEBUG) 

volc = Volcanoes() 

print(volc.volcanoes[0])