diff --git a/eqcorrscan/core/lag_calc.py b/eqcorrscan/core/lag_calc.py index 09adb6740..83e2ad555 100644 --- a/eqcorrscan/core/lag_calc.py +++ b/eqcorrscan/core/lag_calc.py @@ -12,6 +12,7 @@ import scipy import logging import os +import warnings from collections import Counter, namedtuple @@ -227,7 +228,7 @@ def xcorr_pick_family(family, stream, shift_len=0.2, min_cc=0.4, horizontal_chans=['E', 'N', '1', '2'], cores=1, interpolate=False, plot=False, plotdir=None, export_cc=False, cc_dir=None, - **kwargs): + check_full_seed=False, **kwargs): """ Compute cross-correlation picks for detections in a family. @@ -276,15 +277,27 @@ 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. """ + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") picked_dict = {} delta = family.template.st[0].stats.delta detect_streams_dict = _prepare_data( family=family, detect_data=stream, shift_len=shift_len, all_vert=all_vert, all_horiz=all_horiz, vertical_chans=vertical_chans, - horizontal_chans=horizontal_chans) + horizontal_chans=horizontal_chans, 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] @@ -401,8 +414,8 @@ 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, all_vert=False, - all_horiz=False, vertical_chans=['Z'], +def _prepare_data(family, detect_data, shift_len, check_full_seed, + all_vert=False, all_horiz=False, vertical_chans=['Z'], horizontal_chans=['E', 'N', '1', '2']): """ Prepare data for lag_calc - reduce memory here. @@ -414,6 +427,11 @@ def _prepare_data(family, detect_data, shift_len, all_vert=False, :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 @@ -441,8 +459,11 @@ def _prepare_data(family, detect_data, shift_len, all_vert=False, 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: @@ -463,7 +484,8 @@ def lag_calc(detections, detect_data, template_names, templates, all_vert=False, all_horiz=False, horizontal_chans=['E', 'N', '1', '2'], vertical_chans=['Z'], cores=1, interpolate=False, - plot=False, plotdir=None, export_cc=False, cc_dir=None, **kwargs): + plot=False, plotdir=None, export_cc=False, cc_dir=None, + check_full_seed=False, **kwargs): """ Cross-correlation derived picking of seismic events. @@ -525,6 +547,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. @@ -581,6 +608,12 @@ def lag_calc(detections, detect_data, template_names, templates, The correlation data that are saved to the binary files can be useful to select an appropriate threshold for your data. """ + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") # First check that sample rates are equal for everything for tr in detect_data: if tr.stats.sampling_rate != detect_data[0].stats.sampling_rate: @@ -611,7 +644,8 @@ def lag_calc(detections, detect_data, template_names, templates, 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, **kwargs) + export_cc=export_cc, cc_dir=cc_dir, + check_full_seed=check_full_seed, **kwargs) initial_cat.update(template_dict) # Order the catalogue to match the input output_cat = Catalog() diff --git a/eqcorrscan/core/match_filter/family.py b/eqcorrscan/core/match_filter/family.py index 03a65cffd..5239401a0 100644 --- a/eqcorrscan/core/match_filter/family.py +++ b/eqcorrscan/core/match_filter/family.py @@ -16,6 +16,7 @@ import os import shutil import logging +import warnings from obspy import UTCDateTime, Stream, Catalog from obspy.core.event import ( @@ -512,7 +513,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. @@ -585,6 +586,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. @@ -609,6 +616,13 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4, """ from eqcorrscan.core.lag_calc import xcorr_pick_family + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") + processed_stream = self._process_streams( stream=stream, pre_processed=pre_processed, process_cores=process_cores, parallel=parallel, @@ -619,7 +633,8 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4, min_cc_from_mean_cc_factor=min_cc_from_mean_cc_factor, vertical_chans=vertical_chans, cores=cores, interpolate=interpolate, plot=plot, plotdir=plotdir, - export_cc=export_cc, cc_dir=cc_dir, **kwargs) + export_cc=export_cc, cc_dir=cc_dir, + check_full_seed=check_full_seed, **kwargs) catalog_out = Catalog([ev for ev in picked_dict.values()]) for detection_id, event in picked_dict.items(): for pick in event.picks: diff --git a/eqcorrscan/core/match_filter/party.py b/eqcorrscan/core/match_filter/party.py index 403983ba7..15cb6afd4 100644 --- a/eqcorrscan/core/match_filter/party.py +++ b/eqcorrscan/core/match_filter/party.py @@ -18,6 +18,7 @@ import tarfile import tempfile import logging +import warnings from os.path import join import numpy as np @@ -838,7 +839,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. @@ -911,6 +912,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 + behaviour 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. @@ -936,6 +944,12 @@ def lag_calc(self, stream, pre_processed, shift_len=0.2, min_cc=0.4, .. Note:: Picks are corrected for the template pre-pick time. """ + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") process_cores = process_cores or cores template_groups = group_templates( [_f.template for _f in self.families @@ -970,7 +984,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 diff --git a/eqcorrscan/core/match_filter/template.py b/eqcorrscan/core/match_filter/template.py index ba8955c3b..bd874d68f 100644 --- a/eqcorrscan/core/match_filter/template.py +++ b/eqcorrscan/core/match_filter/template.py @@ -17,6 +17,7 @@ import re import shutil import logging +import warnings import numpy as np from obspy import Stream @@ -535,7 +536,8 @@ def construct(self, method, name, lowcut, highcut, samp_rate, filt_order, length, prepick, swin="all", process_len=86400, all_horiz=False, delayed=True, plot=False, plotdir=None, min_snr=None, parallel=False, num_cores=False, - skip_short_chans=False, **kwargs): + skip_short_chans=False, check_full_seed=False, + **kwargs): """ Construct a template using a given method. @@ -600,6 +602,13 @@ def construct(self, method, name, 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 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 + behaviour was originally necessary to cope with some software + (i.e. SEISAN) not storing picks with full SEED info. .. note:: @@ -644,6 +653,12 @@ def construct(self, method, name, lowcut, highcut, samp_rate, filt_order, Tribe.construct instead. """ + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") if method in ['from_meta_file', 'from_client', 'multi_template_gen']: raise NotImplementedError('Method is not supported, ' 'use Tribe.construct instead.') diff --git a/eqcorrscan/core/match_filter/tribe.py b/eqcorrscan/core/match_filter/tribe.py index 6927958ea..ef8aa32f2 100644 --- a/eqcorrscan/core/match_filter/tribe.py +++ b/eqcorrscan/core/match_filter/tribe.py @@ -19,6 +19,7 @@ import tarfile import tempfile import logging +import warnings import numpy as np from obspy import Catalog, Stream, read, read_events @@ -933,7 +934,8 @@ def construct(self, method, lowcut, highcut, samp_rate, filt_order, length, prepick, swin="all", process_len=86400, all_horiz=False, delayed=True, plot=False, plotdir=None, min_snr=None, parallel=False, num_cores=False, - skip_short_chans=False, save_progress=False, **kwargs): + skip_short_chans=False, save_progress=False, + check_full_seed=False, **kwargs): """ Generate a Tribe of Templates. @@ -1004,6 +1006,13 @@ def construct(self, method, lowcut, highcut, samp_rate, filt_order, :param save_progress: Whether to save the resulting party at every data step or not. Useful for long-running processes. + :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 + behaviour was originally necessary to cope with some software + (i.e. SEISAN) not storing picks with full SEED info. .. note:: *Method specific arguments:* @@ -1032,6 +1041,12 @@ def construct(self, method, lowcut, highcut, samp_rate, filt_order, .. Note:: Templates will be named according to their start-time. """ + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") templates, catalog, process_lengths = template_gen.template_gen( method=method, lowcut=lowcut, highcut=highcut, length=length, filt_order=filt_order, samp_rate=samp_rate, prepick=prepick, @@ -1039,7 +1054,7 @@ def construct(self, method, lowcut, highcut, samp_rate, filt_order, process_len=process_len, all_horiz=all_horiz, plotdir=plotdir, delayed=delayed, plot=plot, min_snr=min_snr, parallel=parallel, num_cores=num_cores, skip_short_chans=skip_short_chans, - **kwargs) + check_full_seed=check_full_seed, **kwargs) for template, event, process_len in zip(templates, catalog, process_lengths): t = Template() diff --git a/eqcorrscan/core/template_gen.py b/eqcorrscan/core/template_gen.py index 4fa489d58..5981c1230 100644 --- a/eqcorrscan/core/template_gen.py +++ b/eqcorrscan/core/template_gen.py @@ -20,6 +20,7 @@ import numpy as np import logging import os +import warnings from obspy import Stream, read, Trace, UTCDateTime, read_events from obspy.core.event import Catalog @@ -56,7 +57,8 @@ def template_gen(method, lowcut, highcut, samp_rate, filt_order, plotdir=None, return_event=False, min_snr=None, parallel=False, num_cores=False, save_progress=False, skip_short_chans=False, vertical_chans=['Z'], - horizontal_chans=['E', 'N', '1', '2'], **kwargs): + horizontal_chans=['E', 'N', '1', '2'], + check_full_seed=False, **kwargs): """ Generate processed and cut waveforms for use as templates. @@ -131,6 +133,13 @@ def template_gen(method, lowcut, highcut, samp_rate, filt_order, :param horizontal_chans: List of channel endings for horizontal channels, on which S-picks are accepted. + :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 @@ -244,6 +253,12 @@ def template_gen(method, lowcut, highcut, samp_rate, filt_order, >>> print(len(templates[0])) 15 """ + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") client_map = {'from_client': 'fdsn'} assert method in ('from_client', 'from_meta_file', 'from_sac') if not isinstance(swin, list): @@ -403,7 +418,8 @@ def template_gen(method, lowcut, highcut, samp_rate, filt_order, event.picks, st, length, swin, prepick=prepick, plot=plot, all_vert=all_vert, all_horiz=all_horiz, delayed=delayed, min_snr=min_snr, vertical_chans=vertical_chans, - horizontal_chans=horizontal_chans, plotdir=plotdir) + horizontal_chans=horizontal_chans, plotdir=plotdir, + check_full_seed=check_full_seed) process_lengths.append(len(st[0].data) / samp_rate) temp_list.append(template) catalog_out += event @@ -599,7 +615,8 @@ def _rms(array): def _template_gen(picks, st, length, swin='all', prepick=0.05, all_vert=False, all_horiz=False, delayed=True, plot=False, min_snr=None, plotdir=None, vertical_chans=['Z'], - horizontal_chans=['E', 'N', '1', '2']): + horizontal_chans=['E', 'N', '1', '2'], + check_full_seed=False): """ Master function to generate a multiplexed template for a single event. @@ -656,6 +673,13 @@ def _template_gen(picks, st, length, swin='all', prepick=0.05, all_vert=False, :param horizontal_chans: List of channel endings for horizontal channels, on which S-picks are accepted. + :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` @@ -736,11 +760,29 @@ def _template_gen(picks, st, length, swin='all', prepick=0.05, all_vert=False, 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] # Cope with missing phase_hints if _swin != "all": station_picks = [p for p in station_picks if p.phase_hint] @@ -817,8 +859,16 @@ def _template_gen(picks, st, length, swin='all', prepick=0.05, all_vert=False, 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']: diff --git a/eqcorrscan/tests/lag_calc_test.py b/eqcorrscan/tests/lag_calc_test.py index 635e57de0..35b2e363c 100644 --- a/eqcorrscan/tests/lag_calc_test.py +++ b/eqcorrscan/tests/lag_calc_test.py @@ -93,7 +93,8 @@ def test_prepare_data(self): shift_len = 0.2 for family in self.party: detect_stream_dict = _prepare_data( - family=family, detect_data=self.data, shift_len=shift_len) + family=family, detect_data=self.data, shift_len=shift_len, + check_full_seed=False) self._prepare_data_checks(detect_stream_dict=detect_stream_dict, family=family, shift_len=shift_len) @@ -103,7 +104,8 @@ def test_prepare_data_too_short(self): self.party[0][0].detect_time + 3) shift_len = 0.2 detect_stream_dict = _prepare_data( - family=self.party[0], detect_data=data, shift_len=shift_len) + family=self.party[0], detect_data=data, shift_len=shift_len, + check_full_seed=False) self.assertEqual(len(detect_stream_dict), 1) def test_prepare_data_masked(self): @@ -113,7 +115,8 @@ def test_prepare_data_masked(self): data.merge() shift_len = 0.2 detect_stream_dict = _prepare_data( - family=self.party[0], detect_data=data, shift_len=shift_len) + family=self.party[0], detect_data=data, shift_len=shift_len, + check_full_seed=False) short_key = self.party[0][0].id for key, value in detect_stream_dict.items(): detection = [d for d in self.party[0] if d.id == key][0] diff --git a/eqcorrscan/utils/catalog_to_dd.py b/eqcorrscan/utils/catalog_to_dd.py index 3bd7608a0..b57bf55c6 100644 --- a/eqcorrscan/utils/catalog_to_dd.py +++ b/eqcorrscan/utils/catalog_to_dd.py @@ -10,6 +10,7 @@ """ import numpy as np import logging +import warnings from collections import namedtuple, defaultdict, Counter from obspy.core import stream from multiprocessing import cpu_count, Pool @@ -233,7 +234,8 @@ def _prepare_stream(stream, event, extract_len, pre_pick, seed_pick_ids=None): def _compute_dt_correlations(catalog, master, min_link, event_id_mapper, stream_dict, min_cc, extract_len, pre_pick, - shift_len, interpolate, max_workers=1, **kwargs): + shift_len, interpolate, max_workers=1, + *args, **kwargs): """ Compute cross-correlation delay times. """ max_workers = max_workers or 1 Logger.info( @@ -404,17 +406,20 @@ def _compute_dt_correlations(catalog, master, min_link, event_id_mapper, return differential_times -def _compute_dt(sparse_catalog, master, min_link, event_id_mapper): +def _compute_dt(sparse_catalog, master, min_link, + event_id_mapper, check_full_seed): """ Inner function to compute differential times between a catalog and a master event. """ return [_make_event_pair( sparse_event=event, master=master, event_id_mapper=event_id_mapper, - min_link=min_link) for event in sparse_catalog] + min_link=min_link, check_full_seed=check_full_seed) + 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. """ @@ -425,9 +430,14 @@ def _make_event_pair(sparse_event, master, event_id_mapper, min_link): if master_pick.phase_hint and \ master_pick.phase_hint 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_hint == master_pick.phase_hint] + if check_full_seed: + matched_picks = [p for p in sparse_event.picks + if p.seed_id == master_pick.seed_id + and p.phase_hint == master_pick.phase_hint] + else: + matched_picks = [p for p in sparse_event.picks + if p.station == master_pick.station + and p.phase_hint == master_pick.phase_hint] for matched_pick in matched_picks: differential_times.obs.append( _DTObs(station=master_pick.station, @@ -482,7 +492,8 @@ def compute_differential_times(catalog, correlation, stream_dict=None, min_cc=None, extract_len=None, pre_pick=None, shift_len=None, interpolate=False, all_horiz=False, max_workers=None, - max_trace_workers=1, *args, **kwargs): + max_trace_workers=1, check_full_seed=False, + *args, **kwargs): """ Generate groups of differential times for a catalog. @@ -547,6 +558,12 @@ def compute_differential_times(catalog, correlation, stream_dict=None, quicker for few events with many or very long traces and requires less memory. """ + if not check_full_seed: + warnings.warn( + "Deprecation warning: check_full_seed will default to" + "True in a future release. Check the docs page here " + "for how this will affect you: " + "https://eqcorrscan.readthedocs.io/en/latest/faq.html") include_master = kwargs.get("include_master", False) correlation_kwargs = dict( min_cc=min_cc, stream_dict=stream_dict, extract_len=extract_len, @@ -573,7 +590,10 @@ def compute_differential_times(catalog, correlation, stream_dict=None, sparse_catalog = _prep_horiz_picks(sparse_catalog, stream_dict, event_id_mapper) - additional_args = dict(min_link=min_link, event_id_mapper=event_id_mapper) + additional_args = dict( + min_link=min_link, + event_id_mapper=event_id_mapper, + check_full_seed=check_full_seed) if correlation: differential_times = {} additional_args.update(correlation_kwargs)