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