requake 0.5__tar.gz → 0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {requake-0.5 → requake-0.6}/CHANGELOG.md +17 -0
- {requake-0.5 → requake-0.6}/PKG-INFO +11 -10
- {requake-0.5 → requake-0.6}/README.md +9 -8
- {requake-0.5 → requake-0.6}/requake/_version.py +3 -3
- {requake-0.5 → requake-0.6}/requake/catalog/__init__.py +1 -0
- {requake-0.5 → requake-0.6}/requake/catalog/catalog.py +4 -1
- requake-0.6/requake/catalog/print_catalog.py +53 -0
- {requake-0.5 → requake-0.6}/requake/config/configspec.conf +16 -0
- requake-0.6/requake/config/generic_printer.py +66 -0
- {requake-0.5 → requake-0.6}/requake/config/parse_arguments.py +83 -16
- {requake-0.5 → requake-0.6}/requake/config/rq_setup.py +22 -5
- {requake-0.5 → requake-0.6}/requake/config/utils.py +60 -2
- {requake-0.5 → requake-0.6}/requake/families/__init__.py +1 -0
- {requake-0.5 → requake-0.6}/requake/families/build_families.py +2 -55
- {requake-0.5 → requake-0.6}/requake/families/families.py +12 -3
- requake-0.6/requake/families/pairs.py +146 -0
- {requake-0.5 → requake-0.6}/requake/families/print_families.py +27 -49
- requake-0.6/requake/families/print_pairs.py +79 -0
- {requake-0.5 → requake-0.6}/requake/formulas/__init__.py +2 -0
- requake-0.5/requake/formulas/slip.py → requake-0.6/requake/formulas/moment.py +12 -21
- requake-0.6/requake/formulas/slip.py +104 -0
- {requake-0.5 → requake-0.6}/requake/main.py +9 -3
- {requake-0.5 → requake-0.6}/requake/plot/__init__.py +1 -1
- requake-0.6/requake/plot/plot_cumulative.py +174 -0
- {requake-0.5 → requake-0.6}/requake/plot/plot_families.py +8 -0
- {requake-0.5 → requake-0.6}/requake/plot/plot_timespans.py +3 -2
- {requake-0.5 → requake-0.6}/requake/plot/plot_utils.py +8 -4
- {requake-0.5 → requake-0.6}/requake.egg-info/PKG-INFO +11 -10
- {requake-0.5 → requake-0.6}/requake.egg-info/SOURCES.txt +6 -1
- {requake-0.5 → requake-0.6}/setup.py +7 -2
- requake-0.5/requake/plot/plot_slip.py +0 -119
- {requake-0.5 → requake-0.6}/CONTRIBUTORS.txt +0 -0
- {requake-0.5 → requake-0.6}/LICENSE.txt +0 -0
- {requake-0.5 → requake-0.6}/MANIFEST.in +0 -0
- {requake-0.5 → requake-0.6}/requake/__init__.py +0 -0
- {requake-0.5 → requake-0.6}/requake/catalog/read_catalog.py +0 -0
- {requake-0.5 → requake-0.6}/requake/catalog/read_catalog_from_csv.py +0 -0
- {requake-0.5 → requake-0.6}/requake/catalog/read_catalog_from_fdsnws.py +0 -0
- {requake-0.5 → requake-0.6}/requake/catalog/read_catalog_from_quakeml.py +0 -0
- {requake-0.5 → requake-0.6}/requake/config/__init__.py +0 -0
- {requake-0.5 → requake-0.6}/requake/config/config.py +0 -0
- {requake-0.5 → requake-0.6}/requake/config/configobj/__init__.py +0 -0
- {requake-0.5 → requake-0.6}/requake/config/configobj/_version.py +0 -0
- {requake-0.5 → requake-0.6}/requake/config/configobj/validate.py +0 -0
- {requake-0.5 → requake-0.6}/requake/families/build_templates.py +0 -0
- {requake-0.5 → requake-0.6}/requake/families/flag_family.py +0 -0
- {requake-0.5 → requake-0.6}/requake/formulas/conversion.py +0 -0
- {requake-0.5 → requake-0.6}/requake/plot/cached_tiler.py +0 -0
- {requake-0.5 → requake-0.6}/requake/plot/map_families.py +0 -0
- {requake-0.5 → requake-0.6}/requake/plot/map_tiles.py +0 -0
- {requake-0.5 → requake-0.6}/requake/plot/plot_pair.py +0 -0
- {requake-0.5 → requake-0.6}/requake/scan/__init__.py +0 -0
- {requake-0.5 → requake-0.6}/requake/scan/scan_catalog.py +0 -0
- {requake-0.5 → requake-0.6}/requake/scan/scan_templates.py +0 -0
- {requake-0.5 → requake-0.6}/requake/waveforms/__init__.py +0 -0
- {requake-0.5 → requake-0.6}/requake/waveforms/arrivals.py +0 -0
- {requake-0.5 → requake-0.6}/requake/waveforms/station_metadata.py +0 -0
- {requake-0.5 → requake-0.6}/requake/waveforms/waveforms.py +0 -0
- {requake-0.5 → requake-0.6}/requake.egg-info/dependency_links.txt +0 -0
- {requake-0.5 → requake-0.6}/requake.egg-info/entry_points.txt +0 -0
- {requake-0.5 → requake-0.6}/requake.egg-info/requires.txt +0 -0
- {requake-0.5 → requake-0.6}/requake.egg-info/top_level.txt +0 -0
- {requake-0.5 → requake-0.6}/setup.cfg +0 -0
- {requake-0.5 → requake-0.6}/versioneer.py +0 -0
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2021-2024 Claudio Satriano <satriano@ipgp.fr>
|
|
4
4
|
|
|
5
|
+
## v0.6 - 2024-05-04
|
|
6
|
+
|
|
7
|
+
Note: you might want to run `requake update_config` to update your config file
|
|
8
|
+
to the latest version.
|
|
9
|
+
|
|
10
|
+
- Verb `plot_slip` renamed to `plot_cumulative`. This new verb has new options
|
|
11
|
+
to plot cumulative slip, cumulative moment, and cumulative number of events,
|
|
12
|
+
and to make the plot logarithmic.
|
|
13
|
+
- New verb `print_catalog`: print the event catalog to screen
|
|
14
|
+
- New verb `print_pairs`: print the event pairs to screen
|
|
15
|
+
- `print_families`: also print minimum and maximum family magnitudes
|
|
16
|
+
- Additional models to convert magnitude to slip. Currently supported models
|
|
17
|
+
are: Nadeau and Johnson (1998), Beeler et al. (2001), Eshelby (1957).
|
|
18
|
+
Model selection is done using the `mag_to_slip_model` config parameter.
|
|
19
|
+
- New verb `update_config`: update an existing config file to the latest
|
|
20
|
+
version
|
|
21
|
+
|
|
5
22
|
## v0.5 - 2024-04-23
|
|
6
23
|
|
|
7
24
|
- New config options: `station_metadata_path` and `waveform_data_path` to
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: requake
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6
|
|
4
4
|
Summary: Repeating earthquakes search and analysis
|
|
5
5
|
Home-page: https://requake.seismicsource.org
|
|
6
6
|
Author: Claudio Satriano
|
|
@@ -33,7 +33,7 @@ Requires-Dist: argcomplete
|
|
|
33
33
|
Requires-Dist: tqdm
|
|
34
34
|
Requires-Dist: tabulate
|
|
35
35
|
|
|
36
|
-
<img src="imgs/Requake_logo.svg" width="400">
|
|
36
|
+
<img src="https://cdn.jsdelivr.net/gh/SeismicSource/requake@dc9a6e6fd818e57e0c0d74f9c16f2bfc6d4d148c/imgs/Requake_logo.svg" width="400">
|
|
37
37
|
|
|
38
38
|
# Requake
|
|
39
39
|
|
|
@@ -122,33 +122,34 @@ To get help, use:
|
|
|
122
122
|
|
|
123
123
|
requake -h
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
Currently supported verbs are:
|
|
125
|
+
Different commands are available:
|
|
127
126
|
|
|
128
127
|
sample_config write sample config file to current directory and exit
|
|
128
|
+
update_config update an existing config file to the latest version
|
|
129
129
|
read_catalog read an event catalog from web services or from a file
|
|
130
|
+
print_catalog print the event catalog to screen
|
|
130
131
|
scan_catalog scan an existing catalog for earthquake pairs
|
|
132
|
+
print_pairs print pairs to screen
|
|
131
133
|
plot_pair plot traces for a given event pair
|
|
132
134
|
build_families build families of repeating earthquakes from a catalog
|
|
133
135
|
of pairs
|
|
134
136
|
print_families print families to screen
|
|
135
137
|
plot_families plot traces for one ore more event families
|
|
136
138
|
plot_timespans plot family timespans
|
|
137
|
-
|
|
139
|
+
plot_cumulative cumulative plot for one or more families
|
|
138
140
|
map_families plot families on a map
|
|
139
141
|
flag_family flag a family of repeating earthquakes as valid or not
|
|
140
|
-
valid.
|
|
141
|
-
when first created
|
|
142
|
+
valid.
|
|
142
143
|
build_templates build waveform templates for one or more event
|
|
143
144
|
families
|
|
144
145
|
scan_templates scan a continuous waveform stream using one or more
|
|
145
146
|
templates
|
|
146
147
|
|
|
147
|
-
Certain
|
|
148
|
+
Certain commands (e.g., `plot_pair`) require further arguments (use, e.g.,
|
|
148
149
|
`requake plot_pair -h` to get help).
|
|
149
150
|
|
|
150
|
-
Requake supports command line tab completion for arguments, thanks
|
|
151
|
-
[argcomplete](https://kislyuk.github.io/argcomplete/).
|
|
151
|
+
Requake supports command line tab completion for commands and arguments, thanks
|
|
152
|
+
to [argcomplete](https://kislyuk.github.io/argcomplete/).
|
|
152
153
|
To enable command line tab completion, add the following line to your `.bashrc`
|
|
153
154
|
or `.zshrc`:
|
|
154
155
|
|
|
@@ -87,33 +87,34 @@ To get help, use:
|
|
|
87
87
|
|
|
88
88
|
requake -h
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
Currently supported verbs are:
|
|
90
|
+
Different commands are available:
|
|
92
91
|
|
|
93
92
|
sample_config write sample config file to current directory and exit
|
|
93
|
+
update_config update an existing config file to the latest version
|
|
94
94
|
read_catalog read an event catalog from web services or from a file
|
|
95
|
+
print_catalog print the event catalog to screen
|
|
95
96
|
scan_catalog scan an existing catalog for earthquake pairs
|
|
97
|
+
print_pairs print pairs to screen
|
|
96
98
|
plot_pair plot traces for a given event pair
|
|
97
99
|
build_families build families of repeating earthquakes from a catalog
|
|
98
100
|
of pairs
|
|
99
101
|
print_families print families to screen
|
|
100
102
|
plot_families plot traces for one ore more event families
|
|
101
103
|
plot_timespans plot family timespans
|
|
102
|
-
|
|
104
|
+
plot_cumulative cumulative plot for one or more families
|
|
103
105
|
map_families plot families on a map
|
|
104
106
|
flag_family flag a family of repeating earthquakes as valid or not
|
|
105
|
-
valid.
|
|
106
|
-
when first created
|
|
107
|
+
valid.
|
|
107
108
|
build_templates build waveform templates for one or more event
|
|
108
109
|
families
|
|
109
110
|
scan_templates scan a continuous waveform stream using one or more
|
|
110
111
|
templates
|
|
111
112
|
|
|
112
|
-
Certain
|
|
113
|
+
Certain commands (e.g., `plot_pair`) require further arguments (use, e.g.,
|
|
113
114
|
`requake plot_pair -h` to get help).
|
|
114
115
|
|
|
115
|
-
Requake supports command line tab completion for arguments, thanks
|
|
116
|
-
[argcomplete](https://kislyuk.github.io/argcomplete/).
|
|
116
|
+
Requake supports command line tab completion for commands and arguments, thanks
|
|
117
|
+
to [argcomplete](https://kislyuk.github.io/argcomplete/).
|
|
117
118
|
To enable command line tab completion, add the following line to your `.bashrc`
|
|
118
119
|
or `.zshrc`:
|
|
119
120
|
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-
|
|
11
|
+
"date": "2024-05-04T17:23:20+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "0.
|
|
14
|
+
"full-revisionid": "dc9a6e6fd818e57e0c0d74f9c16f2bfc6d4d148c",
|
|
15
|
+
"version": "0.6"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -264,10 +264,13 @@ def read_stored_catalog(config):
|
|
|
264
264
|
try:
|
|
265
265
|
cat = RequakeCatalog()
|
|
266
266
|
cat.read(config.scan_catalog_file)
|
|
267
|
+
cat.sort()
|
|
268
|
+
if not cat:
|
|
269
|
+
raise ValueError('Empty catalog')
|
|
267
270
|
return cat
|
|
268
271
|
except ValueError as m:
|
|
269
272
|
raise ValueError(
|
|
270
|
-
f'Error reading catalog file {config.scan_catalog_file}'
|
|
273
|
+
f'Error reading catalog file {config.scan_catalog_file}: {m}'
|
|
271
274
|
) from m
|
|
272
275
|
except FileNotFoundError as m:
|
|
273
276
|
raise FileNotFoundError(
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# -*- coding: utf8 -*-
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
"""
|
|
4
|
+
Print the event catalog to screen.
|
|
5
|
+
|
|
6
|
+
:copyright:
|
|
7
|
+
2021-2024 Claudio Satriano <satriano@ipgp.fr>
|
|
8
|
+
:license:
|
|
9
|
+
GNU General Public License v3.0 or later
|
|
10
|
+
(https://www.gnu.org/licenses/gpl-3.0-standalone.html)
|
|
11
|
+
"""
|
|
12
|
+
import logging
|
|
13
|
+
from .catalog import read_stored_catalog
|
|
14
|
+
from ..config.generic_printer import generic_printer
|
|
15
|
+
from ..config.rq_setup import rq_exit
|
|
16
|
+
logger = logging.getLogger(__name__.rsplit('.', maxsplit=1)[-1])
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def print_catalog(config):
|
|
20
|
+
"""
|
|
21
|
+
Print the event catalog to screen.
|
|
22
|
+
|
|
23
|
+
:param config: Configuration object.
|
|
24
|
+
:type config: config.Config
|
|
25
|
+
"""
|
|
26
|
+
try:
|
|
27
|
+
catalog = read_stored_catalog(config)
|
|
28
|
+
except (ValueError, FileNotFoundError) as m:
|
|
29
|
+
logger.error(m)
|
|
30
|
+
rq_exit(1)
|
|
31
|
+
|
|
32
|
+
headers_fmt = [
|
|
33
|
+
('evid', None),
|
|
34
|
+
('origin time', None),
|
|
35
|
+
('longitude', '.4f'),
|
|
36
|
+
('latitude', '.4f'),
|
|
37
|
+
('depth\n(km)', '.3f'),
|
|
38
|
+
('mag\ntype', None),
|
|
39
|
+
('mag', '.1f')
|
|
40
|
+
]
|
|
41
|
+
rows = [
|
|
42
|
+
[
|
|
43
|
+
ev.evid,
|
|
44
|
+
ev.orig_time,
|
|
45
|
+
ev.lon,
|
|
46
|
+
ev.lat,
|
|
47
|
+
ev.depth,
|
|
48
|
+
ev.mag_type,
|
|
49
|
+
ev.mag
|
|
50
|
+
]
|
|
51
|
+
for ev in catalog
|
|
52
|
+
]
|
|
53
|
+
generic_printer(config, rows, headers_fmt)
|
|
@@ -128,3 +128,19 @@ distance_from_lat = float(default=None)
|
|
|
128
128
|
## Normalization will produce an average trace which is more representative
|
|
129
129
|
## of the family, but will be less effective in reducing noise.
|
|
130
130
|
normalize_traces_before_averaging = boolean(default=False)
|
|
131
|
+
|
|
132
|
+
#### Post-processing parameters
|
|
133
|
+
## Estimation of fault slip (in cm) from repetater's magnitude
|
|
134
|
+
## Choose between:
|
|
135
|
+
## NJ1998 : Nadeau and Johnson (1998)
|
|
136
|
+
## B2001 : Beeler et al. (2001)
|
|
137
|
+
## E1957 : Eshelby (1957), circular crack model
|
|
138
|
+
## See Uchida (2019, https://doi.org/10.1186/s40645-019-0284-z) for details
|
|
139
|
+
## on the models.
|
|
140
|
+
mag_to_slip_model = string(default='NJ1998')
|
|
141
|
+
## Static stress drop value for B2001 and E1957 models (MPa)
|
|
142
|
+
static_stress_drop = float(default=10.0)
|
|
143
|
+
## Rigidity value for B2001 and E1957 models (GPa)
|
|
144
|
+
rigidity = float(default=30.0)
|
|
145
|
+
## Strain hardening coefficient for B2001 model (MPa/cm)
|
|
146
|
+
strain_hardening = float(default=0.5)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# -*- coding: utf8 -*-
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
"""
|
|
4
|
+
Generic printer functions for Requake.
|
|
5
|
+
|
|
6
|
+
:copyright:
|
|
7
|
+
2021-2024 Claudio Satriano <satriano@ipgp.fr>
|
|
8
|
+
:license:
|
|
9
|
+
GNU General Public License v3.0 or later
|
|
10
|
+
(https://www.gnu.org/licenses/gpl-3.0-standalone.html)
|
|
11
|
+
"""
|
|
12
|
+
import sys
|
|
13
|
+
import os
|
|
14
|
+
import csv
|
|
15
|
+
import contextlib
|
|
16
|
+
import logging
|
|
17
|
+
from tabulate import tabulate
|
|
18
|
+
logger = logging.getLogger(__name__.rsplit('.', maxsplit=1)[-1])
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def generic_printer(config, rows, headers_fmt, print_headers=True):
|
|
22
|
+
"""
|
|
23
|
+
A generic printer function for Requake.
|
|
24
|
+
|
|
25
|
+
:param config: Configuration object.
|
|
26
|
+
:type config: config.Config
|
|
27
|
+
:param rows: Rows to print.
|
|
28
|
+
:type rows: list of rows
|
|
29
|
+
:param headers_fmt: Headers and format strings.
|
|
30
|
+
:type headers_fmt: list of tuples of str
|
|
31
|
+
"""
|
|
32
|
+
headers = [h[0] for h in headers_fmt]
|
|
33
|
+
floatfmt = [h[1] for h in headers_fmt]
|
|
34
|
+
tablefmt = config.args.format
|
|
35
|
+
if tablefmt == 'csv':
|
|
36
|
+
writer = csv.writer(sys.stdout)
|
|
37
|
+
if print_headers:
|
|
38
|
+
# replace newlines with spaces in headers
|
|
39
|
+
headers = [h.replace('\n', ' ') for h in headers]
|
|
40
|
+
writer.writerow(headers)
|
|
41
|
+
elif tablefmt == 'markdown':
|
|
42
|
+
headers = [h.replace('\n', '<br>') for h in headers]
|
|
43
|
+
if tablefmt == 'csv':
|
|
44
|
+
try:
|
|
45
|
+
writer.writerows(rows)
|
|
46
|
+
except BrokenPipeError:
|
|
47
|
+
# Redirect remaining output to devnull to avoid another
|
|
48
|
+
# BrokenPipeError at shutdown
|
|
49
|
+
devnull = os.open(os.devnull, os.O_WRONLY)
|
|
50
|
+
os.dup2(devnull, sys.stdout.fileno())
|
|
51
|
+
else:
|
|
52
|
+
format_dict = {
|
|
53
|
+
'simple': 'simple',
|
|
54
|
+
'markdown': 'github'
|
|
55
|
+
}
|
|
56
|
+
tablefmt = format_dict[config.args.format]
|
|
57
|
+
with contextlib.suppress(BrokenPipeError):
|
|
58
|
+
kwargs = {
|
|
59
|
+
'headers': headers,
|
|
60
|
+
'floatfmt': floatfmt,
|
|
61
|
+
'tablefmt': tablefmt
|
|
62
|
+
}
|
|
63
|
+
line = tabulate(rows, **kwargs)
|
|
64
|
+
if not print_headers:
|
|
65
|
+
line = line.rsplit('\n', maxsplit=1)[-1]
|
|
66
|
+
print(line)
|
|
@@ -34,6 +34,22 @@ class NewlineHelpFormatter(argparse.HelpFormatter):
|
|
|
34
34
|
return lines
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
class SubcommandHelpFormatter(argparse.RawDescriptionHelpFormatter):
|
|
38
|
+
"""
|
|
39
|
+
Custom help formatter that removes the list of subcommands from the help
|
|
40
|
+
message.
|
|
41
|
+
|
|
42
|
+
See: https://stackoverflow.com/a/13429281/2021880
|
|
43
|
+
"""
|
|
44
|
+
def _format_action(self, action):
|
|
45
|
+
parts = super(
|
|
46
|
+
argparse.RawDescriptionHelpFormatter, self
|
|
47
|
+
)._format_action(action)
|
|
48
|
+
if action.nargs == argparse.PARSER:
|
|
49
|
+
parts = '\n'.join(parts.split('\n')[1:])
|
|
50
|
+
return parts
|
|
51
|
+
|
|
52
|
+
|
|
37
53
|
def parse_arguments(progname='requake'):
|
|
38
54
|
"""
|
|
39
55
|
Parse command line arguments.
|
|
@@ -44,9 +60,14 @@ def parse_arguments(progname='requake'):
|
|
|
44
60
|
:rtype: argparse.Namespace
|
|
45
61
|
"""
|
|
46
62
|
parser = argparse.ArgumentParser(
|
|
47
|
-
description=f'{progname}: Repeating earthquakes search and analysis.'
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
description=f'{progname}: Repeating earthquakes search and analysis.',
|
|
64
|
+
epilog='Use "%(prog)s <command> -h" for help on a specific command\n'
|
|
65
|
+
'(example: "%(prog)s read_catalog -h").\n'
|
|
66
|
+
'\nFull documentation at https://requake.readthedocs.io',
|
|
67
|
+
formatter_class=SubcommandHelpFormatter
|
|
68
|
+
)
|
|
69
|
+
subparser = parser.add_subparsers(dest='action', title='commands')
|
|
70
|
+
subparser.metavar = '<command> [options]'
|
|
50
71
|
parser.add_argument(
|
|
51
72
|
'-c',
|
|
52
73
|
'--configfile',
|
|
@@ -73,6 +94,16 @@ def parse_arguments(progname='requake'):
|
|
|
73
94
|
help='write sample config file to current directory and exit'
|
|
74
95
|
)
|
|
75
96
|
# ---
|
|
97
|
+
# --- update_config
|
|
98
|
+
updateconfig = subparser.add_parser(
|
|
99
|
+
'update_config',
|
|
100
|
+
help='update an existing config file to the latest version'
|
|
101
|
+
)
|
|
102
|
+
updateconfig.add_argument(
|
|
103
|
+
'config_file', default='requake.conf', nargs='?',
|
|
104
|
+
help='config file to be updated (default: %(default)s)'
|
|
105
|
+
)
|
|
106
|
+
# ---
|
|
76
107
|
# --- read catalog
|
|
77
108
|
readcatalog = subparser.add_parser(
|
|
78
109
|
'read_catalog',
|
|
@@ -103,6 +134,22 @@ def parse_arguments(progname='requake'):
|
|
|
103
134
|
'-a', '--append', action='store_true',
|
|
104
135
|
help='append events to existing catalog'
|
|
105
136
|
)
|
|
137
|
+
# --- printformat
|
|
138
|
+
# a parent parser for the "format" option,
|
|
139
|
+
# used by the "print" subparsers
|
|
140
|
+
printformat = argparse.ArgumentParser(add_help=False)
|
|
141
|
+
printformat.add_argument(
|
|
142
|
+
'-f', '--format', type=str, default='simple',
|
|
143
|
+
choices=['simple', 'markdown', 'csv'],
|
|
144
|
+
help='format for the output table (default: %(default)s)'
|
|
145
|
+
)
|
|
146
|
+
# ---
|
|
147
|
+
# --- print_catalog
|
|
148
|
+
subparser.add_parser(
|
|
149
|
+
'print_catalog',
|
|
150
|
+
parents=[printformat],
|
|
151
|
+
help='print the event catalog to screen'
|
|
152
|
+
)
|
|
106
153
|
# ---
|
|
107
154
|
# --- scan_catalog
|
|
108
155
|
subparser.add_parser(
|
|
@@ -110,6 +157,23 @@ def parse_arguments(progname='requake'):
|
|
|
110
157
|
help='scan an existing catalog for earthquake pairs'
|
|
111
158
|
)
|
|
112
159
|
# ---
|
|
160
|
+
# --- print_pairs
|
|
161
|
+
printpairs = subparser.add_parser(
|
|
162
|
+
'print_pairs',
|
|
163
|
+
parents=[printformat],
|
|
164
|
+
help='print pairs to screen'
|
|
165
|
+
)
|
|
166
|
+
printpairs.add_argument(
|
|
167
|
+
'-c', '--cc_min',
|
|
168
|
+
type=float, default=None,
|
|
169
|
+
help='minimum cross-correlation coefficient (default: %(default)s)'
|
|
170
|
+
)
|
|
171
|
+
printpairs.add_argument(
|
|
172
|
+
'-C', '--cc_max',
|
|
173
|
+
type=float, default=None,
|
|
174
|
+
help='maximum cross-correlation coefficient (default: %(default)s)'
|
|
175
|
+
)
|
|
176
|
+
# ---
|
|
113
177
|
# --- plot_pair
|
|
114
178
|
plotpair = subparser.add_parser(
|
|
115
179
|
'plot_pair',
|
|
@@ -166,16 +230,11 @@ def parse_arguments(progname='requake'):
|
|
|
166
230
|
)
|
|
167
231
|
# ---
|
|
168
232
|
# --- print_families
|
|
169
|
-
|
|
233
|
+
subparser.add_parser(
|
|
170
234
|
'print_families',
|
|
171
|
-
parents=[longerthan, minevents, familynumbers],
|
|
235
|
+
parents=[longerthan, minevents, familynumbers, printformat],
|
|
172
236
|
help='print families to screen'
|
|
173
237
|
)
|
|
174
|
-
printfamilies.add_argument(
|
|
175
|
-
'-f', '--format', type=str, default='simple',
|
|
176
|
-
choices=['simple', 'markdown', 'csv'],
|
|
177
|
-
help='format for the output table (default: %(default)s)'
|
|
178
|
-
)
|
|
179
238
|
# ---
|
|
180
239
|
# --- plot_families
|
|
181
240
|
plotfamilies = subparser.add_parser(
|
|
@@ -207,11 +266,20 @@ def parse_arguments(progname='requake'):
|
|
|
207
266
|
help='quantity to sort families by on y-axis (default: %(default)s)'
|
|
208
267
|
)
|
|
209
268
|
# ---
|
|
210
|
-
# ---
|
|
211
|
-
subparser.add_parser(
|
|
212
|
-
'
|
|
269
|
+
# --- plot_cumulative
|
|
270
|
+
plotcumulative = subparser.add_parser(
|
|
271
|
+
'plot_cumulative',
|
|
213
272
|
parents=[longerthan, minevents, familynumbers],
|
|
214
|
-
help='
|
|
273
|
+
help='cumulative plot for one or more families'
|
|
274
|
+
)
|
|
275
|
+
plotcumulative.add_argument(
|
|
276
|
+
'-q', '--quantity', type=str, default='slip',
|
|
277
|
+
choices=['slip', 'moment', 'number'],
|
|
278
|
+
help='cumulative quantity to plot on y-axis (default: %(default)s)'
|
|
279
|
+
)
|
|
280
|
+
plotcumulative.add_argument(
|
|
281
|
+
'-L', '--logscale', action='store_true',
|
|
282
|
+
help='use log scale for y-axis'
|
|
215
283
|
)
|
|
216
284
|
# ---
|
|
217
285
|
# --- map_families
|
|
@@ -242,8 +310,7 @@ def parse_arguments(progname='requake'):
|
|
|
242
310
|
# --- flag_family
|
|
243
311
|
flagfamily = subparser.add_parser(
|
|
244
312
|
'flag_family',
|
|
245
|
-
help='flag a family of repeating earthquakes as valid or not valid
|
|
246
|
-
'Note that all families are valid by default when first created'
|
|
313
|
+
help='flag a family of repeating earthquakes as valid or not valid'
|
|
247
314
|
)
|
|
248
315
|
flagfamily.add_argument('family_number')
|
|
249
316
|
flagfamily.add_argument(
|
|
@@ -25,7 +25,7 @@ from .._version import get_versions
|
|
|
25
25
|
from .config import Config
|
|
26
26
|
from .utils import (
|
|
27
27
|
parse_configspec, read_config, validate_config, write_sample_config,
|
|
28
|
-
write_ok
|
|
28
|
+
update_config_file, write_ok
|
|
29
29
|
)
|
|
30
30
|
# pylint: disable=global-statement,import-outside-toplevel
|
|
31
31
|
|
|
@@ -50,6 +50,20 @@ def _check_library_versions():
|
|
|
50
50
|
OBSPY_VERSION_STR = obspy.__version__
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
def _make_outdir(outdir):
|
|
54
|
+
"""Create the output directory if it doesn't exist."""
|
|
55
|
+
if not os.path.exists(outdir):
|
|
56
|
+
os.makedirs(outdir)
|
|
57
|
+
readme = os.path.join(outdir, 'README.txt')
|
|
58
|
+
if not os.path.exists(readme):
|
|
59
|
+
with open(readme, 'w', encoding='utf8') as fp:
|
|
60
|
+
fp.write('This is the Requake output directory.\n\n')
|
|
61
|
+
fp.write('''\
|
|
62
|
+
Do not manually edit the files in this directory, unless you know what you
|
|
63
|
+
are doing.
|
|
64
|
+
''')
|
|
65
|
+
|
|
66
|
+
|
|
53
67
|
def _setup_logging(config, progname, action_name):
|
|
54
68
|
"""Set up the logging infrastructure."""
|
|
55
69
|
global logger
|
|
@@ -68,8 +82,7 @@ def _setup_logging(config, progname, action_name):
|
|
|
68
82
|
'build_families'
|
|
69
83
|
]
|
|
70
84
|
if action_name in logging_actions:
|
|
71
|
-
|
|
72
|
-
os.makedirs(config.args.outdir)
|
|
85
|
+
_make_outdir(config.args.outdir)
|
|
73
86
|
logfile = os.path.join(
|
|
74
87
|
config.args.outdir, f'{progname}.{action_name}.log')
|
|
75
88
|
filehand = logging.FileHandler(filename=logfile, mode='a')
|
|
@@ -190,6 +203,9 @@ def configure(args):
|
|
|
190
203
|
if args.action == 'sample_config':
|
|
191
204
|
write_sample_config(configspec, 'requake')
|
|
192
205
|
sys.exit(0)
|
|
206
|
+
if args.action == 'update_config':
|
|
207
|
+
update_config_file(args.configfile, configspec)
|
|
208
|
+
sys.exit(0)
|
|
193
209
|
config_obj = read_config(args.configfile, configspec)
|
|
194
210
|
# Set to None all the 'None' strings
|
|
195
211
|
for key, value in config_obj.dict().items():
|
|
@@ -261,8 +277,9 @@ def rq_exit(retval=0, abort=False, progname='requake'):
|
|
|
261
277
|
"""Exit as gracefully as possible."""
|
|
262
278
|
if abort:
|
|
263
279
|
print('\nAborting.')
|
|
264
|
-
logger
|
|
265
|
-
|
|
280
|
+
if logger is not None:
|
|
281
|
+
logger.debug(f'{progname} ABORTED\n\n')
|
|
282
|
+
elif logger is not None:
|
|
266
283
|
logger.debug(f'{progname} END\n\n')
|
|
267
284
|
logging.shutdown()
|
|
268
285
|
sys.exit(retval)
|
|
@@ -12,8 +12,8 @@ Utility functions for Requake.
|
|
|
12
12
|
import os
|
|
13
13
|
import sys
|
|
14
14
|
import locale
|
|
15
|
-
import
|
|
16
|
-
from
|
|
15
|
+
import shutil
|
|
16
|
+
from datetime import datetime
|
|
17
17
|
from .configobj import ConfigObj
|
|
18
18
|
from .configobj.validate import Validator
|
|
19
19
|
locale.setlocale(locale.LC_ALL, '')
|
|
@@ -133,6 +133,53 @@ def validate_config(config_obj):
|
|
|
133
133
|
err_exit('No configuration value present!')
|
|
134
134
|
|
|
135
135
|
|
|
136
|
+
def update_config_file(config_file, configspec):
|
|
137
|
+
"""
|
|
138
|
+
Update a configuration file to the latest version.
|
|
139
|
+
|
|
140
|
+
:param config_file: Configuration file.
|
|
141
|
+
:type config_file: str
|
|
142
|
+
:param configspec: Configuration specification file.
|
|
143
|
+
:type configspec: str
|
|
144
|
+
"""
|
|
145
|
+
config_obj = read_config(config_file, configspec)
|
|
146
|
+
val = Validator()
|
|
147
|
+
config_obj.validate(val)
|
|
148
|
+
mod_time = datetime.fromtimestamp(os.path.getmtime(config_file))
|
|
149
|
+
mod_time_str = mod_time.strftime('%Y%m%d_%H%M%S')
|
|
150
|
+
config_file_old = f'{config_file}.{mod_time_str}'
|
|
151
|
+
ans = input(
|
|
152
|
+
f'Ok to update {config_file}? [y/N]\n'
|
|
153
|
+
f'(Old file will be saved as {config_file_old}) '
|
|
154
|
+
)
|
|
155
|
+
if ans not in ['y', 'Y']:
|
|
156
|
+
sys.exit(0)
|
|
157
|
+
config_new = ConfigObj(configspec=configspec, default_encoding='utf8')
|
|
158
|
+
config_new = read_config(None, configspec)
|
|
159
|
+
config_new.validate(val)
|
|
160
|
+
config_new.defaults = []
|
|
161
|
+
config_new.comments = configspec.comments
|
|
162
|
+
config_new.initial_comment = config_obj.initial_comment
|
|
163
|
+
config_new.final_comment = configspec.final_comment
|
|
164
|
+
for k, v in config_obj.items():
|
|
165
|
+
if k not in config_new:
|
|
166
|
+
continue
|
|
167
|
+
# Fix for force_list(default=None)
|
|
168
|
+
if v == ['None', ]:
|
|
169
|
+
v = None
|
|
170
|
+
config_new[k] = v
|
|
171
|
+
migrate_options = {
|
|
172
|
+
# 'old_option': 'new_option'
|
|
173
|
+
}
|
|
174
|
+
for old_opt, new_opt in migrate_options.items():
|
|
175
|
+
if old_opt in config_obj and config_obj[old_opt] != 'None':
|
|
176
|
+
config_new[new_opt] = config_obj[old_opt]
|
|
177
|
+
shutil.copyfile(config_file, config_file_old)
|
|
178
|
+
with open(config_file, 'wb') as fp:
|
|
179
|
+
config_new.write(fp)
|
|
180
|
+
print(f'{config_file}: updated')
|
|
181
|
+
|
|
182
|
+
|
|
136
183
|
def manage_uncaught_exception(exception):
|
|
137
184
|
"""
|
|
138
185
|
Manage an uncaught exception.
|
|
@@ -140,6 +187,13 @@ def manage_uncaught_exception(exception):
|
|
|
140
187
|
:param exception: Exception object.
|
|
141
188
|
:type exception: Exception
|
|
142
189
|
"""
|
|
190
|
+
# pylint: disable=import-outside-toplevel
|
|
191
|
+
from .. import __version__
|
|
192
|
+
import traceback
|
|
193
|
+
import numpy as np
|
|
194
|
+
import scipy as sp
|
|
195
|
+
import obspy
|
|
196
|
+
import matplotlib
|
|
143
197
|
sys.stderr.write("""
|
|
144
198
|
# BEGIN TRACEBACK #############################################################
|
|
145
199
|
""")
|
|
@@ -160,6 +214,10 @@ Include the following information in your report:
|
|
|
160
214
|
""")
|
|
161
215
|
sys.stderr.write(f' Requake version: {__version__}\n')
|
|
162
216
|
sys.stderr.write(f' Python version: {sys.version}\n')
|
|
217
|
+
sys.stderr.write(f' NumPy version: {np.__version__}\n')
|
|
218
|
+
sys.stderr.write(f' SciPy version: {sp.__version__}\n')
|
|
219
|
+
sys.stderr.write(f' ObsPy version: {obspy.__version__}\n')
|
|
220
|
+
sys.stderr.write(f' Matplotlib version: {matplotlib.__version__}\n')
|
|
163
221
|
sys.stderr.write(f' Platform: {sys.platform}\n')
|
|
164
222
|
sys.stderr.write(f' Command line: {" ".join(sys.argv)}\n')
|
|
165
223
|
sys.stderr.write(f' Error message: {str(exception)}\n')
|
|
@@ -10,6 +10,7 @@ earthquakes.
|
|
|
10
10
|
GNU General Public License v3.0 or later
|
|
11
11
|
(https://www.gnu.org/licenses/gpl-3.0-standalone.html)
|
|
12
12
|
"""
|
|
13
|
+
from .print_pairs import print_pairs # noqa
|
|
13
14
|
from .build_families import build_families # noqa
|
|
14
15
|
from .print_families import print_families # noqa
|
|
15
16
|
from .flag_family import flag_family # noqa
|