1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6import csv
7import logging
8import numpy as num
9from os import path as op
10from collections import OrderedDict
12from pyrocko import config, util
13from .util import get_download_callback
16logger = logging.getLogger('volcanoes')
18citation = '''
19Global Volcanism Program, 2013. Volcanoes of the World,
20v. 4.8.5. Venzke, E (ed.). Smithsonian Institution. Downloaded 29 Jan 2020.
21https://doi.org/10.5479/si.GVP.VOTW4-2013 '''
24class Volcano(object):
25 age = None
27 __fields__ = OrderedDict()
28 __slots__ = list(__fields__.keys())
30 def __init__(self, *args):
31 for (attr, attr_type), value in zip(self.__fields__.items(), args):
32 if attr_type in (int, float):
33 if not value or value == '?':
34 value = 0.
35 try:
36 setattr(self, attr, attr_type(value))
37 except ValueError as e:
38 print(list(zip(self.__fields__.keys(), args)))
39 raise e
41 def __str__(self):
42 d = {attr: getattr(self, attr) for attr in self.__fields__.keys()}
43 return '\n'.join(['%s: %s' % (attr, val) for attr, val in d.items()])
46class VolcanoHolocene(Volcano):
47 age = 'holocene'
49 __fields__ = OrderedDict([
50 ('fid', str),
51 ('volcano_number', int),
52 ('volcano_name', str),
53 ('primary_volcano_type', str),
54 ('last_eruption_year', int),
55 ('country', str),
56 ('geological_summary', str),
57 ('region', str),
58 ('subregion', str),
59 ('lat', float),
60 ('lon', float),
61 ('elevation', float),
62 ('tectonic_setting', str),
63 ('geologic_epoch', str),
64 ('evidence_category', str),
65 ('primary_photo_link', str),
66 ('primary_photo_caption', str),
67 ('primary_photo_credit', str),
68 ('major_rock_type', str),
69 ('geolocation', str),
70 ])
73class VolcanoPleistocene(Volcano):
74 age = 'pleistocene'
76 __fields__ = OrderedDict([
77 ('fid', str),
78 ('volcano_number', int),
79 ('volcano_name', str),
80 ('primary_volcano_type', str),
81 ('country', str),
82 ('geological_summary', str),
83 ('region', str),
84 ('subregion', str),
85 ('lat', float),
86 ('lon', float),
87 ('elevation', float),
88 ('geologic_epoch', str),
89 ('geolocation', str),
90 ])
93class Volcanoes(object):
94 URL_HOLOCENE = 'https://mirror.pyrocko.org/smithsonian/smithsonian-holocene.csv' # noqa
95 URL_PLEISTOCENE = 'https://mirror.pyrocko.org/smithsonian/smithsonian-pleistocene.csv' # noqa
97 def __init__(self):
98 self.fname_holocene = op.join(
99 config.config().volcanoes_dir, 'smithsonian-holocene.csv')
100 self.fname_pleistocene = op.join(
101 config.config().volcanoes_dir, 'smithsonian-pleistocene.csv')
103 if not op.exists(self.fname_holocene) \
104 or not op.exists(self.fname_pleistocene):
105 self.download()
107 self.volcanoes = []
108 self._load_volcanoes(self.fname_holocene, VolcanoHolocene)
109 self._load_volcanoes(self.fname_pleistocene, VolcanoPleistocene)
111 def _load_volcanoes(self, fname, cls):
112 with open(fname, 'r', encoding='utf8') as f:
113 next(f) # skip header
114 reader = csv.reader(f, dialect='unix')
115 for row in reader:
116 volcano = cls(*row)
117 self.volcanoes.append(volcano)
118 logger.debug('loaded %d volcanoes', self.nvolcanoes)
120 def download(self):
121 logger.info('Downloading Holocene volcanoes...')
122 util.download_file(
123 self.URL_HOLOCENE, self.fname_holocene,
124 status_callback=get_download_callback(
125 'Downloading Holocene volcanoe database...'))
127 logger.info('Downloading Pleistocene volcanoes...')
128 util.download_file(
129 self.URL_PLEISTOCENE, self.fname_pleistocene,
130 status_callback=get_download_callback(
131 'Downloading Pleistocene volcanoe database...'))
133 @property
134 def volcanoes_holocene(self):
135 return [v for v in self.volcanoes if isinstance(v, VolcanoHolocene)]
137 @property
138 def volcanoes_pleistocene(self):
139 return [v for v in self.volcanoes if isinstance(v, VolcanoPleistocene)]
141 @property
142 def nvolcanoes(self):
143 return len(self.volcanoes)
145 @property
146 def nvolcanoes_holocene(self):
147 return len(self.volcanoes_holocene)
149 @property
150 def nvolcanoes_pleistocene(self):
151 return len(self.volcanoes_pleistocene)
153 def get_coords(self):
154 return num.array([(v.lat, v.lon) for v in self.volcanoes])
156 def get_names(self):
157 return [v.volcano_name for v in self.volcanoes]
160if __name__ == '__main__':
161 logging.basicConfig(level=logging.DEBUG)
162 volc = Volcanoes()
163 print(volc.volcanoes[0])