Source code for seismic.inventory.inventory_split

#!/usr/bin/env python
"""Split a station inventory file into a separate file per network.
"""

from __future__ import print_function

import os
import sys
from collections import defaultdict

import click
from obspy.core.inventory import Inventory

from seismic.inventory.inventory_util import load_station_xml
from seismic.inventory.fdsnxml_convert import sc3_conversion_available, toSc3ml

PY2 = sys.version_info[0] < 3  # pylint: disable=invalid-name

if PY2:
    import pathlib2 as pathlib  # pylint: disable=import-error
else:
    import pathlib  # pylint: disable=import-error

try:
    import tqdm
    show_progress = True
except ImportError:  # pragma: no cover
    show_progress = False
    print("Run 'pip install tqdm' to see progress bar.")


[docs]def split_inventory_by_network(obspy_inv, output_folder, validate=False): """Export a station XML file per network for each network in given obspy Inventory. :param obspy_inv: Obspy Inventory containing the networks to export to file. :type obspy_inv: obspy.core.inventory.inventory.Inventory :param output_folder: Folder in which to output the per-network XML files. Will be created if doesn't yet exist. :type output_folder: str or pathlib.Path :param validate: Whether to validate the station data on write, defaults to False :type validate: bool, optional """ pathlib.Path(output_folder).mkdir(exist_ok=True) if show_progress: pbar = tqdm.tqdm(total=len(obspy_inv.networks), ascii=True) std_print = pbar.write else: std_print = print # Since duplicate network codes can occur, we ensure that output file names are unique by keeping an instance # count for the occurrences of each network, and appending this to the file name. network_count = defaultdict(int) for network in obspy_inv: if show_progress: pbar.update() pbar.set_description("Network {}".format(network.code)) net_inv = Inventory(networks=[network], source=obspy_inv.source) fname = "network_{}_{}.xml".format(network.code, network_count[network.code]) network_count[network.code] += 1 try: net_inv.write(os.path.join(output_folder, fname), format="stationxml", validate=validate) except Exception as e: std_print(str(e)) std_print("FAILED writing file {0} for network {1}, continuing".format(fname, network.code)) continue if show_progress: pbar.close()
[docs]def inventory_split(inv_file, output_folder, sc3ml=False): """Split an inventory file (station XML) into separate inventory file per network, stored in folder output_folder. :param inv_file: Station inventory to be split. This file is not changed by the script. :type inv_file: str or path :param output_folder: Folder where per-network station xml files will be generated. :type output_folder: str or path to folder :param sc3ml: If True, try to convert output files to sc3ml format if possible using seiscomp3. Defaults to False. :type sc3ml: bool, optional """ print("Loading file {}".format(inv_file)) stn_inventory = load_station_xml(inv_file) print("Splitting inventory into folder {}".format(output_folder)) split_inventory_by_network(stn_inventory, output_folder) # Can be large in memory, so release as soon as no longer needed. del stn_inventory # Perform sc3ml conversion if requested and if supported. if sc3ml and sc3_conversion_available(): sc3ml_output_folder = output_folder + "_sc3ml" try: toSc3ml(output_folder, sc3ml_output_folder) except OSError as e: print("WARNING: Unable to convert to sc3ml!") print(str(e)) if os.path.isdir(sc3ml_output_folder): import uuid print(" Renaming {} to avoid accidental use!".format(sc3ml_output_folder)) stashed_name = sc3ml_output_folder + ".BAD." + str(uuid.uuid4())[-8:] os.rename(sc3ml_output_folder, stashed_name)
@click.command() @click.option('--inv-file', type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True), required=True, help='Station inventory to be split. This file is not changed by the script.') @click.option('--output-folder', type=click.Path(exists=False, dir_okay=True), required=True, help='Folder where per-network station xml files will be generated.') @click.option('--sc3ml', is_flag=True, default=False, show_default=True, help='Try to convert output files to sc3ml format if possible using seiscomp3.') def main(inv_file, output_folder, sc3ml=False): # pragma: no cover """Main function. """ inventory_split(inv_file, output_folder, sc3ml) if __name__ == "__main__": main() # pylint: disable=no-value-for-parameter