### Install EQcorrscan from Source Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt Use this command to install EQcorrscan by running the setup.py script after downloading the source code. ```bash python setup.py install ``` -------------------------------- ### Install fftw3 Library on Ubuntu Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt On Ubuntu systems, install the fftw3 development libraries using apt-get. Ensure you have sudo access for this command. ```bash apt-get install libfftw3-dev ``` -------------------------------- ### Compile and Install fftw3 from Source on macOS Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt For macOS, compile and install fftw3 from source, enabling threads and float precision. This step is necessary if not using pre-compiled libraries. ```bash ./configure --enable-threads --enable-float && make make install ./configure --enable-threads && make # Need both double and float precision files make install ``` -------------------------------- ### Read and Write Template Example Source: https://eqcorrscan.readthedocs.io/en/latest/submodules/core.match_filter.template.html Demonstrates how to create a Template object, write it to a file, and then read it back. This is useful for saving and loading template configurations. ```python from obspy import read template_a = Template( name='a', st=read(), lowcut=2.0, highcut=8.0, samp_rate=100, filt_order=4, process_length=3600, prepick=0.5) template_a.write( 'test_template_read') Template a: 3 channels; lowcut: 2.0 Hz; highcut: 8.0 Hz; sampling rate 100 Hz; filter order: 4; process length: 3600 s template_b = Template().read('test_template_read.tgz') template_a == template_b ``` -------------------------------- ### Install Testing Dependencies Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/intro.rst.txt Install pytest, pytest-pep8, and pytest-cov using pip to prepare for running tests. ```bash pip install pytest pytest-pep8 pytest-cov ``` -------------------------------- ### Install EQcorrscan via Pip (after fftw3) Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt Once the fftw3 library is installed on your system, you can install EQcorrscan using pip. This command is applicable after manual dependency installation. ```bash pip install eqcorrscan ``` -------------------------------- ### Install GCC and fftw on macOS with Homebrew Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt For macOS, install a recent version of GCC and the fftw library using Homebrew. This is a prerequisite for compiling EQcorrscan. ```bash brew install gcc6 brew install fftw ``` -------------------------------- ### Create and Write Tribe Source: https://eqcorrscan.readthedocs.io/en/latest/submodules/core.match_filter.tribe.html Demonstrates creating a Tribe with templates and writing it to a file. Shows an example of an unsupported format causing a TypeError. ```python >>> tribe = Tribe(templates=[Template(name='c', st=read())]) >>> tribe.write('test_tribe') Tribe of 1 templates >>> tribe.write( ... "this_wont_work.bob", ... catalog_format="BOB") Traceback (most recent call last): TypeError: BOB is not supported ``` -------------------------------- ### Initialize Matplotlib and NumPy Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/tutorials/matched-filter.ipynb.txt Standard imports for numerical operations and plotting. Ensure these libraries are installed. ```python import matplotlib.pyplot as plt import numpy as np ``` -------------------------------- ### Install Testing Dependencies Source: https://eqcorrscan.readthedocs.io/en/latest/intro.html Installs pytest and related packages required for running EQcorrscan tests. Ensure you have pip installed. ```bash pip install pytest pytest-pep8 pytest-cov ``` -------------------------------- ### Install EQcorrscan with GCC Compiler Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt If the default compiler (clang) causes issues, specify GCC as the C compiler for installation. ```bash CC=gcc python setup.py install ``` -------------------------------- ### TriggerParameters and Network Triggering Example Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/utils/trigger.html Demonstrates how to set up TriggerParameters for seismic channels and use the network_trigger function to detect events. This example reads seismic data, configures trigger parameters for each trace, and then applies network triggering with coincidence sum and moveout criteria. ```python from obspy import read from eqcorrscan.utils.trigger import TriggerParameters, network_trigger st = read("https://examples.obspy.org/" + "example_local_earthquake_3stations.mseed") parameters = [] for tr in st: parameters.append(TriggerParameters({'station': tr.stats.station, 'channel': tr.stats.channel, 'sta_len': 0.5, 'lta_len': 10.0, 'thr_on': 10.0, 'thr_off': 3.0, 'lowcut': 2.0, 'highcut': 15.0})) triggers = network_trigger(st=st, parameters=parameters, thr_coincidence_sum=5, moveout=30, max_trigger_length=60, despike=False) print(len(triggers)) ``` -------------------------------- ### Catalog Clustering Example Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/utils/clustering.html Clusters an earthquake catalog using specified thresholds and metrics. Requires Obspy and FDSN client. ```python from eqcorrscan.utils.clustering import catalog_cluster from obspy.clients.fdsn import Client from obspy import UTCDateTime client = Client("https://earthquake.usgs.gov") starttime = UTCDateTime("2002-01-01") endtime = UTCDateTime("2002-02-01") cat = client.get_events(starttime=starttime, endtime=endtime, minmagnitude=6) groups = catalog_cluster(catalog=cat, thresh=1000, metric="time", show=False) ``` -------------------------------- ### Compute Network Triggers Source: https://eqcorrscan.readthedocs.io/en/latest/submodules/autogen/eqcorrscan.utils.trigger.network_trigger.html Example demonstrating how to compute network triggers using the network_trigger function. Requires Obspy Stream and a list of TriggerParameters. Sets despike to False. ```python from obspy import read from eqcorrscan.utils.trigger import TriggerParameters, network_trigger st = read("https://examples.obspy.org/" + "example_local_earthquake_3stations.mseed") parameters = [] for tr in st: parameters.append(TriggerParameters({'station': tr.stats.station, 'channel': tr.stats.channel, 'sta_len': 0.5, 'lta_len': 10.0, 'thr_on': 10.0, 'thr_off': 3.0, 'lowcut': 2.0, 'highcut': 15.0})) triggers = network_trigger(st=st, parameters=parameters, thr_coincidence_sum=5, moveout=30, max_trigger_length=60, despike=False) print(len(triggers)) ``` -------------------------------- ### Template Comparison Example Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/template.html Demonstrates how to compare two Template objects for equality. This includes comparing associated Stream and Event objects, as well as other processing parameters. ```python >>> from eqcorrscan.core.match_filter.party import Party >>> party = Party().read() >>> template_a = party.families[0].template >>> template_b = template_a.copy() >>> template_b.event.origins[0].time = \ ... template_a.event.origins[0].time + 20 >>> template_a == template_b False ``` -------------------------------- ### Example of using numpy_normxcorr with match_filter Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/submodules/utils.correlate.rst.txt Demonstrates how to import and use the numpy_normxcorr function as a backend for the match_filter function. This shows a basic setup for correlation analysis. ```python import obspy import numpy as np from eqcorrscan.utils.correlate import numpy_normxcorr, set_xcorr from eqcorrscan.core.match_filter import match_filter ``` -------------------------------- ### Read hypoDD phase file into Obspy Catalog Source: https://eqcorrscan.readthedocs.io/en/latest/submodules/autogen/eqcorrscan.utils.catalog_to_dd.read_phase.html Demonstrates how to use the `read_phase` function to load event information from a hypoDD phase file into an Obspy Catalog object. Ensure you have Obspy and eqcorrscan installed. The example uses a test data file provided by eqcorrscan. ```python from obspy.core.event.catalog import Catalog # Get the path to the test data import eqcorrscan import os TEST_PATH = os.path.dirname(eqcorrscan.__file__) + '/tests/test_data' catalog = read_phase(TEST_PATH + '/tunnel.phase') isinstance(catalog, Catalog) True ``` -------------------------------- ### Initialize and Use TriggerParameters Source: https://eqcorrscan.readthedocs.io/en/latest/submodules/autogen/eqcorrscan.utils.trigger.TriggerParameters.html Demonstrates initializing TriggerParameters with default values and then updating them. It also shows how to initialize using a dictionary of parameters. Use this to set up trigger configurations. ```python >>> from eqcorrscan.utils.trigger import TriggerParameters >>> defaults = TriggerParameters() >>> defaults.station = 'TEST' >>> # Or use dictionaries >>> defaults['station'] = 'ALF' >>> defaults = TriggerParameters({'station': 'TEST', ... 'channel': 'SHZ', ... 'sta_len': 0.3, ... 'lta_len': 10.0, ... 'thr_on': 10, ... 'thr_off': 3, ... 'lowcut': 2, ... 'highcut': 20}) >>> print(defaults.station) TEST ``` -------------------------------- ### Tribe Initialization and Indexing Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/tribe.html Demonstrates how to initialize a Tribe with multiple templates and access individual templates or slices using indexing. Also shows how to retrieve templates by name. ```python tribe = Tribe(templates=[Template(name='a'), Template(name='b'), Template(name='c')]) tribe[1] # doctest: +NORMALIZE_WHITESPACE Template b: 0 channels; lowcut: None Hz; highcut: None Hz; sampling rate None Hz; filter order: None; process length: None s tribe[0:2] Tribe of 2 templates tribe["d"] [] ``` -------------------------------- ### Tribe Class Initialization and Reading Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/tribe.html Demonstrates how to initialize a Tribe object, write it to a file, and read it back, including support for both compressed tarball and pickle formats. ```APIDOC ## Class: Tribe ### Description Represents a collection of seismic templates for event detection. ### Methods #### `__init__(self, templates=None, filename=None)` Initializes a Tribe object. Can be initialized with a list of templates or by reading from a file. #### `read(self, filename)` Reads a Tribe object from a specified file. Supports '.pkl' (pickle) and compressed tarball formats. **Parameters:** - **filename** (str) - The path to the file to read the Tribe from. **Returns:** - `self` - The Tribe object after reading and loading data. ### Internal Methods #### `_read_from_folder(self, dirname)` Internal method to read templates from a specified directory. **Parameters:** - **dirname** (str) - The directory containing template files and associated data. ``` -------------------------------- ### Install EQcorrscan on macOS with Homebrew (GCC) Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt After installing dependencies on macOS, use pip to install EQcorrscan, specifying CC=gcc to ensure correct compilation with OpenMP support. ```bash CC=gcc pip install eqcorrscan ``` -------------------------------- ### Local Data Access with Obsplus Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/tutorials/matched-filter.ipynb.txt Demonstrates how to create a local database using obsplus for efficient data access with EQcorrscan. This is crucial for handling overlapping data chunks. ```python from obsplus.clients import Client client = Client(outdir=outdir) # Example of accessing data using the client # This part is conceptual and depends on how you'd use the client object # For instance, to get traces for a specific station and channel: # client.get_waveforms(network='NZ', station='EDRZ', location='10', channel='EHZ', # starttime=starttime, endtime=endtime) ``` -------------------------------- ### Plotting a Template with Background Data and Event Information Source: https://eqcorrscan.readthedocs.io/en/latest/submodules/autogen/eqcorrscan.utils.plotting.pretty_template_plot.html This example demonstrates how to plot a template stream, overlay background data, and include event information for sorting. Ensure necessary Obspy and EQcorrscan modules are imported and test data is accessible. ```python from obspy import read, read_events import os from eqcorrscan.core import template_gen from eqcorrscan.utils.plotting import pretty_template_plot import eqcorrscan TEST_PATH = os.path.dirname(eqcorrscan.__file__) + '/tests/test_data' test_file = os.path.join(TEST_PATH, 'REA', 'TEST_', '01-0411-15L.S201309') test_wavefile = os.path.join( TEST_PATH, 'WAV', 'TEST_', '2013-09-01-0410-35.DFDPC_024_00') event = read_events(test_file)[0] st = read(test_wavefile) st = st.filter('bandpass', freqmin=2.0, freqmax=15.0) for tr in st: tr = tr.trim(tr.stats.starttime + 30, tr.stats.endtime - 30) # Hack around seisan 2-letter channel naming tr.stats.channel = tr.stats.channel[0] + tr.stats.channel[-1] template = template_gen._template_gen(event.picks, st, 2) pretty_template_plot(template, background=st, # doctest +SKIP event=event) ``` -------------------------------- ### Install GCC on macOS with MacPorts Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt On macOS, if using MacPorts, install an up-to-date GCC version. GCC is required for OpenMP compatibility. ```bash port install gcc6 ``` -------------------------------- ### Install EQcorrscan in Existing Conda Environment Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt If you already have a conda environment set up, use this command to install EQcorrscan and its dependencies within it. ```bash conda install -c conda-forge eqcorrscan ``` -------------------------------- ### Creating a Family object Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/family.html Demonstrates how to initialize a Family object with a template and a list of detections. It also shows how to check for equality with a copy of itself. ```python from eqcorrscan import Template, Detection from eqcorrscan.core.match_filter import Family from obspy import UTCDateTime family = Family( template=Template(name='a'), detections=[ Detection(template_name='a', detect_time=UTCDateTime(0), no_chans=8, detect_val=4.2, threshold=1.2, typeofdet='corr', threshold_type='MAD', threshold_input=8.0), Detection(template_name='a', detect_time=UTCDateTime(0) + 10, no_chans=8, detect_val=4.5, threshold=1.2, typeofdet='corr', threshold_type='MAD', threshold_input=8.0)]) family == family.copy() ``` -------------------------------- ### Create and Write a Family Object Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/family.html Example of creating a Family object with templates and detections, and then writing it to a file. Requires importing Template, Detection, and obspy's read and UTCDateTime. ```python from eqcorrscan import Template, Detection from obspy import read from obspy.core.utcdatetime import UTCDateTime family = Family( template=Template(name='a', st=read()), detections=[ Detection(template_name='a', detect_time=UTCDateTime(0) + 200, no_chans=8, detect_val=4.2, threshold=1.2, typeofdet='corr', threshold_type='MAD', threshold_input=8.0), Detection(template_name='a', detect_time=UTCDateTime(0), no_chans=8, detect_val=4.5, threshold=1.2, typeofdet='corr', threshold_type='MAD', threshold_input=8.0), Detection(template_name='a', detect_time=UTCDateTime(0) + 10, no_chans=8, detect_val=4.5, threshold=1.2, typeofdet='corr', threshold_type='MAD', threshold_input=8.0)]) family.write('test_family') ``` -------------------------------- ### Install NumPy and Pip on macOS with MacPorts Source: https://eqcorrscan.readthedocs.io/en/latest/installation.html Installs NumPy and pip for Python 3.5 using MacPorts. You may need to prepend 'sudo'. ```bash port install py35-numpy py35-pip ``` -------------------------------- ### Sanitize Stream Length Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/utils/pre_processing.html Adjusts a seismic stream to a specified start and end time, or trims it based on available start or end times. It also handles potential off-by-one sample errors after trimming and returns the processed stream, calculated length, clipping status, and the effective start time. ```python from obspy import Stream, UTCDateTime def _sanitize_length(st, starttime=None, endtime=None): """ Check length and work out start, end, length and trimming criteria :param st: Stream to check :type st: obspy.core.Stream :param starttime: Desired starttime - if None, will be evaluated from data :type starttime: obspy.core.UTCDateTime :param endtime: DEsired endtime - can be None :type endtime: obspy.core.UTCDateTime :return: obspy.core.Stream, length[float], clip[bool], starttime[obspy.core.UTCDateTime] """ length, clip = None, False if starttime is not None and endtime is not None: for tr in st: Logger.info( f"Trimming {tr.id} between {starttime} and {endtime}") tr.trim(starttime, endtime) if len(tr.data) == ((endtime - starttime) * tr.stats.sampling_rate) + 1: Logger.info(f"{tr.id} between {tr.stats.starttime} and " f"{tr.stats.endtime} with {tr.stats.npts} samples " f"is overlength by one sample. Dropping last " f"sample.") tr.data = tr.data[0:-1] length = endtime - starttime clip = True elif starttime: for tr in st: tr.trim(starttime=starttime) elif endtime: for tr in st: tr.trim(endtime=endtime) return st, length, clip, starttime ``` -------------------------------- ### Writing a Tribe of Templates Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/tribe.html Demonstrates how to write a collection of templates to disk, including event catalogs and associated data. Supports different catalog formats and optional compression. Raises a TypeError if an unsupported catalog format is specified. ```python from eqcorrscan.core.match_filter import CAT_EXT_MAP if catalog_format not in CAT_EXT_MAP.keys(): raise TypeError("{0} is not supported".format(catalog_format)) dirname, ext = os.path.splitext(filename) if not os.path.isdir(dirname): os.makedirs(dirname) self._par_write(dirname) tribe_cat = Catalog() for t in self.templates: if t.event is not None: # Check that the name in the comment matches the template name for comment in t.event.comments: if not comment.text: comment.text = "eqcorrscan_template_{0}".format(t.name) elif comment.text.startswith("eqcorrscan_template_"): comment.text = "eqcorrscan_template_{0}".format(t.name) tribe_cat.append(t.event) if len(tribe_cat) > 0: tribe_cat.write( os.path.join(dirname, 'tribe_cat.{0}'.format( CAT_EXT_MAP[catalog_format])), format=catalog_format) for template in self.templates: template.st.write( os.path.join(dirname, '{0}.ms'.format(template.name)), format='MSEED') if compress: if not filename.endswith(".tgz"): Logger.info("Appending '.tgz' to filename.") filename += ".tgz" with tarfile.open(filename, "w:gz") as tar: tar.add(dirname, arcname=os.path.basename(dirname)) shutil.rmtree(dirname) return self ``` -------------------------------- ### Install NumPy and Pip on macOS with MacPorts Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt Install NumPy and Pip for your chosen Python version using MacPorts. You can also set pip as the default. ```bash port install py35-numpy py35-pip # optional, select pip35 as default pip port select --set pip pip35 ``` -------------------------------- ### Install Python 3.5 on macOS with MacPorts Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt Install a specific Python version (e.g., 3.5) from MacPorts. You can optionally set it as the default Python for your terminal. ```bash port install python35 # optional: select python35 as default python for terminal: port select --set python python35 ``` -------------------------------- ### Load and Print Catalog Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/tutorials/matched-filter.ipynb.txt Loads seismic event data from an XML file and prints the catalog. Ensure the 'tutorial_catalog.xml' file is accessible. ```python from obspy import read_events cat = read_events("tutorial_catalog.xml") print(cat) ``` -------------------------------- ### Concurrent Detection Workflow Setup Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/tribe.html This code sets up a concurrent detection workflow, handling stream input (either a Stream object or a Queue) and preparing temporary storage for templates. It initializes various queues for inter-process communication. ```python def _detect_concurrent( self, stream, template_ids, pre_processed, parallel_process, process_cores, ignore_length, overlap, ignore_bad_data, group_size, groups, sampling_rate, threshold, threshold_type, save_progress, xcorr_func, concurrency, cores, cc_squared, export_cccsums, parallel, peak_cores, trig_int, full_peaks, plot, plotdir, plot_format, make_events, min_stations, **kwargs ): """ Internal concurrent detect workflow. """ from eqcorrscan.core.match_filter.helpers.processes import ( _pre_processor, _prepper, _make_detections, _check_for_poison, _get_and_check, Poison) from eqcorrscan.core.match_filter.helpers.tribe import _corr_and_peaks if isinstance(stream, Stream): Logger.info("Copying stream to keep your original data safe") st_queue = Queue(maxsize=2) st_queue.put(stream.copy()) # Close off queue st_queue.put(None) stream = st_queue else: # Note that if a queue has been passed we do not try to keep # data safe Logger.warning("Streams in queue will be edited in-place, you " "should not re-use them") # To reduce load copying templates between processes we dump them to # disk and pass the dictionary of files template_dir = f".template_db_{uuid.uuid4()}" template_db = self._temporary_template_db(template_dir) # Set up processes and queues poison_queue = kwargs.get('poison_queue', Queue()) if not pre_processed: processed_stream_queue = Queue(maxsize=1) else: processed_stream_queue = stream # Prepped queue contains templates and stream (and extras) prepped_queue = Queue(maxsize=1) # Output queues peaks_queue = Queue() party_file_queue = Queue() # Set up processes if not pre_processed: pre_processor_process = Process( target=_pre_processor, kwargs=dict( input_stream_queue=stream, temp_stream_dir=self._stream_dir, template_ids=template_ids, pre_processed=pre_processed, filt_order=self.templates[0].filt_order, highcut=self.templates[0].highcut, lowcut=self.templates[0].lowcut, samp_rate=self.templates[0].samp_rate, process_length=self.templates[0].process_length, parallel=parallel_process, cores=process_cores, ignore_length=ignore_length, overlap=overlap, ignore_bad_data=ignore_bad_data, output_filename_queue=processed_stream_queue, poison_queue=poison_queue, ), name="ProcessProcess" ) ``` -------------------------------- ### Install GCC and Python on macOS with MacPorts Source: https://eqcorrscan.readthedocs.io/en/latest/installation.html Installs GCC (version >4 recommended for OpenMP) and Python 3.5 using MacPorts. You may need to prepend 'sudo'. ```bash port install gcc6 port install python35 ``` -------------------------------- ### Run Advanced Subspace Tutorial Source: https://eqcorrscan.readthedocs.io/en/latest/tutorials/subspace.html Executes the advanced subspace tutorial to demonstrate waveform detection capabilities. Requires waveform data and catalog information. Can optionally plot results and return detection streams. ```python """ Advanced subspace tutorial to show some of the capabilities of the method. This example uses waveforms from a known earthquake sequence (in the Wairarapa region north of Wellington, New Zealand). The catalogue locations etc can be downloaded from this link: http://quakesearch.geonet.org.nz/services/1.0.0/csv?bbox=175.37956,-40.97912,175.53097,-40.84628&startdate=2015-7-18T2:00:00&enddate=2016-7-18T3:00:00 """ import logging from http.client import IncompleteRead from obspy.clients.fdsn import Client from obspy import UTCDateTime, Stream from eqcorrscan.utils.catalog_utils import filter_picks from eqcorrscan.utils.clustering import catalog_cluster from eqcorrscan.core import subspace # Set up logging logging.basicConfig( level=logging.INFO, format="%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s") def run_tutorial(plot=False, multiplex=True, return_streams=False, cores=4, verbose=False): """ Run the tutorial. :return: detections """ client = Client("GEONET", debug=verbose) cat = client.get_events( minlatitude=-40.98, maxlatitude=-40.85, minlongitude=175.4, maxlongitude=175.5, starttime=UTCDateTime(2016, 5, 1), endtime=UTCDateTime(2016, 5, 20)) print(f"Downloaded a catalog of {len(cat)} events") # This gives us a catalog of events - it takes a while to download all # the information, so give it a bit! # We will generate a five station, multi-channel detector. cat = filter_picks(catalog=cat, top_n_picks=5) stachans = list(set( [(pick.waveform_id.station_code, pick.waveform_id.channel_code) for event in cat for pick in event.picks])) # In this tutorial we will only work on one cluster, defined spatially. # You can work on multiple clusters, or try to whole set. clusters = catalog_cluster( catalog=cat, metric="distance", thresh=2, show=False) # We will work on the largest cluster cluster = sorted(clusters, key=lambda c: len(c))[-1] # This cluster contains 32 events, we will now download and trim the # waveforms. Note that each chanel must start at the same time and be the # same length for multiplexing. If not multiplexing EQcorrscan will # maintain the individual differences in time between channels and delay # the detection statistics by that amount before stacking and detection. client = Client('GEONET') design_set = [] st = Stream() for event in cluster: print(f"Downloading for event {event.resource_id.id}") bulk_info = [] t1 = event.origins[0].time t2 = t1 + 25.1 # Have to download extra data, otherwise GeoNet will # trim wherever suits. t1 -= 0.1 for station, channel in stachans: try: st += client.get_waveforms( 'NZ', station, '*', channel[0:2] + '?', t1, t2) except IncompleteRead: print(f"Could not download for {station} {channel}") print(f"Downloaded {len(st)} channels") for event in cluster: t1 = event.origins[0].time t2 = t1 + 25 design_set.append(st.copy().trim(t1, t2)) # Construction of the detector will process the traces, then align them, # before multiplexing. print("Making detector") detector = subspace.Detector() detector.construct( streams=design_set, lowcut=2.0, highcut=9.0, filt_order=4, sampling_rate=20, multiplex=multiplex, name='Wairarapa1', align=True, reject=0.2, shift_len=6, plot=plot).partition(9) print("Constructed Detector") if plot: detector.plot() # We also want the continuous stream to detect in. t1 = UTCDateTime(2016, 5, 11, 19) t2 = UTCDateTime(2016, 5, 11, 20) # We are going to look in a single hour just to minimize cost, but you can # run for much longer. bulk_info = [('NZ', stachan[0], '*', stachan[1][0] + '?' + stachan[1][-1], t1, t2) for stachan in detector.stachans] print("Downloading continuous data") st = client.get_waveforms_bulk(bulk_info) st.merge().detrend('simple').trim(starttime=t1, endtime=t2) # We set a very low threshold because the detector is not that great, we # haven't aligned it particularly well - however, at this threshold we make # two real detections. print("Computing detections") detections, det_streams = detector.detect( st=st, threshold=0.4, trig_int=2, extract_detections=True, cores=cores) if return_streams: return detections, det_streams else: return detections if __name__ == '__main__': run_tutorial() ``` -------------------------------- ### Getting the Number of Detections in a Family Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/family.html Shows how to get the total number of detections stored within a Family object. This is a common operation for understanding the size of the detection set. ```python >>> from eqcorrscan import Template, Detection >>> family = Family( ... template=Template(name='a'), detections=[ ... Detection(template_name='a', detect_time=UTCDateTime(0), ... no_chans=8, detect_val=4.2, threshold=1.2, ... typeofdet='corr', threshold_type='MAD', ... threshold_input=8.0), ... Detection(template_name='a', detect_time=UTCDateTime(0) + 10, ... no_chans=8, detect_val=4.5, threshold=1.2, ... typeofdet='corr', threshold_type='MAD', ... threshold_input=8.0)]) >>> print(len(family)) 2 ``` -------------------------------- ### Create and Activate Conda Environment for EQcorrscan Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/installation.rst.txt Use this command to create a new conda environment named 'eqcorrscan' and install the package and its dependencies. It's recommended for isolating the installation. ```bash conda create -n eqcorrscan -c conda-forge eqcorrscan source activate eqcorrscan ``` -------------------------------- ### Convert Trace to Stream and Sanity Check Filter Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/utils/pre_processing.html This snippet demonstrates the initial steps of pre-processing, including converting a single Trace to a Stream if necessary and performing sanity checks on filter parameters like highcut relative to the Nyquist frequency and ensuring lowcut is not above highcut. ```python if isinstance(st, Trace): tracein = True st = Stream(st) else: tracein = False # Add sanity check for filter if highcut and highcut >= 0.5 * samp_rate: raise IOError('Highcut must be lower than the Nyquist') if highcut and lowcut: assert lowcut < highcut, f"Lowcut: {lowcut} above highcut: {highcut}" ``` -------------------------------- ### Subspace Detector Example Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/tutorials/subspace.rst.txt This example demonstrates computing detections for a short data period during an earthquake sequence. It shows a single subspace detector but can be extended to create multiple detectors using clustering routines. ```python from eqcorrscan.utils.read import read from eqcorrscan.core import SubspaceDetector # Load the detector (this is a placeholder, replace with your actual detector) detector = SubspaceDetector.load("path/to/your/detector.pkl") # Load the stream of seismic data stream = read(wavefiles[0]) # Detect events using the subspace detector detections = detector.detect(st=stream, threshold=0.5, trig_int=3) # doctest:+ELLIPSIS print(f"Found {len(detections)} detections.") ``` -------------------------------- ### get_catalog Source: https://eqcorrscan.readthedocs.io/en/latest/submodules/core.match_filter.party.html Get an obspy catalog object from the party. ```APIDOC ## get_catalog ### Description Get an obspy catalog object from the party. ### Method `get_catalog()` ### Returns `obspy.core.event.Catalog` ### Example ```python >>> party = Party().read() >>> cat = party.get_catalog() >>> print(len(cat)) 4 ``` ``` -------------------------------- ### Configure Logging Level and Format Source: https://eqcorrscan.readthedocs.io/en/latest/tutorial.html Set up the logging module to control the verbosity and format of output messages from EQcorrscan. This example sets the level to INFO and defines a custom format for log entries. ```python import logging logging.basicConfig( level=logging.INFO, format="%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s") ``` -------------------------------- ### Party Initialization and Length Check Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/party.html Demonstrates initializing a Party object with families and checking its length. The length is initially 0 as no detections are present. ```python >>> from eqcorrscan import Family, Template >>> party = Party(families=[Family(template=Template(name='a')), ... Family(template=Template(name='b'))]) >>> len(party) 0 ``` -------------------------------- ### Plotting Peaks in Seismic Data Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/utils/plotting.html Visualizes detected peaks on a seismic data trace. Requires Numpy array for data, Obspy UTCDateTime for start time, sampling rate, and a list of peak locations and amplitudes. The plot displays time in hours relative to the start time. ```python import matplotlib.pyplot as plt peaks = peaks or [(0, 0)] npts = len(data) t = np.arange(npts, dtype=np.float32) / (samp_rate * 3600) fig = plt.figure() ax1 = fig.add_subplot(111) ax1.plot(t, data, 'k') ax1.scatter(peaks[0][1] / (samp_rate * 3600), peaks[0][0], color='r', label='Peaks') for peak in peaks: ax1.scatter(peak[1] / (samp_rate * 3600), peak[0], color='r') ax1.legend() ax1.set_xlabel("Time after %s [hr]" % starttime.isoformat()) ax1.axis('tight') fig.suptitle('Peaks') fig = _finalise_figure(fig=fig, **kwargs) # pragma: no cover return fig ``` -------------------------------- ### Create Seismic Event Picks and Catalog Source: https://eqcorrscan.readthedocs.io/en/latest/_sources/tutorials/matched-filter.ipynb.txt Constructs seismic event picks and a catalog from scratch using ObsPy. Useful when event data is not available in a standard format. ```python from obspy.core.event import ( Catalog, Event, Pick, WaveformStreamID) from obspy import UTCDateTime # Make the picks for the event: picks = [ Pick( time=UTCDateTime(2023, 3, 18, 7, 46, 15, 593125), waveform_id=WaveformStreamID( network_code='NZ', station_code='MARZ', channel_code='EHZ', location_code='10'), phase_hint='P'), Pick( time=UTCDateTime(2023, 3, 18, 7, 46, 17, 633115), waveform_id=WaveformStreamID( network_code='NZ', station_code='MKRZ', channel_code='EHZ', location_code='10'), phase_hint='P'), Pick( time=UTCDateTime(2023, 3, 18, 7, 46, 18, 110000), waveform_id=WaveformStreamID( network_code='NZ', station_code='OMRZ', channel_code='EHZ', location_code='10'), phase_hint='P'), ] # Add as many picks as you have - you might want to loop # and/or make a function to pasre your picks to obspy Picks. # Make the event event = Event(picks=picks) # Make the catalog catalog = Catalog([event]) ``` -------------------------------- ### Party Length Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/party.html Explains how to get the total number of detections across all families in a Party object. ```APIDOC ## Party Length (`__len__`) ### Description Returns the total number of detections across all families within the `Party` object. ### Method `__len__` ### Return Value - **length** (int): The total count of detections. ### Example ```python from eqcorrscan import Party, Family, Template # Assume Family has a 'detections' attribute which is a list family1 = Family(template=Template(name='a')) family1.detections = [1, 2, 3] # Mock detections family2 = Family(template=Template(name='b')) family2.detections = [4, 5] # Mock detections party = Party(families=[family1, family2]) print(len(party)) # Expected output: 5 ``` ``` -------------------------------- ### Creating a Temporary Template Database Source: https://eqcorrscan.readthedocs.io/en/latest/_modules/eqcorrscan/core/match_filter/tribe.html Writes a temporary database of pickled templates to disk. Ensures template names are unique and creates a temporary directory if none is provided. Returns a dictionary mapping template names to their file paths. ```python # We use template names for filenames - check that these are unique self.__unique_ids() # Make sure that the template directory exists, or make a tempdir if template_dir: if not os.path.isdir(template_dir): os.makedirs(template_dir) else: template_dir = tempfile.mkdtemp() template_files = dict() for template in self.templates: t_file = os.path.join(template_dir, f"{template.name}.pkl") with open(t_file, "wb") as f: pickle.dump(template, f) template_files.update({template.name: t_file}) return template_files ```