Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Check full seed #391

Closed
wants to merge 72 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
a7d849c
add check_seed_id to _template_gen
Apr 27, 2020
f4edc37
pass check_seed_id from template_gen.template_gen to hidden func
Apr 28, 2020
87fe456
warning if not check_full_seed; avoid error in pretty_template_plot f…
May 9, 2020
f32d5cb
include net and loc in trace trimming
May 13, 2020
8e912fe
force full seed check in _make_event_pair()
cjhopp Aug 14, 2020
8547877
Merge branch 'develop' into check_full_seed_id
cjhopp Aug 17, 2020
b4051f2
opt-in only for check_full_seed
cjhopp Aug 17, 2020
2dc3940
Update Quick-start with correct merge method: #429
calum-chamberlain Sep 20, 2020
9a9b256
Pygments pinning for sphinx issues
calum-chamberlain Sep 20, 2020
7ad96bd
Add version info
calum-chamberlain Oct 8, 2020
2c69b87
Add version info.
calum-chamberlain Oct 8, 2020
5a2637d
add new function mapplot to plotting.py
Dec 29, 2019
8002226
add 3 samples output of mapplot
Dec 29, 2019
947d100
the additional_docstring added before mapplot functions
Dec 29, 2019
b8d2189
Test and a catalog added for testing mapplot
Dec 30, 2019
16a387d
add check_seed_id to _template_gen
Apr 27, 2020
be43c99
pass check_seed_id from template_gen.template_gen to hidden func
Apr 28, 2020
3b9c4b6
convert paramters to kwargs
May 8, 2020
cf8aa5a
making corrections to the labels
May 8, 2020
396e08c
Inputs of the function changed
May 8, 2020
c79e70b
The function's name changed
May 8, 2020
074aa70
Changing tests appropriate to new changes
May 8, 2020
953a149
warning if not check_full_seed; avoid error in pretty_template_plot f…
May 9, 2020
b91401b
include net and loc in trace trimming
May 13, 2020
77df1f1
pass kwargs to scatter functions
May 15, 2020
f4de09d
One output is enough
May 16, 2020
9de252e
down is positive now
May 16, 2020
7948fe4
test script changed for twoD_seismplot and catalog.txt removed
May 16, 2020
63a6485
Cope with no quality
calum-chamberlain Jul 17, 2020
e33b6f5
Add docs and return ints
calum-chamberlain Jul 23, 2020
2ebf109
changelog
calum-chamberlain Jul 23, 2020
c06e910
Higher precision times in phase.dat
calum-chamberlain Aug 2, 2020
aeb4b89
Added the ability of saving correlation data of the lag_calc.
Aug 7, 2020
ee78f60
Writing correction in note of lag_calc
Aug 7, 2020
e19d166
Make npydir
Aug 7, 2020
3edc9a6
change variables name same as #420
Aug 10, 2020
4b3a302
Added logger to export_cc
Aug 10, 2020
421ee28
Added test for export_cc in xcorr_pick_family
Aug 10, 2020
2fd3192
make line <79 characters
Aug 10, 2020
4c92509
Round to 1dp across all systems
calum-chamberlain Aug 10, 2020
db7518a
Round to 1 dp across all systems
calum-chamberlain Aug 10, 2020
fbea529
force full seed check in _make_event_pair()
cjhopp Aug 14, 2020
188ee5d
Apply suggestions from code review
calum-chamberlain Aug 14, 2020
28b176f
Move changelog to correct place
calum-chamberlain Aug 14, 2020
60d9fdc
Ensure `return_figure` isn't sent as a kwarg to plotting func.
calum-chamberlain Aug 15, 2020
1c7ad71
Check that the numpy files are actually written.
calum-chamberlain Aug 15, 2020
14c63b8
opt-in only for check_full_seed
cjhopp Aug 17, 2020
d30344b
Merge branch 'check_full_seed_id' of https://github.com/eqcorrscan/EQ…
cjhopp Dec 8, 2020
7a7ac02
add check_seed_id to _template_gen
Apr 27, 2020
2914b05
pass check_seed_id from template_gen.template_gen to hidden func
Apr 28, 2020
bc4d749
warning if not check_full_seed; avoid error in pretty_template_plot f…
May 9, 2020
2b5597d
include net and loc in trace trimming
May 13, 2020
ccf6d5a
force full seed check in _make_event_pair()
cjhopp Aug 14, 2020
b3a62a8
opt-in only for check_full_seed
cjhopp Aug 17, 2020
ffc6a9f
Update Quick-start with correct merge method: #429
calum-chamberlain Sep 20, 2020
0b71719
Pygments pinning for sphinx issues
calum-chamberlain Sep 20, 2020
385c9ae
Add version info
calum-chamberlain Oct 8, 2020
bd7701f
Add version info.
calum-chamberlain Oct 8, 2020
d239c23
add new function mapplot to plotting.py
Dec 29, 2019
4fa09dd
add 3 samples output of mapplot
Dec 29, 2019
795fa8b
the additional_docstring added before mapplot functions
Dec 29, 2019
b2ccda0
Test and a catalog added for testing mapplot
Dec 30, 2019
ae6529c
add check_seed_id to _template_gen
Apr 27, 2020
a2e07e0
pass check_seed_id from template_gen.template_gen to hidden func
Apr 28, 2020
f11d97c
warning if not check_full_seed; avoid error in pretty_template_plot f…
May 9, 2020
32a2118
include net and loc in trace trimming
May 13, 2020
ad7a94d
One output is enough
May 16, 2020
ee8d740
test script changed for twoD_seismplot and catalog.txt removed
May 16, 2020
c2b164d
force full seed check in _make_event_pair()
cjhopp Aug 14, 2020
d3c5460
opt-in only for check_full_seed
cjhopp Aug 17, 2020
e7a3547
rebase onto develop
cjhopp Dec 8, 2020
08f630c
check_full_seed arg for lag_calc methods
cjhopp Dec 8, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ assignees: ''

---

<!--
Please fill in the following

To get versions of python packages, import them and `print(package.__version__)`
-->

**Describe the bug**
A clear and concise description of what the bug is.

Expand Down
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/help-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ assignees: ''

<!--
Please fill out the form below so that we can help as best we can

To get versions of python packages, import them and `print(package.__version__)`
-->

# What do you need help with?
Expand Down
37 changes: 30 additions & 7 deletions eqcorrscan/core/lag_calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def _concatenate_and_correlate(streams, template, cores):
def xcorr_pick_family(family, stream, shift_len=0.2, min_cc=0.4,
horizontal_chans=['E', 'N', '1', '2'],
vertical_chans=['Z'], cores=1, interpolate=False,
plot=False, plotdir=None, export_cc=False, cc_dir=None):
plot=False, plotdir=None, export_cc=False, cc_dir=None,
check_full_seed=False):
"""
Compute cross-correlation picks for detections in a family.

Expand Down Expand Up @@ -234,13 +235,20 @@ def xcorr_pick_family(family, stream, shift_len=0.2, min_cc=0.4,
:type cc_dir: str
:param cc_dir:
Path to saving folder, NumPy files will be output here.
:type check_full_seed: bool
:param check_full_seed:
If True, will check for duplicate traces against the full SEED id,
including Network, Station, Location and Channel. If False (default),
will check only against Station and Channel.


:return: Dictionary of picked events keyed by detection id.
"""
picked_dict = {}
delta = family.template.st[0].stats.delta
detect_streams_dict = _prepare_data(
family=family, detect_data=stream, shift_len=shift_len)
family=family, detect_data=stream, shift_len=shift_len,
check_full_seed=check_full_seed)
detection_ids = list(detect_streams_dict.keys())
detect_streams = [detect_streams_dict[detection_id]
for detection_id in detection_ids]
Expand Down Expand Up @@ -349,7 +357,7 @@ def xcorr_pick_family(family, stream, shift_len=0.2, min_cc=0.4,
return picked_dict


def _prepare_data(family, detect_data, shift_len):
def _prepare_data(family, detect_data, shift_len, check_full_seed):
"""
Prepare data for lag_calc - reduce memory here.

Expand All @@ -360,6 +368,11 @@ def _prepare_data(family, detect_data, shift_len):
:param detect_data: Stream to extract detection streams from.
:type shift_len: float
:param shift_len: Shift length in seconds allowed for picking.
:type check_full_seed: bool
:param check_full_seed:
If True, will check for duplicate traces against the full SEED id,
including Network, Station, Location and Channel. If False (default),
will check only against Station and Channel.

:returns: Dictionary of detect_streams keyed by detection id
to be worked on
Expand All @@ -385,8 +398,11 @@ def _prepare_data(family, detect_data, shift_len):
detect_stream.remove(trace)
Logger.warning("Masked array found for {0}, not supported, "
"removing.".format(trace.id))
stachans = [(tr.stats.station, tr.stats.channel)
for tr in detect_stream]
if check_full_seed:
stachans = [tr.id for tr in detect_stream]
else:
stachans = [(tr.stats.station, tr.stats.channel)
for tr in detect_stream]
c_stachans = Counter(stachans)
for key in c_stachans.keys():
if c_stachans[key] > 1:
Expand All @@ -405,7 +421,8 @@ def _prepare_data(family, detect_data, shift_len):
def lag_calc(detections, detect_data, template_names, templates,
shift_len=0.2, min_cc=0.4, horizontal_chans=['E', 'N', '1', '2'],
vertical_chans=['Z'], cores=1, interpolate=False,
plot=False, plotdir=None, export_cc=False, cc_dir=None):
plot=False, plotdir=None, export_cc=False, cc_dir=None,
check_full_seed=False):
"""
Cross-correlation derived picking of seismic events.

Expand Down Expand Up @@ -462,6 +479,11 @@ def lag_calc(detections, detect_data, template_names, templates,
:type cc_dir: str
:param cc_dir:
Path to saving folder, NumPy files will be output here.
:type check_full_seed: bool
:param check_full_seed:
If True, will check for duplicate traces against the full SEED id,
including Network, Station, Location and Channel. If False (default),
will check only against Station and Channel.

:returns:
Catalog of events with picks. No origin information is included.
Expand Down Expand Up @@ -546,7 +568,8 @@ def lag_calc(detections, detect_data, template_names, templates,
min_cc=min_cc, horizontal_chans=horizontal_chans,
vertical_chans=vertical_chans, interpolate=interpolate,
cores=cores, shift_len=shift_len, plot=plot, plotdir=plotdir,
export_cc=export_cc, cc_dir=cc_dir)
export_cc=export_cc, cc_dir=cc_dir,
check_full_seed=check_full_seed)
initial_cat.update(template_dict)
# Order the catalogue to match the input
output_cat = Catalog()
Expand Down
10 changes: 8 additions & 2 deletions eqcorrscan/core/match_filter/family.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4,
cores=1, interpolate=False, plot=False, plotdir=None,
parallel=True, process_cores=None, ignore_length=False,
ignore_bad_data=False, export_cc=False, cc_dir=None,
**kwargs):
check_full_seed=False, **kwargs):
"""
Compute picks based on cross-correlation alignment.

Expand Down Expand Up @@ -572,6 +572,12 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4,
:type cc_dir: str
:param cc_dir:
Path to saving folder, NumPy files will be output here.
:type check_full_seed: bool
:param check_full_seed:
If True, will check for duplicate traces against the full SEED id,
including Network, Station, Location and Channel. If False (default),
will check only against Station and Channel.


:returns:
Catalog of events with picks. No origin information is included.
Expand Down Expand Up @@ -605,7 +611,7 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4,
min_cc=min_cc, horizontal_chans=horizontal_chans,
vertical_chans=vertical_chans, cores=cores,
interpolate=interpolate, plot=plot, plotdir=plotdir,
export_cc=export_cc, cc_dir=cc_dir)
export_cc=export_cc, cc_dir=cc_dir, check_full_seed=check_full_seed)
catalog_out = Catalog([ev for ev in picked_dict.values()])
for detection_id, event in picked_dict.items():
for pick in event.picks:
Expand Down
12 changes: 10 additions & 2 deletions eqcorrscan/core/match_filter/party.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4,
cores=1, interpolate=False, plot=False, plotdir=None,
parallel=True, process_cores=None, ignore_length=False,
ignore_bad_data=False, export_cc=False, cc_dir=None,
**kwargs):
check_full_seed=False, **kwargs):
"""
Compute picks based on cross-correlation alignment.

Expand Down Expand Up @@ -851,6 +851,13 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4,
If False (default), errors will be raised if data are excessively
gappy or are mostly zeros. If True then no error will be raised,
but an empty trace will be returned (and not used in detection).
:type check_full_seed: bool
:param check_full_seed:
If True, will check for duplicate traces against the full SEED id,
including Network, Station, Location and Channel. If False (default),
will check only against Station and Channel. This behavior was
originally necessary to cope with some software (i.e. SEISAN) not
storing picks with full SEED info.

:returns:
Catalog of events with picks. No origin information is included.
Expand Down Expand Up @@ -909,7 +916,8 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4,
export_cc=export_cc, cc_dir=cc_dir,
parallel=parallel, process_cores=process_cores,
ignore_bad_data=ignore_bad_data,
ignore_length=ignore_length, **kwargs)
ignore_length=ignore_length,
check_full_seed=check_full_seed, **kwargs)
return catalog

@staticmethod
Expand Down
59 changes: 49 additions & 10 deletions eqcorrscan/core/template_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def template_gen(method, lowcut, highcut, samp_rate, filt_order,
all_horiz=False, delayed=True, plot=False, plotdir=None,
return_event=False, min_snr=None, parallel=False,
num_cores=False, save_progress=False, skip_short_chans=False,
**kwargs):
check_full_seed=False, **kwargs):
"""
Generate processed and cut waveforms for use as templates.

Expand Down Expand Up @@ -120,6 +120,13 @@ def template_gen(method, lowcut, highcut, samp_rate, filt_order,
Whether to ignore channels that have insufficient length data or not.
Useful when the quality of data is not known, e.g. when downloading
old, possibly triggered data from a datacentre
:type check_full_seed: bool
:param check_full_seed:
If True, will check the trace header against the full SEED id,
including Network, Station, Location and Channel. If False (default),
will check only against Station and Channel. This behavior was
originally necessary to cope with some software (i.e. SEISAN) not
storing picks with full SEED info.

:returns: List of :class:`obspy.core.stream.Stream` Templates
:rtype: list
Expand Down Expand Up @@ -393,7 +400,7 @@ def template_gen(method, lowcut, highcut, samp_rate, filt_order,
template = _template_gen(
event.picks, st, length, swin, prepick=prepick, plot=plot,
all_horiz=all_horiz, delayed=delayed, min_snr=min_snr,
plotdir=plotdir)
plotdir=plotdir, check_full_seed=check_full_seed)
process_lengths.append(len(st[0].data) / samp_rate)
temp_list.append(template)
catalog_out += event
Expand Down Expand Up @@ -588,7 +595,7 @@ def _rms(array):

def _template_gen(picks, st, length, swin='all', prepick=0.05,
all_horiz=False, delayed=True, plot=False, min_snr=None,
plotdir=None):
plotdir=None, check_full_seed=False):
"""
Master function to generate a multiplexed template for a single event.

Expand Down Expand Up @@ -634,6 +641,13 @@ def _template_gen(picks, st, length, swin='all', prepick=0.05,
:param plotdir:
The path to save plots to. If `plotdir=None` (default) then the figure
will be shown on screen.
:type check_full_seed: bool
:param check_full_seed:
If True, will check the trace header against the full SEED id,
including Network, Station, Location and Channel. If False (default),
will check only against Station and Channel. This behavior was
originally necessary to cope with some software (i.e. SEISAN) not
storing picks with full SEED info.

:returns: Newly cut template.
:rtype: :class:`obspy.core.stream.Stream`
Expand Down Expand Up @@ -713,11 +727,29 @@ def _template_gen(picks, st, length, swin='all', prepick=0.05,
starttimes = []
for _swin in swin:
for tr in st:
starttime = {'station': tr.stats.station,
'channel': tr.stats.channel, 'picks': []}
station_picks = [pick for pick in picks_copy
if pick.waveform_id.station_code ==
tr.stats.station]
if check_full_seed:
starttime = {'network': tr.stats.network,
'station': tr.stats.station,
'location': tr.stats.location,
'channel': tr.stats.channel,
'picks': []}
station_picks = [pick for pick in picks_copy
if pick.waveform_id.network_code ==
tr.stats.network and
pick.waveform_id.station_code ==
tr.stats.station and
pick.waveform_id.location_code ==
tr.stats.location]
else:
Logger.warning(
'Not checking full SEED id compatibility between' +
' picks and waveforms. Checking full net.sta.loc.chan ' +
'compatibility will be default behavior in future release')
starttime = {'station': tr.stats.station,
'channel': tr.stats.channel, 'picks': []}
station_picks = [pick for pick in picks_copy
if pick.waveform_id.station_code ==
tr.stats.station]
if _swin == 'P_all':
p_pick = [pick for pick in station_picks
if pick.phase_hint.upper()[0] == 'P']
Expand Down Expand Up @@ -772,8 +804,15 @@ def _template_gen(picks, st, length, swin='all', prepick=0.05,
for _starttime in starttimes:
Logger.info(f"Working on channel {_starttime['station']}."
f"{_starttime['channel']}")
tr = st.select(
station=_starttime['station'], channel=_starttime['channel'])[0]
if check_full_seed:
tr = st.select(
network=_starttime['network'],
station=_starttime['station'],
location=_starttime['location'],
channel=_starttime['channel'])[0]
else:
tr = st.select(
station=_starttime['station'], channel=_starttime['channel'])[0]
Logger.info(f"Found Trace {tr}")
used_tr = False
for pick in _starttime['picks']:
Expand Down
6 changes: 4 additions & 2 deletions eqcorrscan/doc/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
matplotlib
sphinx_rtd_theme
nbsphinx
sphinx>=1.5.1
sphinx_bootstrap_theme
sphinx_bootstrap_theme
# have to pin otherwise RTD fails
# see https://github.com/readthedocs/readthedocs.org/issues/7492
Pygments==2.6.1
20 changes: 8 additions & 12 deletions eqcorrscan/doc/tutorials/quick_start.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,12 @@
"\n",
"We can also undertake cross-correlation phase-picking using our templates. This is achieved\n",
"using the `lag_calc` method on `Party` or `Family` objects. You can also use the\n",
"`eqcorrscan.core.lag_calc` module directly on other catalogs."
"`eqcorrscan.core.lag_calc` module directly on other catalogs.\n",
"\n",
"We need to provide a merged stream to the lag-calc function. The stream we have obtained\n",
"from `tribe.detect` has overlaps in it. Using `stream.merge()` would result in gaps at those\n",
"overlaps, which we do not want. We use `stream.merge(method=1)` to take include the real data\n",
"in that gap."
]
},
{
Expand All @@ -415,7 +420,7 @@
}
],
"source": [
"st = st.merge()\n",
"st = st.merge(method=1)\n",
"repicked_catalog = party.lag_calc(st, pre_processed=False, shift_len=0.5, min_cc=0.4)"
]
},
Expand Down Expand Up @@ -516,17 +521,8 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}
}
14 changes: 10 additions & 4 deletions eqcorrscan/utils/catalog_to_dd.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ def _compute_dt(sparse_catalog, master, min_link, event_id_mapper):
min_link=min_link) for event in sparse_catalog]


def _make_event_pair(sparse_event, master, event_id_mapper, min_link):
def _make_event_pair(sparse_event, master, event_id_mapper, min_link,
check_full_seed=False):
"""
Make an event pair for a given event and master event.
"""
Expand All @@ -339,9 +340,14 @@ def _make_event_pair(sparse_event, master, event_id_mapper, min_link):
for master_pick in master.picks:
if master_pick.phase and master_pick.phase not in "PS": # pragma: no cover
continue
matched_picks = [p for p in sparse_event.picks
if p.station == master_pick.station
and p.phase == master_pick.phase]
if check_full_seed:
matched_picks = [p for p in sparse_event.picks
if p.seed_id == master_pick.seed_id
and p.phase == master_pick.phase]
else:
matched_picks = [p for p in sparse_event.picks
if p.station == master_pick.station
and p.phase == master_pick.phase]
for matched_pick in matched_picks:
differential_times.obs.append(
_DTObs(station=master_pick.station,
Expand Down
Loading