From 4526c6983162bb255de8c2a294741eb0a0772eb1 Mon Sep 17 00:00:00 2001 From: Fabio Silva Date: Tue, 3 Dec 2024 23:44:42 -0800 Subject: [PATCH] Updated BBP tools to handle both srf and mrf files. --- bbp/comps/fault_utils.py | 16 +++---- bbp/comps/plot_map.py | 13 +++--- bbp/comps/plot_map_gof.py | 19 ++++---- bbp/comps/plot_srf.py | 6 +-- bbp/comps/plot_utils.py | 97 ++++++++++++++++++++------------------- 5 files changed, 77 insertions(+), 74 deletions(-) diff --git a/bbp/comps/fault_utils.py b/bbp/comps/fault_utils.py index 94ae188a..935cb9e1 100644 --- a/bbp/comps/fault_utils.py +++ b/bbp/comps/fault_utils.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ BSD 3-Clause License -Copyright (c) 2021, University of Southern California +Copyright (c) 2024, University of Southern California All rights reserved. Redistribution and use in source and binary forms, with or without @@ -69,9 +69,9 @@ def get_magnitude(velfile, srffile, suffix="tmp"): bband_utils.runprog(cmd, False) return magnitude -def get_hypocenter(srffile, suffix="tmp"): +def get_hypocenter(input_file, suffix="tmp"): """ - Looks up the hypocenter of an event in a srffile + Looks up the hypocenter of an event in a SRF/MRF input_file """ hypfile = os.path.join(tempfile.gettempdir(), "%s_%s" % @@ -79,7 +79,7 @@ def get_hypocenter(srffile, suffix="tmp"): install = InstallCfg.getInstance() cmd = ("%s < %s > %s" % (os.path.join(install.A_GP_BIN_DIR, "srf_gethypo"), - srffile, hypfile)) + input_file, hypfile)) bband_utils.runprog(cmd) srf_hypo_fp = open(hypfile, 'r') srf_hypo_data = srf_hypo_fp.readline() @@ -126,12 +126,12 @@ def calculate_hypo_depth(srcfile): def calculate_epicenter(input_file): """ This function returns the epicenter of an event using either a SRC - file or a SRF file to look for the hypocenter location. It uses + file or a SRF/MRF file to look for the hypocenter location. It uses Rob Graves' xy2ll utility to convert the coordinates to lat/lon. """ # If we have a SRF file, we already have a function that does this - if input_file.endswith(".srf"): - # Get information from srf file + if input_file.endswith(".srf") or input_file.endswith(".mrf"): + # Get information from srf/mrf file hypo_lon, hypo_lat, _ = get_hypocenter(input_file) return hypo_lon, hypo_lat diff --git a/bbp/comps/plot_map.py b/bbp/comps/plot_map.py index b8e03934..368d4154 100755 --- a/bbp/comps/plot_map.py +++ b/bbp/comps/plot_map.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ BSD 3-Clause License -Copyright (c) 2021, University of Southern California +Copyright (c) 2024, University of Southern California All rights reserved. Redistribution and use in source and binary forms, with or without @@ -71,8 +71,9 @@ def run(self): if (self.input_file is None or self.input_file == "" or (not self.input_file.endswith(".srf") and - not self.input_file.endswith(".src"))): - # We need a SRC or SRF file to get the fault geometry + (not self.input_file.endswith(".mrf") and + not self.input_file.endswith(".src")))): + # We need a SRC/SRF/MRF file to get the fault geometry return install = InstallCfg.getInstance() @@ -99,14 +100,14 @@ def run(self): "%d.plot_map.log" % (self.sim_id)) trace_file = "%s.trace" % (a_input_file) simple_station_file = "%s.simple" % (a_station_file) - if self.input_file.endswith(".srf"): + if self.input_file.endswith(".srf") or self.input_file.endswith(".mrf"): self.trace = plot_utils.write_fault_trace(a_input_file, trace_file) else: self.trace = plot_utils.write_simple_trace(a_input_file, trace_file) plot_utils.write_simple_stations(a_station_file, simple_station_file) map_prefix = os.path.join(a_outdir, "station_map") - # Get hypo_lon, hypo_lat from src/srf file + # Get hypo_lon, hypo_lat from src/srf/mrf file hypo_coord = {} hypo_lon, hypo_lat = fault_utils.calculate_epicenter(a_input_file) hypo_coord['lat'] = hypo_lat diff --git a/bbp/comps/plot_map_gof.py b/bbp/comps/plot_map_gof.py index 34c95a13..c8ec61cd 100644 --- a/bbp/comps/plot_map_gof.py +++ b/bbp/comps/plot_map_gof.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ BSD 3-Clause License -Copyright (c) 2021, University of Southern California +Copyright (c) 2024, University of Southern California All rights reserved. Redistribution and use in source and binary forms, with or without @@ -130,16 +130,17 @@ def read_resid(resid_file, period, summary_output): # Return the data we found return sta_x_data, sta_y_data, sta_resid_data -def plot_map_gof(r_srcfile, r_stations, resid_file, comp_label, sim_id): +def plot_map_gof(source_file, r_stations, resid_file, comp_label, sim_id): """ Reads data from resid_file and plots a map gof plot with a number of periods """ # Make sure we have a src or srf file - if (r_srcfile is None or r_srcfile == "" or - (not r_srcfile.endswith(".srf") and - not r_srcfile.endswith(".src"))): - # We need a SRC or SRF file to get the fault geometry + if (source_file is None or source_file == "" or + (not source_file.endswith(".srf") and + (not source_file.endswith(".mrf")) and + not source_file.endswith(".src"))): + # We need a SRC/SRF/MRF file to get the fault geometry return # Get directory names @@ -147,7 +148,7 @@ def plot_map_gof(r_srcfile, r_stations, resid_file, comp_label, sim_id): a_indir = os.path.join(install.A_IN_DATA_DIR, str(sim_id)) a_outdir = os.path.join(install.A_OUT_DATA_DIR, str(sim_id)) - a_input_file = os.path.join(a_indir, r_srcfile) + a_input_file = os.path.join(a_indir, source_file) a_station_file = os.path.join(a_indir, r_stations) # Define boundaries to plot using the stations in the station file @@ -157,7 +158,7 @@ def plot_map_gof(r_srcfile, r_stations, resid_file, comp_label, sim_id): trace_file = "%s.trace" % (a_input_file) simple_station_file = "%s.simple" % (a_station_file) - if r_srcfile.endswith(".srf"): + if source_file.endswith(".srf") or source_file.endswith(".mrf"): plot_utils.write_fault_trace(a_input_file, trace_file) else: plot_utils.write_simple_trace(a_input_file, trace_file) diff --git a/bbp/comps/plot_srf.py b/bbp/comps/plot_srf.py index 5f5069e0..38507010 100755 --- a/bbp/comps/plot_srf.py +++ b/bbp/comps/plot_srf.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ BSD 3-Clause License -Copyright (c) 2021, University of Southern California +Copyright (c) 2024, University of Southern California All rights reserved. Redistribution and use in source and binary forms, with or without @@ -537,7 +537,7 @@ def run(r_srffile, sim_id=0): # Get number of segments num_segments = get_srf_num_segments(r_srffile) - srfbase = r_srffile[0:r_srffile.find(".srf")] + srfbase = os.path.splitext(r_srffile)[0] # Write slip and tinit files for each segment for seg in range(num_segments): diff --git a/bbp/comps/plot_utils.py b/bbp/comps/plot_utils.py index 0e26cf2b..d0c1d665 100755 --- a/bbp/comps/plot_utils.py +++ b/bbp/comps/plot_utils.py @@ -2,7 +2,7 @@ """ BSD 3-Clause License -Copyright (c) 2023, University of Southern California +Copyright (c) 2024, University of Southern California All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,77 +50,77 @@ BUFFER_LATITUDE = 0.25 BUFFER_LONGITUDE = 0.25 -def get_srf_num_segments(srf_file): +def get_srf_num_segments(input_file): """ - Returns number of segments in a SRF file + Returns number of segments in a SRF/MRF file """ - srf_segments = None + num_segments = None - srf = open(srf_file, 'r') + srf = open(input_file, 'r') for line in srf: if line.startswith("PLANE"): # Found the plane line, read number of segments - srf_segments = int(line.split()[1]) + num_segments = int(line.split()[1]) break srf.close() - if srf_segments is None: + if num_segments is None: print("ERROR: Could not read number of segments from " - "SRF file: %s" % (src_file)) + "input file: %s" % (input_file)) sys.exit(1) # Return number of segments - return srf_segments + return num_segments -def get_srf_params(srf_file, segment=0): +def get_srf_params(input_file, segment=0): """ - Reads fault_len, width, dlen, dwid, and azimuth from the srf_file + Reads fault_len, width, dlen, dwid, and azimuth from the input_file Segment allows users to specify segment of interest (0-based) """ - srf_params1 = None - srf_params2 = None - srf = open(srf_file, 'r') + param_line1 = None + param_line2 = None + srf = open(input_file, 'r') for line in srf: if line.startswith("PLANE"): # Found the plane line, read number of segments - srf_segments = int(line.split()[1]) - if srf_segments < segment + 1: + num_segments = int(line.split()[1]) + if num_segments < segment + 1: print("ERROR: Requested parameters from segment %d, " - " SRF file only has %d segment(s)!" % - (segment + 1, srf_segments)) + " SRF/MRF file only has %d segment(s)!" % + (segment + 1, num_segments)) sys.exit(1) for _ in range(segment): # Skip lines to get to the segment we want _ = next(srf) _ = next(srf) # The next line should have what we need - srf_params1 = next(srf) - srf_params2 = next(srf) + param_line1 = next(srf) + param_line2 = next(srf) break srf.close() - if srf_params1 is None or srf_params2 is None: - print("ERROR: Cannot determine parameters from SRF file %s" % - (srf_file)) + if param_line1 is None or param_line2 is None: + print("ERROR: Cannot determine parameters from SRF/MRF file %s" % + (input_file)) sys.exit(1) - srf_params1 = srf_params1.strip() - srf_params1 = srf_params1.split() - srf_params2 = srf_params2.strip() - srf_params2 = srf_params2.split() + param_line1 = param_line1.strip() + param_line1 = param_line1.split() + param_line2 = param_line2.strip() + param_line2 = param_line2.split() # Make sure we have the correct number of pieces - if len(srf_params1) != 6 or len(srf_params2) != 5: - print("ERROR: Cannot parse params from SRF file %s" % - (srf_file)) + if len(param_line1) != 6 or len(param_line2) != 5: + print("ERROR: Cannot parse params from SRF/MRF file %s" % + (input_file)) sys.exit(1) # Pick the parameters that we need params = {} - params["lon"] = float(srf_params1[0]) - params["lat"] = float(srf_params1[1]) - params["dim_len"] = int(srf_params1[2]) - params["dim_wid"] = int(srf_params1[3]) - params["fault_len"] = float(srf_params1[4]) - params["fault_width"] = float(srf_params1[5]) - params["azimuth"] = int(float(srf_params2[0])) + params["lon"] = float(param_line1[0]) + params["lat"] = float(param_line1[1]) + params["dim_len"] = int(param_line1[2]) + params["dim_wid"] = int(param_line1[3]) + params["fault_len"] = float(param_line1[4]) + params["fault_width"] = float(param_line1[5]) + params["azimuth"] = int(float(param_line2[0])) return params @@ -138,7 +138,7 @@ def write_simple_stations(station_file, out_file): def get_srf_info(srf_file): """ - This function reads a SRF file and returns version, + This function reads a SRF/MRF file and returns version, number of segments, and a list with the nstk values for each segment """ @@ -146,14 +146,15 @@ def get_srf_info(srf_file): num_segments = None nstk = [] - # Read SRF file + # Read SRF/MRF file input_file = open(srf_file, 'r') for line in input_file: line = line.strip() # Skip blank lines if not line: continue - version = int(float(line)) + # First line should contain version number + version = int(float(line.split()[0])) break # Read number of segments @@ -170,7 +171,7 @@ def get_srf_info(srf_file): break if num_segments is None or version is None: - bband_utils.ParameterError("Cannot parse SRF file!") + bband_utils.ParameterError("Cannot parse SRF/MRF file!") # Read nstk for each segment for line in input_file: @@ -188,13 +189,13 @@ def get_srf_info(srf_file): input_file.close() if len(nstk) != num_segments: - bband_utils.ParameterError("Cannot read nstk from SRF file!") + bband_utils.ParameterError("Cannot read nstk from SRF/MRF file!") return version, num_segments, nstk def read_srf_trace(srf_file, num_segment, nstk): """ - This function reads an SRF file and returns the + This function reads an SRF/MRF file and returns the top layer trace for the segment specified """ install = InstallCfg.getInstance() @@ -230,12 +231,12 @@ def read_srf_trace(srf_file, num_segment, nstk): def write_fault_trace(srf_file, out_file): """ - This function reads the srf file and outputs a trace file + This function reads the srf/mrf file and outputs a trace file """ all_points = [] - # Figure out SRF file version - version, num_segments , nstk = get_srf_info(srf_file) + # Figure out SRF/MRF file version + version, num_segments, nstk = get_srf_info(srf_file) # Reads the points for each segment for segment in range(0, num_segments): @@ -413,8 +414,8 @@ def set_boundaries_from_stations(station_file, a_input_file): if a_input_file.endswith(".src"): # Read fault information from SRC file lat1, lon1, _, _, lat2, lon2 = calculate_fault_edges_from_src(a_input_file) - elif a_input_file.endswith(".srf"): - # Read fault information from SRF file + elif a_input_file.endswith(".srf") or a_input_file.endswith(".mrf"): + # Read fault information from SRF/MRF file lat1, lon1, lat2, lon2 = calculate_fault_edges_from_srf(a_input_file) else: bband_utils.ParameterError("Cannot determine input_file format!")