forked from episodes-platform/shared-snippets
Removed unnecessary python snippets
This commit is contained in:
parent
c81a456449
commit
450884838e
@ -1,120 +0,0 @@
|
||||
import pandas as pd
|
||||
|
||||
from obspy.core.event import Catalog
|
||||
from obspy.core.event import Event
|
||||
from obspy.core.event import Pick
|
||||
from obspy.core.event import Origin
|
||||
from obspy.core.event import OriginQuality
|
||||
|
||||
from obspy import UTCDateTime
|
||||
from obspy.core.event.base import WaveformStreamID, Comment
|
||||
|
||||
|
||||
class CatalogConverter:
|
||||
"""
|
||||
Class for converting SeisBench and pyOcto detection results to ObsPy Catalog, which can be saved as QuakeML.
|
||||
"""
|
||||
def __init__(self, config, picks, catalog_df, assignments_df, name_of_algorithm):
|
||||
self._catalog_df = catalog_df
|
||||
self._assignments_df = assignments_df
|
||||
self._picks = picks
|
||||
self._config = config
|
||||
self._name_of_algorithm = name_of_algorithm
|
||||
self.catalog = None
|
||||
|
||||
def _convert_pick(self, p):
|
||||
"""
|
||||
Function converts picks from SeisBench to ObsPy format
|
||||
:param p: SeisBench pick
|
||||
:return: ObsPy pick
|
||||
"""
|
||||
pick = Pick()
|
||||
pick.time = UTCDateTime(p.peak_time.datetime)
|
||||
pick.waveform_id = WaveformStreamID(network_code=p.trace_id.split(".")[0],
|
||||
station_code=p.trace_id.split(".")[1],
|
||||
channel_code=p.trace_id.split(".")[2])
|
||||
if p.phase == 'P':
|
||||
pick.phase_hint = self._config["P_hint"]
|
||||
elif p.phase == 'S':
|
||||
pick.phase_hint = self._config["S_hint"]
|
||||
pick.evaluation_mode = 'automatic'
|
||||
pick.evaluation_status = 'preliminary'
|
||||
return pick
|
||||
|
||||
def _convert_origin(self, origin_sb, list_of_picks_sb):
|
||||
origin = Origin()
|
||||
origin.time = UTCDateTime(pd.to_datetime(origin_sb.time, unit='s').to_pydatetime())
|
||||
origin.latitude = origin_sb.latitude # float
|
||||
origin.longitude = origin_sb.longitude # float
|
||||
origin.depth = origin_sb.depth # float in kilometers (SWIP5 origin version) down the see level
|
||||
origin.depth_type = 'operator assigned'
|
||||
# TODO: make sure that region is not necessary
|
||||
# origin.region = self._config["region"]
|
||||
origin.evaluation_mode = "automatic"
|
||||
origin.evaluation_status = 'preliminary'
|
||||
origin.comments.append(Comment(text=f"Localized by: {self._name_of_algorithm}", force_resource_id=False))
|
||||
origin.quality = OriginQuality(used_phase_count=len(list_of_picks_sb))
|
||||
return origin
|
||||
|
||||
def _convert_event(self, origin_sb, list_of_picks_sb):
|
||||
"""
|
||||
Function convert GaMMa detection to ObsPy Event
|
||||
:param origin_sb:
|
||||
:param list_of_picks_sb:
|
||||
:return:
|
||||
"""
|
||||
event = Event()
|
||||
for p in list_of_picks_sb:
|
||||
pick = self._convert_pick(p)
|
||||
event.picks.append(pick)
|
||||
origin = self._convert_origin(origin_sb, list_of_picks_sb)
|
||||
event.origins.append(origin)
|
||||
return event
|
||||
|
||||
@staticmethod
|
||||
def _append_pick_trace_id(pick, stream):
|
||||
"""
|
||||
Function assigns channel to pick - it is useful for work with SWIP
|
||||
:param pick:
|
||||
:param stream:
|
||||
:return:
|
||||
"""
|
||||
channel = stream[0].stats.channel
|
||||
if pick.phase == "P":
|
||||
pick.trace_id = pick.trace_id + channel[:-1] + "Z"
|
||||
if pick.phase == "S":
|
||||
pick.trace_id = pick.trace_id + channel[:-1] + "E"
|
||||
return pick
|
||||
|
||||
def catalog2obspy(self):
|
||||
"""
|
||||
Function convert GaMMa catalog and SeisBench picks
|
||||
:return: ObsPy Catalog object
|
||||
"""
|
||||
# TODO: make sure that resource id is necessary
|
||||
#cat = Catalog(resource_id=self._config["resource_id"])
|
||||
cat = Catalog()
|
||||
for j, row in self._catalog_df.iterrows():
|
||||
event = self._catalog_df.iloc[j]
|
||||
event_picks = [self._picks[i] for i in
|
||||
self._assignments_df[self._assignments_df["event_idx"] ==
|
||||
event["idx"]]["pick_idx"]]
|
||||
event_obspy = self._convert_event(event, event_picks)
|
||||
cat.append(event_obspy)
|
||||
self.catalog = cat
|
||||
|
||||
def save_catalog_to_file(self, file_path):
|
||||
"""
|
||||
Save ObsPy catalog to a file.
|
||||
|
||||
Args:
|
||||
file_path (str): The file path where the catalog will be saved.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
try:
|
||||
self.catalog.write(file_path, format="QUAKEML")
|
||||
print(f"Catalog saved successfully to {file_path}")
|
||||
except Exception as e:
|
||||
print(f"Error occurred while saving catalog: {e}")
|
@ -1,62 +0,0 @@
|
||||
import os
|
||||
|
||||
import argparse
|
||||
|
||||
from obspy import read_inventory
|
||||
|
||||
def convert_inventory(input_file,
|
||||
output_format,
|
||||
output_dir="."):
|
||||
|
||||
"""
|
||||
Function to read Inventory from provided file and convert it to FDSN Station XML format.
|
||||
The supported input file formats are: INVENTORYXML, RESP, SC3ML, SEED, STATIONTXT, STATIONXML, XSEED
|
||||
|
||||
:type input_file: str
|
||||
:param input_file: File name or path to the input inventory file.
|
||||
:type output_format: str
|
||||
:param output_format: Format of the output inventory file.
|
||||
Supported formats: CSS, KML, SACPZ, SHAPEFILE, STATIONTXT, STATIONXML.
|
||||
:type output_dir: str, optional
|
||||
:param output_dir: Directory to which output files are written.
|
||||
Defaults to current directory.
|
||||
"""
|
||||
inv = read_inventory(input_file)
|
||||
result_filename = os.path.splitext(os.path.basename(input_file))[0] + "." + _get_extension(output_format)
|
||||
inv.write(output_dir + "/" + result_filename, format=output_format)
|
||||
return result_filename
|
||||
|
||||
def _get_extension(output_format):
|
||||
format = output_format.upper()
|
||||
if format == 'STATIONXML':
|
||||
return "xml"
|
||||
elif format == 'STATIONTXT':
|
||||
return "txt"
|
||||
elif format == 'SHAPEFILE':
|
||||
return "shp"
|
||||
else:
|
||||
return format.lower()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Convert provided inventory file"
|
||||
" to another inventory format.")
|
||||
parser.add_argument("input_file", help="Provide inventory file to convert."
|
||||
"The supported input file formats are: INVENTORYXML, RESP, SC3ML, "
|
||||
"SEED, STATIONTXT, STATIONXML, XSEED")
|
||||
parser.add_argument("--output_format",
|
||||
help="Format of the output inventory file. "
|
||||
"Supported formats: CSS, KML, SACPZ, SHAPEFILE, STATIONTXT, STATIONXML.",
|
||||
type=str, default=None, required=True)
|
||||
parser.add_argument("--output_dir",
|
||||
help="Directory to which output files are written. "
|
||||
"Defaults to current directory.",
|
||||
type=str, default=".", required=False)
|
||||
args = parser.parse_args()
|
||||
|
||||
filename = convert_inventory(**vars(args))
|
||||
print('Created file:')
|
||||
print(filename)
|
||||
return
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,98 +0,0 @@
|
||||
from obspy.io.sac import SACTrace
|
||||
|
||||
|
||||
def to_sac_trace(tr,
|
||||
unit_type,
|
||||
remove_response,
|
||||
inv):
|
||||
"""
|
||||
Function converting the specified trace to SAC-specific format
|
||||
|
||||
:type tr: obspy.core.trace.Trace
|
||||
:param tr: Trace to be converted
|
||||
:type unit_type: str
|
||||
:param unit_type: Unit type of the result
|
||||
:type remove_response: bool
|
||||
:param remove_response: Information whether the response was removed, used to determine scale
|
||||
:type inv: obspy.core.inventory.inventory.Inventory
|
||||
:param inv: Inventory read either from SEED file or Station XML
|
||||
:rtype: obspy.core.trace.Trace
|
||||
:return: Converted trace
|
||||
|
||||
"""
|
||||
|
||||
# Assure that tr has fields present in SAC-type trace
|
||||
sac = SACTrace.from_obspy_trace(tr)
|
||||
sac = _prepare_sac_for_writing(sac, remove_response, unit_type, inv, tr.id, tr.stats['starttime'])
|
||||
return sac.to_obspy_trace()
|
||||
|
||||
|
||||
def _prepare_sac_for_writing(sac, remove_response, unit_type, inv, tr_id, tr_starttime):
|
||||
"""
|
||||
Method that adds some additional information to ordinary SACTrace file.
|
||||
It adds location info and information about unit type and scale.
|
||||
|
||||
When the response is removed, it scales down the data to nano units
|
||||
nm/s or so.
|
||||
|
||||
:type sac: obspy.io.sac.SACTrace
|
||||
:param sac: SACTrace object, might be converted out of ordinary trace
|
||||
:type remove_response: bool
|
||||
:param remove_response: Parameter that lets user decide whether the
|
||||
response is going to be removed or not
|
||||
:type unit_type: str
|
||||
:param unit_type: Unit type determined by _get_unit_type
|
||||
:type inv: obspy.core.inventory.inventory.Inventory
|
||||
:param inv: inventory contents
|
||||
:type tr_id: str
|
||||
:param tr_id: Trace's id string
|
||||
:type tr_starttime: UTCDateTime
|
||||
:param tr_starttime: Trace's start time
|
||||
:rtype: obspy.io.sac.SACTrace
|
||||
:return: SACTrace object with added additional information
|
||||
"""
|
||||
# Copy details of station's location
|
||||
|
||||
sac.idep = _get_sac_idep_unit(unit_type)
|
||||
if inv:
|
||||
try:
|
||||
coords = inv.get_coordinates(tr_id, tr_starttime)
|
||||
sensitivity = inv.get_response(tr_id, tr_starttime).instrument_sensitivity.value
|
||||
sac.stla = coords["latitude"]
|
||||
sac.stlo = coords["longitude"]
|
||||
sac.stel = coords["elevation"]
|
||||
sac.user2 = sensitivity
|
||||
|
||||
if remove_response:
|
||||
# Divide by nano multiplier to get a data with removed response
|
||||
# scaled to nano unit (nm/s or so).
|
||||
sac.data = sac.data / _get_nano_multiplier()
|
||||
sac.scale = -12345
|
||||
else:
|
||||
sac.scale = (1 / sensitivity / _get_nano_multiplier())
|
||||
except Exception as err:
|
||||
raise Exception("Cannot read location and sensitivity information: " + str(err))
|
||||
else:
|
||||
sac.scale = -12345
|
||||
return sac
|
||||
|
||||
|
||||
def _get_nano_multiplier():
|
||||
"""
|
||||
Returns a multiplier to obtain nano value from a full value.
|
||||
|
||||
:rtype: float
|
||||
:return: Multiplier value
|
||||
"""
|
||||
return 10**(-9)
|
||||
|
||||
|
||||
def _get_sac_idep_unit(unit_abbrev):
|
||||
if unit_abbrev == "DISP":
|
||||
return "idisp"
|
||||
elif unit_abbrev == "VEL":
|
||||
return "ivel"
|
||||
elif unit_abbrev == "ACC":
|
||||
return "iacc"
|
||||
else:
|
||||
return "iunkn"
|
@ -1,327 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
import warnings
|
||||
|
||||
import obspy
|
||||
import argparse
|
||||
|
||||
import unit
|
||||
import sacutil
|
||||
|
||||
import numpy as np
|
||||
|
||||
from obspy.io.xseed import Parser
|
||||
from obspy.io.xseed.utils import SEEDParserException
|
||||
from obspy.core.util import AttribDict
|
||||
from obspy.core import Stream
|
||||
|
||||
|
||||
def convert_seed(seed_file,
|
||||
inv_file=None,
|
||||
input_unit=None,
|
||||
output_filetype=None,
|
||||
remove_response=False,
|
||||
zero_mean=False,
|
||||
pre_filtering=None,
|
||||
output_unit=None,
|
||||
single_output_file=False,
|
||||
output_dir="."):
|
||||
"""
|
||||
Function to convert provided file to SAC, ASCII or MSEED
|
||||
|
||||
|
||||
:type seed_file: str
|
||||
:param seed_file: File name or path to the seed (seed or msd) file.
|
||||
:type inv_file: str
|
||||
:param inv_file: File name or path to inventory file in any inventory format supported by ObsPy.
|
||||
:type input_unit: str
|
||||
:param input_unit: Unit of the input file: 'ACC', 'DISP' or 'VEL'. Specified only for miniSEED files (full SEED
|
||||
files are always in 'COUNTS'). If the value is not set, no unit ('COUNTS') is assumed.
|
||||
:type output_filetype: str
|
||||
:param output_filetype: Output filetype. Choose either SAC, MSEED, SLIST or INTERNAL_ASCII.
|
||||
When used SLIST, sample values are saved with `%+.10e` formatting.
|
||||
INTERNAL_ASCII is an internal format used for some apps, that uses only one column of values
|
||||
This will be default formatting since ObsPy 1.1.0
|
||||
:type remove_response: bool
|
||||
:param remove_response: Response removal from the waveform
|
||||
Defaults to False.
|
||||
Removal of the instrument's response from the waveform
|
||||
By default it will save waveform without response removal procedure
|
||||
This function uses obspy.core.stream.Stream.remove_response.
|
||||
When set to True, user has to specify parameters zero_mean,
|
||||
pre_filtering and output_unit. Otherwise the script will raise an
|
||||
exception.
|
||||
:type zero_mean: bool, optional
|
||||
:param zero_mean: If true the mean of the data is subtracted
|
||||
For details check the ObsPy's documentation for
|
||||
obspy.core.stream.Stream.remove_response
|
||||
:type pre_filtering: (float, float, float, float), optional
|
||||
:param pre_filtering: Apply a bandpass filter to the data trace before
|
||||
deconvolution.
|
||||
The list or tuple defines the four corner frequencies (f1,f2,f3,f4)
|
||||
of a cosine taper which is one between f2 and f3
|
||||
and tapers to zero for f1 < f < f2 and f3 < f < f4.
|
||||
For details check the ObsPy's documentation for
|
||||
obspy.core.stream.Stream.remove_response
|
||||
:type output_unit: str, optional
|
||||
:param output_unit: Unit of the output waveform.
|
||||
This parameter converts counts to real values during response removal,
|
||||
or, if response_removal is false is just written to the converted file.
|
||||
When used ``auto`` the script will determine the unit automatically
|
||||
with use of second letter of a channel code which determines
|
||||
instrument type.
|
||||
For details see Appendix A to SEED Manual v2.4.
|
||||
|
||||
In case user need to convert all channels to common unit,
|
||||
there can be chosen ``DISP`` for displacement,
|
||||
``VEL`` for velocity and ``ACC`` for acceleration.
|
||||
When this parameter is None and remove_response is set to True
|
||||
script will throw an Exception.
|
||||
:type single_output_file: bool
|
||||
:param single_output_file: if True, a single file with all traces will be created
|
||||
(available only for conversion to MSEED), otherwise, separate files with names in format
|
||||
``network.station.location.channel.starttime_microsecond.output_filetype`` will be created
|
||||
:type output_dir: str, optional
|
||||
:param output_dir: Directory to which output files are written.
|
||||
Defaults to current directory.
|
||||
|
||||
:return: Filenames of created files. Filenames follow pattern:
|
||||
``network.station.location.channel.starttime_microsecond.SAC``
|
||||
|
||||
:raises
|
||||
|
||||
.. note::
|
||||
For more information on parameters used in this function see
|
||||
ObsPy's documentation in ``obspy.core.stream.Stream.remove_response``
|
||||
"""
|
||||
|
||||
st = obspy.read(seed_file)
|
||||
if inv_file:
|
||||
inv = obspy.read_inventory(inv_file)
|
||||
elif remove_response:
|
||||
raise ValueError("Cannot remove response if inventory is not specified")
|
||||
else:
|
||||
inv = None
|
||||
|
||||
if output_unit:
|
||||
if inv:
|
||||
# assuming all the traces have the same unit
|
||||
input_type = unit.determine_instrument_type_from_inventory(inv, st[0].id, st[0].stats.starttime)
|
||||
else:
|
||||
try:
|
||||
# if we don't have the inventory and we have a full SEED file, we can attempt to read unit from it
|
||||
resp = Parser(seed_file)
|
||||
# assuming all the traces have the same unit
|
||||
input_type = unit.determine_instrument_type_from_blockette(resp, st[0].id)
|
||||
except (OSError, SEEDParserException):
|
||||
warnings.warn("The provided file is not a SEED volume - cannot determine unit automatically")
|
||||
|
||||
if output_unit == "auto":
|
||||
output_unit = input_type
|
||||
|
||||
if remove_response and output_unit is None:
|
||||
raise ValueError("You have to provide output_unit parameter"
|
||||
" for response removal procedure.\n"
|
||||
"Available output_unit values are DISP, "
|
||||
"VEL, ACC. Provide one or skip removing "
|
||||
"response by passing "
|
||||
"remove_response=False parameter")
|
||||
|
||||
if remove_response:
|
||||
if pre_filtering is None:
|
||||
tr_sampling_rate = st[0].stats.sampling_rate
|
||||
pre_filt = [0.005, 0.006, 0.9 * 0.5 * tr_sampling_rate, 0.5 * tr_sampling_rate]
|
||||
else:
|
||||
pre_filt = pre_filtering
|
||||
try:
|
||||
_remove_response(st, inv, input_type, output_unit, pre_filt, zero_mean)
|
||||
except (ValueError, SEEDParserException) as exc:
|
||||
raise Exception("There was a problem with removing response from the file: " + str(exc))
|
||||
elif output_unit and input_unit and input_unit != output_unit:
|
||||
_convert_unit(st, input_unit, output_unit)
|
||||
# we are not converting anything, but the input file already had a unit (might happen only with mseed files),
|
||||
# so it should be written to the output file
|
||||
elif input_unit:
|
||||
output_unit = input_unit
|
||||
|
||||
if single_output_file:
|
||||
if output_filetype != "MSEED":
|
||||
raise ValueError("Writing all traces to one file is available only for conversion to MSEED format")
|
||||
return _convert_to_single_mseed(seed_file, st, output_dir)
|
||||
else:
|
||||
return _convert_to_separate_files(st, inv, remove_response, output_unit, output_filetype, output_dir)
|
||||
|
||||
|
||||
# remove response and correct numerical errors (depending on the input and output type)
|
||||
def _remove_response(stream, inv, input_type, output_unit, pre_filt, zero_mean):
|
||||
if input_type == "ACC" and output_unit == "DISP":
|
||||
stream.remove_response(inventory=inv, pre_filt=pre_filt, zero_mean=zero_mean, output="VEL")
|
||||
stream.filter("highpass", freq=1.0)
|
||||
stream.integrate(method="cumtrapz")
|
||||
stream.filter("highpass", freq=0.5)
|
||||
else:
|
||||
stream.remove_response(inventory=inv, pre_filt=pre_filt, zero_mean=zero_mean, output=output_unit)
|
||||
if ((input_type == "ACC" and output_unit == "VEL") or
|
||||
(input_type == "VEL" and (output_unit == "DISP" or output_unit == "VEL"))):
|
||||
stream.filter("highpass", freq=1.0)
|
||||
|
||||
|
||||
# unit conversion - applied when the input data already has response removed and is converted to one of the units
|
||||
def _convert_unit(stream, input_unit, output_unit):
|
||||
if input_unit == "DISP":
|
||||
if output_unit == "ACC": # DIFF x2
|
||||
stream.differentiate(method="gradient")
|
||||
stream.differentiate(method="gradient")
|
||||
elif output_unit == "VEL": # DIFF
|
||||
stream.differentiate(method="gradient")
|
||||
elif input_unit == "VEL":
|
||||
if output_unit == "ACC": # DIFF
|
||||
stream.differentiate(method="gradient")
|
||||
elif output_unit == "DISP": # INTEG + FILTER
|
||||
stream.integrate(method="cumtrapz")
|
||||
stream.filter("highpass", freq=1.0)
|
||||
elif input_unit == "ACC":
|
||||
if output_unit == "VEL": # INTEG + FILTER
|
||||
stream.integrate(method="cumtrapz")
|
||||
stream.filter("highpass", freq=1.0)
|
||||
elif output_unit == "DISP": # (INTEG + FILTER) x2
|
||||
stream.integrate(method="cumtrapz")
|
||||
stream.filter("highpass", freq=1.0)
|
||||
stream.integrate(method="cumtrapz")
|
||||
stream.filter("highpass", freq=0.5)
|
||||
else:
|
||||
raise TypeError("Cannot convert from ", input_unit)
|
||||
|
||||
|
||||
def _convert_to_single_mseed(seed_filename, stream, output_dir):
|
||||
result_filename = os.path.splitext(os.path.basename(seed_filename))[0] + ".msd"
|
||||
stream.write(output_dir + "/" + result_filename, format="MSEED")
|
||||
return [result_filename]
|
||||
|
||||
|
||||
def _convert_to_separate_files(stream, inv, remove_response, output_unit, output_filetype, output_dir):
|
||||
output_stream = Stream()
|
||||
output_file_extension = output_filetype
|
||||
|
||||
for tr in stream:
|
||||
if output_filetype == "SAC":
|
||||
output_file_extension = "sac"
|
||||
tr = sacutil.to_sac_trace(tr, output_unit, remove_response, inv)
|
||||
|
||||
elif output_filetype in ["SLIST", "TSPAIR", "SH_ASC"]:
|
||||
output_file_extension = output_filetype.lower() + ".ascii"
|
||||
slist_unit = unit.translate_instrument_type_to_unit(output_unit) if output_unit else "COUNTS"
|
||||
tr.stats.ascii = AttribDict({"unit": slist_unit})
|
||||
|
||||
elif output_filetype == "MSEED":
|
||||
output_file_extension = "msd"
|
||||
|
||||
elif output_filetype == "INTERNAL_ASCII":
|
||||
output_file_extension = "ascii"
|
||||
|
||||
output_stream.append(tr)
|
||||
|
||||
return _write_separate_output_files(output_stream, output_filetype, output_file_extension, output_dir)
|
||||
|
||||
|
||||
def _write_separate_output_files(stream, output_filetype, file_extension, output_dir):
|
||||
"""
|
||||
Writes all Trace objects present in Stream to separate files. Filetype
|
||||
is set according to User's will.
|
||||
|
||||
:type stream: obspy.core.stream.Stream
|
||||
:param stream: Obspy stream with traces to save separately.
|
||||
:type output_filetype: str
|
||||
:param output_filetype: Contains filetype to save. Currently supported
|
||||
``SAC``, ``SLIST`` and ``MSEED``.
|
||||
"""
|
||||
result_filenames = list()
|
||||
for tr in stream:
|
||||
result_filename = ".".join([tr.id,
|
||||
str(tr.stats.starttime.microsecond),
|
||||
file_extension])
|
||||
result_filepath = output_dir + "/" + result_filename
|
||||
if output_filetype == "INTERNAL_ASCII":
|
||||
_write_ascii_one_column(tr, result_filepath)
|
||||
else:
|
||||
tr.write(result_filepath, format=output_filetype)
|
||||
result_filenames.append(result_filename)
|
||||
return result_filenames
|
||||
|
||||
|
||||
def _write_ascii_one_column(trace, filename):
|
||||
"""
|
||||
Writes trace data into an ASCII file in one-column format (i.e. no header, single column of values).
|
||||
"""
|
||||
with open(filename, 'wb') as fh:
|
||||
data = trace.data.reshape((-1, 1))
|
||||
dtype = data.dtype.name
|
||||
fmt = '%f'
|
||||
if dtype.startswith('int'):
|
||||
fmt = '%d'
|
||||
elif dtype.startswith('float64'):
|
||||
fmt = '%+.16e'
|
||||
np.savetxt(fh, data, delimiter=b'\t', fmt=fmt.encode('ascii', 'strict'))
|
||||
|
||||
|
||||
def main(argv):
|
||||
def str2bool(v):
|
||||
if v.lower() in ("True", "TRUE", "yes", "true", "t", "y", "1"):
|
||||
return True
|
||||
elif v.lower() in ("False", "FALSE", "no", "false", "f", "n", "0"):
|
||||
return False
|
||||
else:
|
||||
raise argparse.ArgumentTypeError("Boolean value expected.")
|
||||
|
||||
parser = argparse.ArgumentParser(description="Convert provided file"
|
||||
" to SAC or SLIST (ASCII).")
|
||||
|
||||
parser.add_argument("seed_file", help="Provide SEED or mSEED file to convert")
|
||||
parser.add_argument("--inv_file", help="Provide inventory file")
|
||||
parser.add_argument("--input_unit",
|
||||
help="Provide input unit. "
|
||||
"ACC, VEL or DISP are available.",
|
||||
type=str, default=None, required=False)
|
||||
parser.add_argument("--output_filetype",
|
||||
help="Provide output filetype. "
|
||||
"MSEED, SAC, SLIST and INTERNAL_ASCII are available.",
|
||||
type=str, default=None, required=True)
|
||||
parser.add_argument("--remove_response",
|
||||
help="Remove instrument's response from the waveform",
|
||||
type=str2bool, default=False)
|
||||
parser.add_argument("--zero_mean",
|
||||
help="If true the mean of the data is subtracted",
|
||||
type=str2bool, default=False, required=False)
|
||||
parser.add_argument("--pre_filtering",
|
||||
help="Apply a bandpass filter to the data trace "
|
||||
"before deconvolution",
|
||||
type=float, nargs="+", default=None,
|
||||
required=False)
|
||||
parser.add_argument("--output_unit",
|
||||
help="Unit to which waveform should be converted "
|
||||
"during response removal. When set to auto, "
|
||||
"the unit will be automatically determined with "
|
||||
"use of the second letter of channel code which "
|
||||
"determines the instrument type."
|
||||
"For details see Appendix A, SEED Manual v2.4.",
|
||||
type=str, default=None, required=False)
|
||||
parser.add_argument("--single_output_file",
|
||||
help="Flag deciding whether all the traces will be written to "
|
||||
"a single file, if set to False, each trace will be "
|
||||
"written to a separate file. True is available only "
|
||||
"for conversion to MSEED",
|
||||
type=str2bool, default=False, required=False)
|
||||
parser.add_argument("--output_dir",
|
||||
help="Directory to which output files are written. "
|
||||
"Defaults to current directory.",
|
||||
type=str, default=".", required=False)
|
||||
args = parser.parse_args()
|
||||
|
||||
filenames = convert_seed(**vars(args))
|
||||
print('Created files:')
|
||||
print(', '.join(filenames))
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
@ -1,95 +0,0 @@
|
||||
def determine_instrument_type_from_blockette(parser, channel_id):
|
||||
"""
|
||||
Determines type of instrument used to record a channel with provided
|
||||
channel_id.
|
||||
|
||||
:type parser: obspy.io.xseed.parser.Parser
|
||||
:param parser: Parser object parsed from Full SEED or dataless or
|
||||
StationXML.
|
||||
:type channel_id: str
|
||||
:param channel_id: Channel_id object generated by obspy.trace.Trace.id
|
||||
:rtype: str
|
||||
:return: Returns str determining the type of instrument
|
||||
"""
|
||||
return translate_unit_to_instrument_type(determine_unit_from_blockette(parser, channel_id))
|
||||
|
||||
|
||||
def determine_unit_from_blockette(parser, channel_id):
|
||||
"""
|
||||
Determines the unit used to record a channel with provided
|
||||
channel_id.
|
||||
|
||||
:type parser: obspy.io.xseed.parser.Parser
|
||||
:param parser: Parser object parsed from Full SEED or dataless or
|
||||
StationXML.
|
||||
:type channel_id: str
|
||||
:param channel_id: Channel_id object generated by obspy.trace.Trace.id
|
||||
:rtype: str
|
||||
:return: Returns str containing a real unit name that can be passed to
|
||||
translate_unit_to_instrument_type method
|
||||
to obtain a str compatible with response removal procedure
|
||||
"""
|
||||
for blkt in parser._select(channel_id):
|
||||
if not blkt.id == 52:
|
||||
continue
|
||||
|
||||
for bl in parser.blockettes[34]:
|
||||
if bl.unit_lookup_code == blkt.units_of_signal_response:
|
||||
return bl.unit_name
|
||||
|
||||
|
||||
def determine_instrument_type_from_inventory(inv, channel_id, time):
|
||||
"""
|
||||
Determines type of instrument used to record a channel with provided channel_id at the provided time.
|
||||
|
||||
:type inv: obspy.core.inventory.inventory.Inventory
|
||||
:param inv: ObsPy Inventory object parsed from a file
|
||||
:type channel_id: str
|
||||
:param channel_id: Channel_id object generated by obspy.trace.Trace.id
|
||||
:type time: obspy.core.utcdatetime.UTCDateTime
|
||||
:param time: time for which the unit should be determined in the inventory (e.g. start time of a trace)
|
||||
:rtype: str
|
||||
:return: Returns str determining the type of instrument
|
||||
"""
|
||||
return translate_unit_to_instrument_type(determine_unit_from_inventory(inv, channel_id, time))
|
||||
|
||||
|
||||
def determine_unit_from_inventory(inv, channel_id, time):
|
||||
"""
|
||||
Determines unit used to record a channel with provided channel_id at the provided time.
|
||||
|
||||
:type inv: obspy.core.inventory.inventory.Inventory
|
||||
:param inv: ObsPy Inventory object parsed from a file
|
||||
:type channel_id: str
|
||||
:param channel_id: Channel_id object generated by obspy.trace.Trace.id
|
||||
:type time: obspy.core.utcdatetime.UTCDateTime
|
||||
:param time: time for which the unit should be determined in the inventory (e.g. start time of a trace)
|
||||
:rtype: str
|
||||
:return: Returns str containing a real unit name that can be passed to
|
||||
translate_unit_to_instrument_type method
|
||||
to obtain a str compatible with response removal procedure
|
||||
"""
|
||||
resp = inv.get_response(channel_id, time)
|
||||
return resp.instrument_sensitivity.input_units
|
||||
|
||||
|
||||
def translate_unit_to_instrument_type(unit_name):
|
||||
if unit_name == "M":
|
||||
return "DISP"
|
||||
elif unit_name == "M/S":
|
||||
return "VEL"
|
||||
elif unit_name == "M/S**2":
|
||||
return "ACC"
|
||||
else:
|
||||
raise TypeError("Unknown unit code ", unit_name)
|
||||
|
||||
|
||||
def translate_instrument_type_to_unit(unit_type):
|
||||
if unit_type == "DISP":
|
||||
return "M"
|
||||
elif unit_type == "VEL":
|
||||
return "M/S"
|
||||
elif unit_type == "ACC":
|
||||
return "M/S**2"
|
||||
else:
|
||||
raise TypeError("Unknown unit code ", unit_type)
|
Loading…
Reference in New Issue
Block a user