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
15logger = logging.getLogger('volcanoes')
17citation = '''
18Global Volcanism Program, 2013. Volcanoes of the World,
19v. 4.8.5. Venzke, E (ed.). Smithsonian Institution. Downloaded 29 Jan 2020.
20https://doi.org/10.5479/si.GVP.VOTW4-2013 '''
23class Volcano(object):
24 age = None
26 __fields__ = OrderedDict()
27 __slots__ = list(__fields__.keys())
29 def __init__(self, *args):
30 for (attr, attr_type), value in zip(self.__fields__.items(), args):
31 if attr_type in (int, float):
32 if not value or value == '?':
33 value = 0.
34 try:
35 setattr(self, attr, attr_type(value))
36 except ValueError as e:
37 print(list(zip(self.__fields__.keys(), args)))
38 raise e
40 def __str__(self):
41 d = {attr: getattr(self, attr) for attr in self.__fields__.keys()}
42 return '\n'.join(['%s: %s' % (attr, val) for attr, val in d.items()])
45class VolcanoHolocene(Volcano):
46 age = 'holocene'
48 __fields__ = OrderedDict([
49 ('fid', str),
50 ('volcano_number', int),
51 ('volcano_name', str),
52 ('primary_volcano_type', str),
53 ('last_eruption_year', int),
54 ('country', str),
55 ('geological_summary', str),
56 ('region', str),
57 ('subregion', str),
58 ('lat', float),
59 ('lon', float),
60 ('elevation', float),
61 ('tectonic_setting', str),
62 ('geologic_epoch', str),
63 ('evidence_category', str),
64 ('primary_photo_link', str),
65 ('primary_photo_caption', str),
66 ('primary_photo_credit', str),
67 ('major_rock_type', str),
68 ('geolocation', str),
69 ])
72class VolcanoPleistocene(Volcano):
73 age = 'pleistocene'
75 __fields__ = OrderedDict([
76 ('fid', str),
77 ('volcano_number', int),
78 ('volcano_name', str),
79 ('primary_volcano_type', str),
80 ('country', str),
81 ('geological_summary', str),
82 ('region', str),
83 ('subregion', str),
84 ('lat', float),
85 ('lon', float),
86 ('elevation', float),
87 ('geologic_epoch', str),
88 ('geolocation', str),
89 ])
92class Volcanoes(object):
93 URL_HOLOCENE = 'https://mirror.pyrocko.org/smithsonian/smithsonian-holocene.csv' # noqa
94 URL_PLEISTOCENE = 'https://mirror.pyrocko.org/smithsonian/smithsonian-pleistocene.csv' # noqa
96 def __init__(self):
97 self.fname_holocene = op.join(
98 config.config().volcanoes_dir, 'smithsonian-holocene.csv')
99 self.fname_pleistocene = op.join(
100 config.config().volcanoes_dir, 'smithsonian-pleistocene.csv')
102 if not op.exists(self.fname_holocene) \
103 or not op.exists(self.fname_pleistocene):
104 self.download()
106 self.volcanoes = []
107 self._load_volcanoes(self.fname_holocene, VolcanoHolocene)
108 self._load_volcanoes(self.fname_pleistocene, VolcanoPleistocene)
110 def _load_volcanoes(self, fname, cls):
111 with open(fname, 'r', encoding='utf8') as f:
112 next(f) # skip header
113 reader = csv.reader(f, dialect='unix')
114 for row in reader:
115 volcano = cls(*row)
116 self.volcanoes.append(volcano)
117 logger.debug('loaded %d volcanoes', self.nvolcanoes)
119 def download(self):
120 logger.info('Downloading Holocene volcanoes...')
121 util.download_file(
122 self.URL_HOLOCENE, self.fname_holocene,
123 status_callback=get_download_callback(
124 'Downloading Holocene volcanoe database...'))
126 logger.info('Downloading Pleistocene volcanoes...')
127 util.download_file(
128 self.URL_PLEISTOCENE, self.fname_pleistocene,
129 status_callback=get_download_callback(
130 'Downloading Pleistocene volcanoe database...'))
132 @property
133 def volcanoes_holocene(self):
134 return [v for v in self.volcanoes if isinstance(v, VolcanoHolocene)]
136 @property
137 def volcanoes_pleistocene(self):
138 return [v for v in self.volcanoes if isinstance(v, VolcanoPleistocene)]
140 @property
141 def nvolcanoes(self):
142 return len(self.volcanoes)
144 @property
145 def nvolcanoes_holocene(self):
146 return len(self.volcanoes_holocene)
148 @property
149 def nvolcanoes_pleistocene(self):
150 return len(self.volcanoes_pleistocene)
152 def get_coords(self):
153 return num.array([(v.lat, v.lon) for v in self.volcanoes])
155 def get_names(self):
156 return [v.volcano_name for v in self.volcanoes]
159if __name__ == '__main__':
160 logging.basicConfig(level=logging.DEBUG)
161 volc = Volcanoes()
162 print(volc.volcanoes[0])