requake 0.4.1__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.
Files changed (68) hide show
  1. {requake-0.4.1 → requake-0.6}/CHANGELOG.md +31 -2
  2. {requake-0.4.1 → requake-0.6}/PKG-INFO +41 -11
  3. {requake-0.4.1 → requake-0.6}/README.md +41 -11
  4. {requake-0.4.1 → requake-0.6}/requake/_version.py +3 -3
  5. {requake-0.4.1 → requake-0.6}/requake/catalog/__init__.py +1 -0
  6. {requake-0.4.1 → requake-0.6}/requake/catalog/catalog.py +70 -1
  7. requake-0.6/requake/catalog/print_catalog.py +53 -0
  8. {requake-0.4.1 → requake-0.6}/requake/catalog/read_catalog.py +64 -10
  9. {requake-0.4.1 → requake-0.6}/requake/catalog/read_catalog_from_csv.py +11 -1
  10. {requake-0.4.1 → requake-0.6}/requake/config/configspec.conf +26 -0
  11. requake-0.6/requake/config/generic_printer.py +66 -0
  12. {requake-0.4.1 → requake-0.6}/requake/config/parse_arguments.py +95 -33
  13. {requake-0.4.1 → requake-0.6}/requake/config/rq_setup.py +72 -15
  14. requake-0.6/requake/config/utils.py +229 -0
  15. {requake-0.4.1 → requake-0.6}/requake/families/__init__.py +1 -0
  16. {requake-0.4.1 → requake-0.6}/requake/families/build_families.py +2 -55
  17. {requake-0.4.1 → requake-0.6}/requake/families/families.py +19 -3
  18. requake-0.6/requake/families/pairs.py +146 -0
  19. requake-0.6/requake/families/print_families.py +82 -0
  20. requake-0.6/requake/families/print_pairs.py +79 -0
  21. {requake-0.4.1 → requake-0.6}/requake/formulas/__init__.py +2 -0
  22. requake-0.4.1/requake/formulas/slip.py → requake-0.6/requake/formulas/moment.py +12 -21
  23. requake-0.6/requake/formulas/slip.py +104 -0
  24. requake-0.4.1/requake/requake.py → requake-0.6/requake/main.py +21 -5
  25. {requake-0.4.1 → requake-0.6}/requake/plot/__init__.py +1 -1
  26. {requake-0.4.1 → requake-0.6}/requake/plot/map_families.py +13 -28
  27. requake-0.6/requake/plot/plot_cumulative.py +174 -0
  28. {requake-0.4.1 → requake-0.6}/requake/plot/plot_families.py +8 -0
  29. requake-0.6/requake/plot/plot_timespans.py +133 -0
  30. requake-0.6/requake/plot/plot_utils.py +152 -0
  31. {requake-0.4.1 → requake-0.6}/requake/scan/scan_catalog.py +7 -3
  32. {requake-0.4.1 → requake-0.6}/requake/waveforms/station_metadata.py +3 -3
  33. {requake-0.4.1 → requake-0.6}/requake/waveforms/waveforms.py +7 -2
  34. {requake-0.4.1 → requake-0.6}/requake.egg-info/PKG-INFO +41 -11
  35. {requake-0.4.1 → requake-0.6}/requake.egg-info/SOURCES.txt +8 -2
  36. requake-0.6/requake.egg-info/entry_points.txt +2 -0
  37. {requake-0.4.1 → requake-0.6}/setup.py +8 -3
  38. requake-0.4.1/requake/config/utils.py +0 -131
  39. requake-0.4.1/requake/families/print_families.py +0 -91
  40. requake-0.4.1/requake/plot/plot_slip.py +0 -121
  41. requake-0.4.1/requake/plot/plot_timespans.py +0 -145
  42. requake-0.4.1/requake.egg-info/entry_points.txt +0 -2
  43. {requake-0.4.1 → requake-0.6}/CONTRIBUTORS.txt +0 -0
  44. {requake-0.4.1 → requake-0.6}/LICENSE.txt +0 -0
  45. {requake-0.4.1 → requake-0.6}/MANIFEST.in +0 -0
  46. {requake-0.4.1 → requake-0.6}/requake/__init__.py +0 -0
  47. {requake-0.4.1 → requake-0.6}/requake/catalog/read_catalog_from_fdsnws.py +0 -0
  48. {requake-0.4.1 → requake-0.6}/requake/catalog/read_catalog_from_quakeml.py +0 -0
  49. {requake-0.4.1 → requake-0.6}/requake/config/__init__.py +0 -0
  50. {requake-0.4.1 → requake-0.6}/requake/config/config.py +0 -0
  51. {requake-0.4.1 → requake-0.6}/requake/config/configobj/__init__.py +0 -0
  52. {requake-0.4.1 → requake-0.6}/requake/config/configobj/_version.py +0 -0
  53. {requake-0.4.1 → requake-0.6}/requake/config/configobj/validate.py +0 -0
  54. {requake-0.4.1 → requake-0.6}/requake/families/build_templates.py +0 -0
  55. {requake-0.4.1 → requake-0.6}/requake/families/flag_family.py +0 -0
  56. {requake-0.4.1 → requake-0.6}/requake/formulas/conversion.py +0 -0
  57. {requake-0.4.1 → requake-0.6}/requake/plot/cached_tiler.py +0 -0
  58. {requake-0.4.1 → requake-0.6}/requake/plot/map_tiles.py +0 -0
  59. {requake-0.4.1 → requake-0.6}/requake/plot/plot_pair.py +0 -0
  60. {requake-0.4.1 → requake-0.6}/requake/scan/__init__.py +0 -0
  61. {requake-0.4.1 → requake-0.6}/requake/scan/scan_templates.py +0 -0
  62. {requake-0.4.1 → requake-0.6}/requake/waveforms/__init__.py +0 -0
  63. {requake-0.4.1 → requake-0.6}/requake/waveforms/arrivals.py +0 -0
  64. {requake-0.4.1 → requake-0.6}/requake.egg-info/dependency_links.txt +0 -0
  65. {requake-0.4.1 → requake-0.6}/requake.egg-info/requires.txt +0 -0
  66. {requake-0.4.1 → requake-0.6}/requake.egg-info/top_level.txt +0 -0
  67. {requake-0.4.1 → requake-0.6}/setup.cfg +0 -0
  68. {requake-0.4.1 → requake-0.6}/versioneer.py +0 -0
@@ -1,6 +1,35 @@
1
- # Requake - Repeating earthquakes search and analysis
1
+ # Requake Changelog
2
2
 
3
- (c) 2021-2024 Claudio Satriano <satriano@ipgp.fr>
3
+ Copyright (c) 2021-2024 Claudio Satriano <satriano@ipgp.fr>
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
+
22
+ ## v0.5 - 2024-04-23
23
+
24
+ - New config options: `station_metadata_path` and `waveform_data_path` to
25
+ read station metadata and waveform data from files. Supports any metadata
26
+ format supported by ObsPy and SDS (SeisComp Data Structure) waveform
27
+ archives.
28
+ - Filter catalog files on reading using the criteria in the config file
29
+ - Improved time axes in `plot_timespans` and `plot_slip` for short time
30
+ intervals
31
+ - `print_families`: autoset duration units based on the average duration
32
+ - `plot_timespans`: default sorting changed to `family_number`
4
33
 
5
34
  ## v0.4.1 - 2024-03-11
6
35
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: requake
3
- Version: 0.4.1
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,6 +33,8 @@ Requires-Dist: argcomplete
33
33
  Requires-Dist: tqdm
34
34
  Requires-Dist: tabulate
35
35
 
36
+ <img src="https://cdn.jsdelivr.net/gh/SeismicSource/requake@dc9a6e6fd818e57e0c0d74f9c16f2bfc6d4d148c/imgs/Requake_logo.svg" width="400">
37
+
36
38
  # Requake
37
39
 
38
40
  Repeating earthquakes search and analysis.
@@ -40,6 +42,8 @@ Repeating earthquakes search and analysis.
40
42
  [![changelog-badge]][changelog-link]
41
43
  [![PyPI-badge]][PyPI-link]
42
44
  [![license-badge]][license-link]
45
+ [![docs-badge]][docs-link]
46
+ [![DOI-badge]][DOI-link]
43
47
 
44
48
  Copyright (c) 2021-2024 Claudio Satriano <satriano@ipgp.fr>
45
49
 
@@ -50,8 +54,8 @@ Requake is a command line tool to search and analyse repeating earthquakes.
50
54
  It can either scan an existing earthquake catalog to search for similar events,
51
55
  or perform template matching on a continuous waveform stream.
52
56
 
53
- Catalogs and waveforms are downloaded using standard
54
- [FDSN web services](https://www.fdsn.org/webservices/).
57
+ Catalogs and waveforms can be read from local files or downloaded using
58
+ standard [FDSN web services](https://www.fdsn.org/webservices/).
55
59
 
56
60
  Requake is written in Python and uses [ObsPy](https://obspy.org) as backend.
57
61
 
@@ -118,33 +122,34 @@ To get help, use:
118
122
 
119
123
  requake -h
120
124
 
121
- The different running modes are specified as "verbs" (positional arguments).
122
- Currently supported verbs are:
125
+ Different commands are available:
123
126
 
124
127
  sample_config write sample config file to current directory and exit
128
+ update_config update an existing config file to the latest version
125
129
  read_catalog read an event catalog from web services or from a file
130
+ print_catalog print the event catalog to screen
126
131
  scan_catalog scan an existing catalog for earthquake pairs
132
+ print_pairs print pairs to screen
127
133
  plot_pair plot traces for a given event pair
128
134
  build_families build families of repeating earthquakes from a catalog
129
135
  of pairs
130
136
  print_families print families to screen
131
137
  plot_families plot traces for one ore more event families
132
138
  plot_timespans plot family timespans
133
- plot_slip plot cumulative slip for one or more families
139
+ plot_cumulative cumulative plot for one or more families
134
140
  map_families plot families on a map
135
141
  flag_family flag a family of repeating earthquakes as valid or not
136
- valid. Note that all families are valid by default
137
- when first created
142
+ valid.
138
143
  build_templates build waveform templates for one or more event
139
144
  families
140
145
  scan_templates scan a continuous waveform stream using one or more
141
146
  templates
142
147
 
143
- Certain running modes (e.g., `plot_pair`) require further arguments (use, e.g.,
148
+ Certain commands (e.g., `plot_pair`) require further arguments (use, e.g.,
144
149
  `requake plot_pair -h` to get help).
145
150
 
146
- Requake supports command line tab completion for arguments, thanks to
147
- [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/).
148
153
  To enable command line tab completion, add the following line to your `.bashrc`
149
154
  or `.zshrc`:
150
155
 
@@ -184,10 +189,35 @@ parallelization will be implemented.
184
189
 
185
190
  - `requake build_families` is fast™.
186
191
 
192
+ ## How to Cite
193
+
194
+ If you used Requake for a scientific paper, please cite it as:
195
+
196
+ > Satriano, C. (2024). Requake: Repeating earthquakes search and analysis (X.Y).
197
+ > [doi: 10.5281/ZENODO.10832204]
198
+
199
+ Please replace `X.Y` with the Requake version number you used.
200
+
201
+ You can also cite the following abstract presented at the
202
+ 2016 AGU Fall Meeting:
203
+
204
+ > Satriano, C., Doucet, A. & Bouin, M.-P. (2021).
205
+ > Probing the creep rate along the Lesser Antilles Subduction Zone through repeating earthquakes.
206
+ > In AGU Fall Meeting Abstracts
207
+ > (Vol. 2021, pp. T25A-0167), [bibcode: 2021AGUFM.T25A0167S]
208
+
187
209
  <!-- Badges and project links -->
188
210
  [PyPI-badge]: http://img.shields.io/pypi/v/requake.svg
189
211
  [PyPI-link]: https://pypi.python.org/pypi/requake
190
212
  [license-badge]: https://img.shields.io/badge/license-GPLv3-green
191
213
  [license-link]: https://www.gnu.org/licenses/gpl-3.0.html
214
+ [docs-badge]: https://readthedocs.org/projects/requake/badge/?version=latest
215
+ [docs-link]: https://requake.readthedocs.io/en/latest/?badge=latest
192
216
  [changelog-badge]: https://img.shields.io/badge/Changelog-136CB6.svg
193
217
  [changelog-link]: https://github.com/SeismicSource/requake/blob/main/CHANGELOG.md
218
+ [DOI-badge]: https://zenodo.org/badge/DOI/10.5281/zenodo.10832204.svg
219
+ [DOI-link]: https://doi.org/10.5281/zenodo.10832204
220
+
221
+ <!-- References -->
222
+ [doi: 10.5281/ZENODO.10832204]: https://doi.org/10.5281/ZENODO.10832204
223
+ [bibcode: 2021AGUFM.T25A0167S]: https://ui.adsabs.harvard.edu/abs/2021AGUFM.T25A0167S
@@ -1,3 +1,5 @@
1
+ <img src="imgs/Requake_logo.svg" width="400">
2
+
1
3
  # Requake
2
4
 
3
5
  Repeating earthquakes search and analysis.
@@ -5,6 +7,8 @@ Repeating earthquakes search and analysis.
5
7
  [![changelog-badge]][changelog-link]
6
8
  [![PyPI-badge]][PyPI-link]
7
9
  [![license-badge]][license-link]
10
+ [![docs-badge]][docs-link]
11
+ [![DOI-badge]][DOI-link]
8
12
 
9
13
  Copyright (c) 2021-2024 Claudio Satriano <satriano@ipgp.fr>
10
14
 
@@ -15,8 +19,8 @@ Requake is a command line tool to search and analyse repeating earthquakes.
15
19
  It can either scan an existing earthquake catalog to search for similar events,
16
20
  or perform template matching on a continuous waveform stream.
17
21
 
18
- Catalogs and waveforms are downloaded using standard
19
- [FDSN web services](https://www.fdsn.org/webservices/).
22
+ Catalogs and waveforms can be read from local files or downloaded using
23
+ standard [FDSN web services](https://www.fdsn.org/webservices/).
20
24
 
21
25
  Requake is written in Python and uses [ObsPy](https://obspy.org) as backend.
22
26
 
@@ -83,33 +87,34 @@ To get help, use:
83
87
 
84
88
  requake -h
85
89
 
86
- The different running modes are specified as "verbs" (positional arguments).
87
- Currently supported verbs are:
90
+ Different commands are available:
88
91
 
89
92
  sample_config write sample config file to current directory and exit
93
+ update_config update an existing config file to the latest version
90
94
  read_catalog read an event catalog from web services or from a file
95
+ print_catalog print the event catalog to screen
91
96
  scan_catalog scan an existing catalog for earthquake pairs
97
+ print_pairs print pairs to screen
92
98
  plot_pair plot traces for a given event pair
93
99
  build_families build families of repeating earthquakes from a catalog
94
100
  of pairs
95
101
  print_families print families to screen
96
102
  plot_families plot traces for one ore more event families
97
103
  plot_timespans plot family timespans
98
- plot_slip plot cumulative slip for one or more families
104
+ plot_cumulative cumulative plot for one or more families
99
105
  map_families plot families on a map
100
106
  flag_family flag a family of repeating earthquakes as valid or not
101
- valid. Note that all families are valid by default
102
- when first created
107
+ valid.
103
108
  build_templates build waveform templates for one or more event
104
109
  families
105
110
  scan_templates scan a continuous waveform stream using one or more
106
111
  templates
107
112
 
108
- Certain running modes (e.g., `plot_pair`) require further arguments (use, e.g.,
113
+ Certain commands (e.g., `plot_pair`) require further arguments (use, e.g.,
109
114
  `requake plot_pair -h` to get help).
110
115
 
111
- Requake supports command line tab completion for arguments, thanks to
112
- [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/).
113
118
  To enable command line tab completion, add the following line to your `.bashrc`
114
119
  or `.zshrc`:
115
120
 
@@ -149,10 +154,35 @@ parallelization will be implemented.
149
154
 
150
155
  - `requake build_families` is fast™.
151
156
 
157
+ ## How to Cite
158
+
159
+ If you used Requake for a scientific paper, please cite it as:
160
+
161
+ > Satriano, C. (2024). Requake: Repeating earthquakes search and analysis (X.Y).
162
+ > [doi: 10.5281/ZENODO.10832204]
163
+
164
+ Please replace `X.Y` with the Requake version number you used.
165
+
166
+ You can also cite the following abstract presented at the
167
+ 2016 AGU Fall Meeting:
168
+
169
+ > Satriano, C., Doucet, A. & Bouin, M.-P. (2021).
170
+ > Probing the creep rate along the Lesser Antilles Subduction Zone through repeating earthquakes.
171
+ > In AGU Fall Meeting Abstracts
172
+ > (Vol. 2021, pp. T25A-0167), [bibcode: 2021AGUFM.T25A0167S]
173
+
152
174
  <!-- Badges and project links -->
153
175
  [PyPI-badge]: http://img.shields.io/pypi/v/requake.svg
154
176
  [PyPI-link]: https://pypi.python.org/pypi/requake
155
177
  [license-badge]: https://img.shields.io/badge/license-GPLv3-green
156
178
  [license-link]: https://www.gnu.org/licenses/gpl-3.0.html
179
+ [docs-badge]: https://readthedocs.org/projects/requake/badge/?version=latest
180
+ [docs-link]: https://requake.readthedocs.io/en/latest/?badge=latest
157
181
  [changelog-badge]: https://img.shields.io/badge/Changelog-136CB6.svg
158
- [changelog-link]: https://github.com/SeismicSource/requake/blob/main/CHANGELOG.md
182
+ [changelog-link]: https://github.com/SeismicSource/requake/blob/main/CHANGELOG.md
183
+ [DOI-badge]: https://zenodo.org/badge/DOI/10.5281/zenodo.10832204.svg
184
+ [DOI-link]: https://doi.org/10.5281/zenodo.10832204
185
+
186
+ <!-- References -->
187
+ [doi: 10.5281/ZENODO.10832204]: https://doi.org/10.5281/ZENODO.10832204
188
+ [bibcode: 2021AGUFM.T25A0167S]: https://ui.adsabs.harvard.edu/abs/2021AGUFM.T25A0167S
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-03-11T15:31:32+0100",
11
+ "date": "2024-05-04T17:23:20+0200",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "fa843d40d788a71f300e374e489cb575396d71c6",
15
- "version": "0.4.1"
14
+ "full-revisionid": "dc9a6e6fd818e57e0c0d74f9c16f2bfc6d4d148c",
15
+ "version": "0.6"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -10,3 +10,4 @@ Functions and data structures for managing earthquake catalogs.
10
10
  (https://www.gnu.org/licenses/gpl-3.0-standalone.html)
11
11
  """
12
12
  from .read_catalog import read_catalog # noqa
13
+ from .print_catalog import print_catalog # noqa
@@ -182,6 +182,72 @@ class RequakeCatalog(list):
182
182
  fp.write(ev.fdsn_text() + '\n')
183
183
 
184
184
 
185
+ def filter(
186
+ self, starttime=None, endtime=None,
187
+ minlatitude=None, maxlatitude=None,
188
+ minlongitude=None, maxlongitude=None,
189
+ mindepth=None, maxdepth=None,
190
+ minmagnitude=None, maxmagnitude=None):
191
+ """
192
+ Filter the catalog, based on the specified criteria.
193
+
194
+ Returns a new catalog.
195
+
196
+ :param starttime: start time
197
+ :type starttime: obspy.UTCDateTime
198
+ :param endtime: end time
199
+ :type endtime: obspy.UTCDateTime
200
+ :param minlatitude: minimum latitude
201
+ :type minlatitude: float
202
+ :param maxlatitude: maximum latitude
203
+ :type maxlatitude: float
204
+ :param minlongitude: minimum longitude
205
+ :type minlongitude: float
206
+ :param maxlongitude: maximum longitude
207
+ :type maxlongitude: float
208
+ :param mindepth: minimum depth (in km)
209
+ :type mindepth: float
210
+ :param maxdepth: maximum depth (in km)
211
+ :type maxdepth: float
212
+ :param minmagnitude: minimum magnitude
213
+ :type minmagnitude: float
214
+ :param maxmagnitude: maximum magnitude
215
+ :type maxmagnitude: float
216
+
217
+ :return: a new catalog
218
+ :rtype: RequakeCatalog
219
+ """
220
+ outcat = RequakeCatalog()
221
+ for ev in self:
222
+ if ev.orig_time is not None:
223
+ if starttime is not None and ev.orig_time < starttime:
224
+ continue
225
+ if endtime is not None and ev.orig_time > endtime:
226
+ continue
227
+ if ev.lat is not None:
228
+ if minlatitude is not None and ev.lat < minlatitude:
229
+ continue
230
+ if maxlatitude is not None and ev.lat > maxlatitude:
231
+ continue
232
+ if ev.lon is not None:
233
+ if minlongitude is not None and ev.lon < minlongitude:
234
+ continue
235
+ if maxlongitude is not None and ev.lon > maxlongitude:
236
+ continue
237
+ if ev.depth is not None:
238
+ if mindepth is not None and ev.depth < mindepth:
239
+ continue
240
+ if maxdepth is not None and ev.depth > maxdepth:
241
+ continue
242
+ if ev.mag is not None:
243
+ if minmagnitude is not None and ev.mag < minmagnitude:
244
+ continue
245
+ if maxmagnitude is not None and ev.mag > maxmagnitude:
246
+ continue
247
+ outcat.append(ev)
248
+ return outcat
249
+
250
+
185
251
  def read_stored_catalog(config):
186
252
  """
187
253
  Read the catalog stored in the output directory.
@@ -198,10 +264,13 @@ def read_stored_catalog(config):
198
264
  try:
199
265
  cat = RequakeCatalog()
200
266
  cat.read(config.scan_catalog_file)
267
+ cat.sort()
268
+ if not cat:
269
+ raise ValueError('Empty catalog')
201
270
  return cat
202
271
  except ValueError as m:
203
272
  raise ValueError(
204
- f'Error reading catalog file {config.scan_catalog_file}'
273
+ f'Error reading catalog file {config.scan_catalog_file}: {m}'
205
274
  ) from m
206
275
  except FileNotFoundError as m:
207
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)
@@ -9,6 +9,7 @@ Read an event catalog from web services or from a file.
9
9
  GNU General Public License v3.0 or later
10
10
  (https://www.gnu.org/licenses/gpl-3.0-standalone.html)
11
11
  """
12
+ import os
12
13
  import logging
13
14
  import contextlib
14
15
  from ..catalog.catalog import RequakeCatalog
@@ -34,8 +35,14 @@ def _read_catalog_from_file(config):
34
35
  :raises ValueError: if the file format is not supported
35
36
  """
36
37
  catalog_file = config.args.catalog_file
38
+ # return ValueError if the file is empty
39
+ if os.stat(catalog_file).st_size == 0:
40
+ raise ValueError('Empty file')
41
+ # return ValueError if the file is a directory
42
+ if os.path.isdir(catalog_file):
43
+ raise ValueError('Is a directory')
37
44
  # try to read the catalog as a QuakeML file
38
- with contextlib.suppress(TypeError):
45
+ with contextlib.suppress(TypeError, IndexError, ValueError):
39
46
  return read_catalog_from_quakeml(catalog_file)
40
47
  # try to read the catalog as a FDSN text file
41
48
  with contextlib.suppress(ValueError):
@@ -47,6 +54,45 @@ def _read_catalog_from_file(config):
47
54
  return read_catalog_from_csv(catalog_file)
48
55
 
49
56
 
57
+ def _filter_catalog(catalog, config):
58
+ """
59
+ Filter an event catalog, based on the criteria specified
60
+ in the configuration.
61
+
62
+ :param catalog: Event catalog.
63
+ :type catalog: requake.catalog.RequakeCatalog
64
+ :param config: Configuration object.
65
+ :type config: requake.rq_setup.RequakeConfig
66
+ :return: Filtered event catalog.
67
+ :rtype: requake.catalog.RequakeCatalog
68
+ """
69
+ lon_min = config.catalog_lon_min
70
+ lon_max = config.catalog_lon_max
71
+ lat_min = config.catalog_lat_min
72
+ lat_max = config.catalog_lat_max
73
+ depth_min = config.catalog_depth_min
74
+ depth_max = config.catalog_depth_max
75
+ mag_min = config.catalog_mag_min
76
+ mag_max = config.catalog_mag_max
77
+ outcat = catalog
78
+ for start_time, end_time in zip(config.catalog_start_times,
79
+ config.catalog_end_times):
80
+ outcat = outcat.filter(
81
+ starttime=start_time, endtime=end_time,
82
+ minlatitude=lat_min, maxlatitude=lat_max,
83
+ minlongitude=lon_min, maxlongitude=lon_max,
84
+ mindepth=depth_min, maxdepth=depth_max,
85
+ minmagnitude=mag_min, maxmagnitude=mag_max
86
+ )
87
+ nevents_in = len(catalog)
88
+ nevents_out = len(outcat)
89
+ logger.info(
90
+ 'Catalog filtered based on configuration file: '
91
+ f'{nevents_out} events out of {nevents_in}'
92
+ )
93
+ return outcat
94
+
95
+
50
96
  def read_catalog(config):
51
97
  """
52
98
  Read an event catalog from web services or from a file.
@@ -59,34 +105,42 @@ def read_catalog(config):
59
105
  :rtype: requake.catalog.RequakeCatalog
60
106
  """
61
107
  catalog = RequakeCatalog()
62
- out_cat_file = config.scan_catalog_file
108
+ output_cat_file = config.scan_catalog_file
63
109
  nevs_read = 0
64
110
  if config.args.append:
65
111
  with contextlib.suppress(FileNotFoundError):
66
112
  catalog = RequakeCatalog()
67
- catalog.read(out_cat_file)
113
+ catalog.read(output_cat_file)
68
114
  nevs_read = len(catalog)
69
- logger.info(f'{nevs_read} events read from "{out_cat_file}"')
115
+ logger.info(f'{nevs_read} events read from "{output_cat_file}"')
70
116
  logger.info('Reading catalog...')
71
- in_cat_file = config.args.catalog_file
72
- if in_cat_file is not None:
117
+ input_cat_file = config.args.catalog_file
118
+ if input_cat_file is not None:
73
119
  try:
74
120
  catalog += _read_catalog_from_file(config)
121
+ # Filter catalog based on configuration
122
+ catalog = _filter_catalog(catalog, config)
75
123
  except FileNotFoundError:
76
- logger.error(f'File "{in_cat_file}" not found')
124
+ logger.error(f'File "{input_cat_file}" not found')
77
125
  rq_exit(1)
78
126
  except ValueError as m:
79
- logger.error(f'Error reading catalog file "{in_cat_file}": {m}')
127
+ logger.error(f'Error reading catalog file "{input_cat_file}": {m}')
80
128
  rq_exit(1)
81
129
  else:
82
130
  catalog += read_catalog_from_fdsnws(config)
83
131
  if not catalog:
84
132
  logger.error('No event read')
85
133
  rq_exit(1)
134
+ # Deduplicate catalog
135
+ len_before = len(catalog)
86
136
  catalog.deduplicate()
137
+ len_after = len(catalog)
138
+ nevs_dedup = len_before - len_after
139
+ if nevs_dedup > 0:
140
+ logger.info(f'{nevs_dedup} duplicate events removed')
87
141
  # Sort catalog in increasing time order
88
142
  catalog.sort()
89
143
  # Write catalog to output file
90
- catalog.write(out_cat_file)
144
+ catalog.write(output_cat_file)
91
145
  nevs_written = len(catalog) - nevs_read
92
- logger.info(f'{nevs_written} events written to "{out_cat_file}"')
146
+ logger.info(f'{nevs_written} events written to "{output_cat_file}"')
@@ -183,7 +183,17 @@ def read_catalog_from_csv(filename):
183
183
  year=year, month=month, day=day,
184
184
  hour=hour, minute=minute, second=0) + seconds
185
185
  else:
186
- orig_time = UTCDateTime(row[fields['orig_time']])
186
+ try:
187
+ orig_time = UTCDateTime(row[fields['orig_time']])
188
+ except ValueError:
189
+ # one last try: check if the time is in the format
190
+ # YYYYMMDD.hhmmss.
191
+ # Replace the dot with a space, pad with zeros
192
+ # and try again
193
+ orig_time = UTCDateTime(
194
+ row[fields['orig_time']]
195
+ .replace('.', ' ').ljust(15, '0')
196
+ )
187
197
  row[None] = None
188
198
  ev = RequakeEvent()
189
199
  ev.orig_time = orig_time
@@ -4,9 +4,19 @@
4
4
  ## FDSN station webservice URL to retrieve station metadata.
5
5
  ## Use a full URL or a ObsPy shortcut (e.g., IRIS, RESIF, GEOFON, ...)
6
6
  fdsn_station_url = string(default=http://example.com)
7
+ ## Alternatively, you can provide the path to a local file with station
8
+ ## metadata in any format supported by ObsPy (note that some formats may not
9
+ ## contain station coordinates, which are required for the scan,
10
+ ## see https://docs.obspy.org/packages/obspy.core.inventory.html).
11
+ ## If both fdsn_station_url and stationxml_file are provided, the
12
+ ## local file will be used.
13
+ station_metadata_path = string(default=None)
7
14
  ## FDSN dataselect webservice URL to retrieve waveforms.
8
15
  ## Use a full URL or a ObsPy shortcut (e.g., IRIS, RESIF, GEOFON, ...)
9
16
  fdsn_dataselect_url = string(default=http://example.com)
17
+ ## Alternatively, you can provide the path to a local SDS waveform archive
18
+ ## (see https://docs.obspy.org/packages/autogen/obspy.clients.filesystem.sds.html)
19
+ waveform_data_path = string(default=None)
10
20
 
11
21
  #### Catalog-based scan
12
22
  ### The following parameters are for a catalog-based scan:
@@ -118,3 +128,19 @@ distance_from_lat = float(default=None)
118
128
  ## Normalization will produce an average trace which is more representative
119
129
  ## of the family, but will be less effective in reducing noise.
120
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)