def calculate_fault_edges(a_src_file): """ Calculates the edges of the fault plane """ # Read data from SRC file cfg_dict = bband_utils.parse_properties(a_src_file) if not "fault_length" in cfg_dict: raise bband_utils.ParameterError("SRC file missing fault_length!") if not "strike" in cfg_dict: raise bband_utils.ParameterError("SRC file missing strike!") if not "lat_top_center" in cfg_dict: raise bband_utils.ParameterError("SRC file missing lat_top_center!") if not "lon_top_center" in cfg_dict: raise bband_utils.ParameterError("SRC file missing lon_top_center!") fault_length = float(cfg_dict["fault_length"]) strike = float(cfg_dict["strike"]) lat_top_center = float(cfg_dict["lat_top_center"]) lon_top_center = float(cfg_dict["lon_top_center"]) dist = fault_length / 2 # Calculate 1st edge lat1, lon1 = calculate_fault_edge(lat_top_center, lon_top_center, dist, strike) # Reverse direction if strike >= 180: strike = strike - 180 else: strike = strike + 180 # Calculate 2nd edge lat2, lon2 = calculate_fault_edge(lat_top_center, lon_top_center, dist, strike) return lat1, lon1, lat_top_center, lon_top_center, lat2, lon2
def calculate_hypo_depth(srcfile): """ Calculates the hypocenter depth using the SRC file parameters """ cfgdict = bband_utils.parse_properties(srcfile) # Look for the needed keys in the SRC file try: depth_to_top = cfgdict["depth_to_top"] except KeyError: bband_utils.ParameterError("SRC file missing DEPTH_TO_TOP parameter!") depth_to_top = float(depth_to_top) try: dip = cfgdict["dip"] except KeyError: bband_utils.ParameterError("SRC file missing DIP parameter!") dip = float(dip) try: hypo_down_dip = cfgdict["hypo_down_dip"] except KeyError: bband_utils.ParameterError("SRC file missing HYPO_DOWN_DIP parameter!") hypo_down_dip = float(hypo_down_dip) # Now, calculate the hypocenter depth hypo_depth = depth_to_top + hypo_down_dip * math.sin(math.radians(dip)) # Done return hypo_depth
def generate_src_files(numsim, source_file, srcdir, prefix, new_seed=None): """ Generates num_sim source files in the srcdir using different random seeds """ src_props = bband_utils.parse_properties(source_file) # Delete "seed" from the property set if "seed" in src_props: # Keep track of SRC file seed value seed = int(src_props["seed"]) src_props.pop("seed") # But use new_seed if provided by the user if new_seed is not None: seed = new_seed else: if new_seed is None: raise bband_utils.ParameterError("Please specify a seed for" " this simulation!") seed = new_seed # Create common list of keys for all files output = "" for key in src_props: output = output + "%s = %s\n" % (key.upper(), src_props[key]) for sim in range(0, numsim): srcfile = os.path.join(srcdir, "%s-%04d.src" % (prefix, sim)) outfile = open(srcfile, 'w') outfile.write(output) outfile.write("SEED = %d\n" % (seed)) outfile.close()
def __init__(self, i_r_stations, i_r_srcfile=None, i_a_obsdir=None, i_obs_format=None, i_obs_corr=None, i_comparison_label=None, cutoff=None, sim_id=0): """ Initializes class variables """ self.sim_id = sim_id self.r_srcfile = i_r_srcfile self.r_stations = i_r_stations self.comp_label = i_comparison_label self.max_cutoff = cutoff self.a_obsdir = i_a_obsdir self.obs_format = i_obs_format self.obs_corrections = i_obs_corr self.src_keys = None # Make observed seismograms are in a format we can handle if i_obs_format is not None and i_obs_format not in SUPPORTED_OBS_FORMATS: raise bband_utils.ParameterError("Format %s for " % (self.obs_format) + "observed seismograms " "not supported")
def find_empirical_file(self): """ This function finds the correct empirical file to use based on a file with magnitude ranges """ mag = round(self.config.CFGDICT['magnitude'], 2) emp_amp_file = None infile = open(self.empirical_ranges, 'r') for line in infile: line = line.strip() if line.startswith("#"): # Skip comments continue pieces = line.split() m_min = float(pieces[0]) m_max = float(pieces[1]) # Check if event magnitude is within range if mag >= m_min and mag <= m_max: # Found the file we need emp_amp_file = pieces[2] break infile.close() if emp_amp_file is None: raise bband_utils.ParameterError("Cannot find empirical_amp file " "for event of magnitude %f" % (mag)) return emp_amp_file
def create_station_list(self): """ This function creates the CSM station list """ # Check if Simula can handle our station list if self.num_stations > self.config.SIMULA_MAX_STATIONS: raise bband_utils.ParameterError("Too many stations in " "the station list: %d. " % (self.num_stations) + "Maximum limit is %d." % (self.config.SIMULA_MAX_STATIONS)) csm_stations = os.path.join(self.csm_dir, self.config.csm_stations) outfile = open(csm_stations, 'w') outfile.write("%14.4f %9.4f\n" % (self.config.cfgparams["hypolat"], self.config.cfgparams["hypolon"])) outfile.write("%5i\n" % (len(self.stat_list.site_list))) for station in self.stat_list.getStationList(): outfile.write("%4s %12.5f %12.5f %20s\n" % (station.scode, station.lat, station.lon, "CSMStation.txt")) outfile.close()
def gp_subset(in_file1, in_format1, in_file2, outfile): """ Takes two input stat files in a given format and outputs an intersection file in GP format """ #Get a station list from in_file1 if in_format1 == 'GP' or in_format1 == 'UCSB': stat_list = StationList(in_file1).getStationList() stat_names = [stat.scode for stat in stat_list] elif in_format1 == 'SDSU': stat_file_fp = open(in_file1, 'r') data = stat_file_fp.readlines() stat_file_fp.close() for i in range(0, len(data)): pieces = data[i].split() if len(pieces) > 1: if pieces[1] == 'X': break stat_names = [] for j in range(i + 1, len(data)): pieces = data[j].split() stat_names.append(pieces[2]) else: raise bband_utils.ParameterError("Format %s is not supported." % (in_format1)) # Use the station list to subset in_file2 intersect_list = [] stat2_list = StationList(in_file2).getStationList() for stat2 in stat2_list: for stat1 in stat_names: if stat2.scode == stat1: intersect_list.append(stat2) StationList.build(intersect_list, outfile)
def write_simple_trace(a_src_file, out_file): """ This function reads the SRC file and calculates the fault trace """ points = [] # Read data from SRC file cfg_dict = bband_utils.parse_properties(a_src_file) if not "fault_length" in cfg_dict: raise bband_utils.ParameterError("SRC file missing fault_length!") if not "strike" in cfg_dict: raise bband_utils.ParameterError("SRC file missing strike!") if not "lat_top_center" in cfg_dict: raise bband_utils.ParameterError("SRC file missing lat_top_center!") if not "lon_top_center" in cfg_dict: raise bband_utils.ParameterError("SRC file missing lon_top_center!") fault_length = float(cfg_dict["fault_length"]) strike = float(cfg_dict["strike"]) lat_top_center = float(cfg_dict["lat_top_center"]) lon_top_center = float(cfg_dict["lon_top_center"]) dist = fault_length / 2 # Calculate 1st edge lat1, lon1 = calculate_fault_edge(lat_top_center, lon_top_center, dist, strike) # Reverse direction if strike >= 180: strike = strike - 180 else: strike = strike + 180 # Calculate 2nd edge lat2, lon2 = calculate_fault_edge(lat_top_center, lon_top_center, dist, strike) points.append([lon1, lat1]) points.append([lon_top_center, lat_top_center]) points.append([lon2, lat2]) # Now, open output file, and write the data trace_file = open(out_file, 'w') for point in points: trace_file.write("%f %f\n" % (point[0], point[1])) trace_file.flush() trace_file.close() # Save trace return points
def __init__(self, i_r_stations, i_format, i_mag, i_comparison_label, i_gmpe_group_name, sim_id=0): self.sim_id = sim_id self.r_stations = i_r_stations self.format = i_format self.mag = i_mag self.comp_label = i_comparison_label self.gmpe_group_name = i_gmpe_group_name # Make sure gmpes are in the right format if i_format != "gmpe": raise bband_utils.ParameterError("Format %s for " % (self.format) + "gmpe results " "not supported")
def write_fault_trace(srf_file, out_file): """ This function reads the srf file and outputs a trace file """ points = [] line = 0 shallowest = 100.0 # Figure out SRF file version srf_data = open(srf_file, 'r') for line in srf_data: line = line.strip() # Skip blank lines if not line: continue line = int(float(line)) break if line == 1: tokens = 8 elif line == 2: tokens = 10 else: bband_utils.ParameterError("Cannot determine SRF file version!") for line in srf_data: pieces = line.split() if len(pieces) == tokens: depth = float(pieces[2]) if depth == shallowest: points.append([float(pieces[0]), float(pieces[1])]) elif depth < shallowest: shallowest = depth del points[:] points.append([float(pieces[0]), float(pieces[1])]) # Done reading, close file srf_data.close() # Now, open output file, and write the data trace_file = open(out_file, 'w') for point in points: trace_file.write("%f %f\n" % (point[0], point[1])) trace_file.flush() trace_file.close() # Return trace return points
def parse_src_file(a_srcfile): """ Function parses the SRC file and checks for needed keys. It returns a dictionary containing the keys found in the src file. """ src_keys = bband_utils.parse_properties(a_srcfile) required_keys = ["magnitude", "fault_length", "fault_width", "dlen", "dwid", "depth_to_top", "strike", "rake", "dip", "lat_top_center", "lon_top_center"] for key in required_keys: if key not in src_keys: raise bband_utils.ParameterError("key %s missing in src file" % (key)) # Convert keys to floats for key in src_keys: src_keys[key] = float(src_keys[key]) return src_keys
def __init__(self, i_r_stations, i_a_obsdir, i_obs_format, i_obs_corr, sim_id=0): """ Initialize basic parameters for the ObsSeismograms class """ self.sim_id = sim_id self.r_stations = i_r_stations self.a_obsdir = i_a_obsdir self.obs_format = i_obs_format self.obs_corrections = i_obs_corr # Make observed seismograms are in a format we can handle if i_obs_format not in SUPPORTED_OBS_FORMATS: raise bband_utils.ParameterError("Format %s for " % (self.obs_format) + "observed seismograms " "not supported")
def plot(self, plottitle, gof_fileroot, indir, outdir, cutoff=0, min_period=0.01, mode=None, colorset=None): """ Creates the GOF plot """ if mode == "rd50-single": self.plot_single_component_gof(plottitle, gof_fileroot, indir, outdir, cutoff=cutoff, min_period=min_period, colorset=colorset) elif mode == "rd50" or mode == "rd100": self.plot_three_component_gof(plottitle, gof_fileroot, indir, outdir, cutoff=cutoff, min_period=min_period, mode=mode, colorset=colorset) else: raise bband_utils.ParameterError("plot mode %s unsupported" % (mode))
def generate_src_files(numsim, source_file, srcdir, prefix, hypo_rand): """ Generates num_sim source files in the srcdir using different random seeds """ src_props = bband_utils.parse_properties(source_file) # Delete "seed" from the property set if "seed" in src_props: src_props.pop("seed") # Get FAULT_LENGTH and FAULT_WIDTH from the SRC file try: flen = float(src_props["fault_length"]) fwid = float(src_props["fault_width"]) except KeyError: raise bband_utils.ParameterError("Cannot read fault_length/fault_width" " parameters from SRC file!") if hypo_rand: # Delete HYPO_ALONG_STK and HYPO_DOWN_DIP if "hypo_along_stk" in src_props: src_props.pop("hypo_along_stk") if "hypo_down_dip" in src_props: src_props.pop("hypo_down_dip") # Create common list of keys for all files output = "" for key in src_props: output = output + "%s = %s\n" % (key.upper(), src_props[key]) for sim in range(0, numsim): random.seed(sim + 1) seed = int(math.exp(7 * math.log(10.0)) * random.random()) hypo_along_stk = flen * (0.2 + 0.6 * random.random() - 0.5) hypo_down_dip = fwid * (0.2 + 0.6 * random.random()) srcfile = os.path.join(srcdir, "%s-%04d.src" % (prefix, sim)) outfile = open(srcfile, 'w') outfile.write(output) if hypo_rand: outfile.write("HYPO_ALONG_STK = %.2f\n" % (hypo_along_stk)) outfile.write("HYPO_DOWN_DIP = %.2f\n" % (hypo_down_dip)) outfile.write("SEED = %d\n" % (seed)) outfile.close()
def correct_station(self, station, extension): """ This function applies the user-provided correction factors to the station's amplitudes, and outputs the corrected file """ if not station in self.factors: raise bband_utils.ParameterError("Unknown station %s!" % (station)) orig_file = os.path.join(self.proc_dir, "%s-orig.%s" % (station, extension)) corr_file = os.path.join(self.proc_dir, "%s.%s" % (station, extension)) # Make sure input files exist if not os.path.exists(orig_file): raise bband_utils.ProcessingError("File %s not found!" % (orig_file)) # Pick set of correction factors factors = self.factors[station] # Correct rd50 file self.correct_file(factors, orig_file, corr_file)
def run(self): """ Generate an index file in the outdata directory """ print("GenHTML".center(80, '-')) install = InstallCfg.getInstance() sim_id = self.sim_id a_indir = os.path.join(install.A_IN_DATA_DIR, str(sim_id)) a_tmpdir = os.path.join(install.A_TMP_DATA_DIR, str(sim_id)) a_outdir = os.path.join(install.A_OUT_DATA_DIR, str(sim_id)) self.log = os.path.join(install.A_OUT_LOG_DIR, str(sim_id), "%d.genhtml.log" % (sim_id)) a_statfile = os.path.join(a_indir, self.r_stations) a_param_outdir = os.path.join(a_outdir, "param_files") a_param_statfile = os.path.join(a_param_outdir, self.r_stations) if self.r_src_file is not None and self.r_src_file != "": a_src_file = os.path.join(a_indir, self.r_src_file) a_param_srcfile = os.path.join(a_param_outdir, self.r_src_file) src_props = bband_utils.parse_properties(a_src_file) if "seed" in src_props: seed = src_props["seed"] else: seed = "not available" else: a_src_file = None a_param_srcfile = None # Make sure tmpdir, outdir exist dirs = [a_tmpdir, a_outdir, a_param_outdir] bband_utils.mkdirs(dirs, print_cmd=False) # Copy station list, srf_file to outdir's param_files directory shutil.copy2(a_statfile, a_param_statfile) if a_param_srcfile is not None: shutil.copy2(a_src_file, a_param_srcfile) # Get pointer to the velocity model object vel_obj = velocity_models.get_velocity_model_by_name(self.vmodel_name) if vel_obj is None: raise bband_utils.ParameterError("Cannot find velocity model: %s" % (self.vmodel_name)) vel_version = ("%s - %s" % (vel_obj.get_name(), vel_obj.get_version())) # Get pointer to validation object, if any val_version = None if self.val_name: val_obj = validation_cfg.VE_EVENTS.get_event_by_name(self.val_name) if val_obj is not None: val_version = ("%s - %s" % (val_obj.get_print_name(), val_obj.get_version())) # # Read and parse the station list with this call # slo = StationList(a_statfile) site_list = slo.getStationList() index_file = os.path.join(a_outdir, "index-%d.html" % (sim_id)) idxout = open(index_file, 'w') idxout.write("<html>\n") idxout.write("<title>Results for simulation %d</title>\n" % (sim_id)) idxout.write("<body>\n") idxout.write("<h2>Simulation Results</h2>\n") idxout.write("<table>\n") idxout.write("<tr>\n") idxout.write("<td>Broadband Version</td>\n") idxout.write("<td>%s</td>\n" % (install.VERSION)) idxout.write("</tr>\n") idxout.write("<tr>\n") idxout.write("<td>Velocity model version</td>\n") idxout.write("<td>%s</td>\n" % (vel_version)) idxout.write("</tr>\n") if val_version: idxout.write("<tr>\n") idxout.write("<td>Validation package version</td>\n") idxout.write("<td>%s</td>\n" % (val_version)) idxout.write("</tr>\n") if install.start_time is not None: idxout.write("<tr>\n") idxout.write("<td>Simulation Start Time</td>\n") idxout.write("<td>%s</td>\n" % (time.strftime("%a %d %b %Y %X %Z", install.start_time))) idxout.write("</tr>\n") idxout.write("<tr>\n") idxout.write("<td>Simulation End Time</td>\n") idxout.write("<td>%s</td>\n" % (time.strftime("%a %d %b %Y %X %Z", time.localtime()))) idxout.write("</tr>\n") idxout.write("<tr>\n") idxout.write("<td>Simulation ID</td>\n") idxout.write("<td>%d</td>\n" % (sim_id)) idxout.write("</tr>\n") idxout.write("<tr>\n") idxout.write("<td>Simulation Method</td>\n") idxout.write("<td>%s</td>\n" % (self.method)) idxout.write("</tr>\n") # Add xml file if os.path.exists(os.path.join(a_outdir, "%d.xml" % (sim_id))): idxout.write("<tr>\n") idxout.write("<td>Sim Spec</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "%d.xml" % (sim_id)), "%d.xml" % (sim_id))) idxout.write("</tr>\n") # Add station list and src_file if os.path.exists(os.path.join(a_param_outdir, self.r_stations)): idxout.write("<tr>\n") idxout.write("<td>Station List</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "param_files", self.r_stations), self.r_stations)) idxout.write("</tr>\n") if a_param_srcfile is not None: if os.path.exists(os.path.join(a_param_outdir, self.r_src_file)): idxout.write("<tr>\n") idxout.write("<td>Source Description</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "param_files", self.r_src_file), self.r_src_file)) idxout.write("</tr>\n") idxout.write("<tr>\n") idxout.write("<td>Random Seed</td>\n") idxout.write('<td>%s</td>\n' % (seed)) idxout.write("</tr>\n") # Get bias plots dist_lin_plot = glob.glob(os.path.join(a_outdir, "gof-dist-lin*.png")) dist_log_plot = glob.glob(os.path.join(a_outdir, "gof-dist-log*.png")) plots = glob.glob(os.path.join(a_outdir, "gof*.png")) rd50plot = glob.glob(os.path.join(a_outdir, "gof*-rd50.png")) gmpegofplot = glob.glob(os.path.join(a_outdir, "gof*-GMPE-*.png")) mapgofplot = glob.glob(os.path.join(a_outdir, "gof-map-*.png")) if len(gmpegofplot) == 1: gmpegofplot = gmpegofplot[0] else: gmpegofplot = "" if len(mapgofplot) == 1: mapgofplot = mapgofplot[0] else: mapgofplot = "" if len(dist_lin_plot) == 1: dist_lin_plot = dist_lin_plot[0] else: dist_lin_plot = "" if len(dist_log_plot) == 1: dist_log_plot = dist_log_plot[0] else: dist_log_plot = "" if len(rd50plot) == 1: rd50plot = rd50plot[0] else: if gmpegofplot: rd50plot = [plot for plot in rd50plot if plot != gmpegofplot] if mapgofplot: rd50plot = [plot for plot in rd50plot if plot != mapgofplot] if dist_lin_plot: rd50plot = [plot for plot in rd50plot if plot != dist_lin_plot] if dist_log_plot: rd50plot = [plot for plot in rd50plot if plot != dist_log_plot] if len(rd50plot) == 1: rd50plot = rd50plot[0] else: rd50plot = "" if len(plots) > 1: rspplot = [plot for plot in plots if (plot != rd50plot and plot != gmpegofplot and plot != mapgofplot and plot != dist_lin_plot and plot != dist_log_plot)] if len(rspplot) == 1: rspplot = rspplot[0] else: rspplot = "" else: rspplot = "" gmpegofplot = os.path.basename(gmpegofplot) mapgofplot = os.path.basename(mapgofplot) rd50plot = os.path.basename(rd50plot) rspplot = os.path.basename(rspplot) dist_lin_plot = os.path.basename(dist_lin_plot) dist_log_plot = os.path.basename(dist_log_plot) # Add RotD50 bias plot if rd50plot: idxout.write("<tr>\n") idxout.write("<td>RotD50 Bias Plot</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "%s" % (rd50plot)), "PNG")) idxout.write("</tr>\n") if mapgofplot: idxout.write("<tr>\n") idxout.write("<td>RotD50 Map GOF Plot</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "%s" % (mapgofplot)), "PNG")) idxout.write("</tr>\n") # Add RSP bias plot if rspplot: idxout.write("<tr>\n") idxout.write("<td>Respect Bias Plot</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "%s" % (rspplot)), "PNG")) idxout.write("</tr>\n") # Add the GMPE bias plot if gmpegofplot: idxout.write("<tr>\n") idxout.write("<td>GMPE Comparison Bias Plot</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "%s" % (gmpegofplot)), "PNG")) idxout.write("</tr>\n") # Add distance plots if dist_lin_plot: idxout.write("<tr>\n") idxout.write("<td>RotD50 Dist Bias Linear</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "%s" % (dist_lin_plot)), "PNG")) idxout.write("</tr>\n") if dist_log_plot: idxout.write("<tr>\n") idxout.write("<td>RotD50 Dist Bias Log</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "%s" % (dist_log_plot)), "PNG")) idxout.write("</tr>\n") # Add station map and kml file if os.path.exists(os.path.join(a_outdir, "station_map.png")): idxout.write("<tr>\n") idxout.write("<td>Station Map</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "station_map.png"), "PNG")) if os.path.exists(os.path.join(a_outdir, "station_map.kml")): idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", "station_map.kml"), "KML")) idxout.write("</tr>\n") # Now get SRF file and plot srfs = glob.glob(os.path.join(a_outdir, "*.srf")) if len(srfs) == 1: srffile = os.path.basename(srfs[0]) srfplot = ("%s.png" % (os.path.basename(os.path.splitext(srffile)[0]))) if not os.path.exists(os.path.join(a_outdir, srfplot)): srfplot = "" else: srffile = "" srfplot = "" if srffile: idxout.write("<tr>\n") idxout.write("<td>Rupture file</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", srffile), "data")) if srfplot: idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", srfplot), "PNG")) idxout.write("</tr>\n") idxout.write("</table>\n") idxout.write("<p><p>\n") for sits in site_list: site = sits.scode idxout.write("<p>\n") idxout.write("<h2>%s</h2>\n" % (site)) idxout.write("<table>\n") # Find all files velfile = "%d.%s.vel.bbp" % (sim_id, site) velplot = "%d.%s_velocity_seis.png" % (sim_id, site) accfile = "%d.%s.acc.bbp" % (sim_id, site) accplot = "%d.%s_acceleration_seis.png" % (sim_id, site) rd50file = "%d.%s.rd50" % (sim_id, site) rspfile = "%d.%s.rsp" % (sim_id, site) rd50plot = glob.glob(os.path.join(a_outdir, "*_%d_%s_rotd50.png" % (sim_id, site))) if len(rd50plot) == 1: rd50plot = os.path.basename(rd50plot[0]) else: rd50plot = "" rspplot = glob.glob(os.path.join(a_outdir, "*_%d_%s_rsp.png" % (sim_id, site))) if len(rspplot) == 1: rspplot = os.path.basename(rspplot[0]) else: rspplot = "" overlayfile = glob.glob(os.path.join(a_outdir, "*_%d_%s_overlay.png" % (sim_id, site))) if len(overlayfile) == 1: overlayfile = os.path.basename(overlayfile[0]) else: overlayfile = "" gmpeplot = glob.glob(os.path.join(a_outdir, "*_%d_%s_gmpe.png" % (sim_id, site))) if len(gmpeplot) == 1: gmpeplot = os.path.basename(gmpeplot[0]) else: gmpeplot = "" if os.path.exists(os.path.join(a_outdir, velfile)): idxout.write("<tr>\n") idxout.write("<td>Velocity</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", velfile), "BBP")) if os.path.exists(os.path.join(a_outdir, velplot)): idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", velplot), "PNG")) idxout.write("</tr>\n") if os.path.exists(os.path.join(a_outdir, accfile)): idxout.write("<tr>\n") idxout.write("<td>Acceleration</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", accfile), "BBP")) if os.path.exists(os.path.join(a_outdir, accplot)): idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", accplot), "PNG")) idxout.write("</tr>\n") if os.path.exists(os.path.join(a_outdir, rd50file)): idxout.write("<tr>\n") idxout.write("<td>RotD50</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", rd50file), "data")) if rd50plot: idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", rd50plot), "PNG")) idxout.write("</tr>\n") if os.path.exists(os.path.join(a_outdir, rspfile)): idxout.write("<tr>\n") idxout.write("<td>Respect</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", rspfile), "data")) if rspplot: idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", rspplot), "PNG")) idxout.write("</tr>\n") if overlayfile: idxout.write("<tr>\n") idxout.write("<td>Overlay</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", overlayfile), "PNG")) idxout.write("</tr>\n") if gmpeplot: idxout.write("<tr>\n") idxout.write("<td>GMPE Plot</td>\n") idxout.write('<td><a href="%s">%s</a></td>\n' % (os.path.join(".", gmpeplot), "PNG")) idxout.write("</tr>\n") idxout.write("</table>\n") idxout.write("</body>\n") idxout.write("</html>\n") idxout.close() print("==> Wrote file: %s" % (index_file)) print("GenHTML Completed".center(80, '-'))
def calculate_params(self, a_velmodel, user_sdrp=None): """ This function calculates a number of parameters for the rupture read in the src file. The results are stored in the cfgparams dictionary. """ cfgparams = self.cfgparams # Random seeds random.seed(self.SEED) cfgparams["seed1"] = int(random.random() * 10000) cfgparams["seed2"] = int(random.random() * 10000) cfgparams["seed3"] = int(random.random() * 10000) # cfgparams["seed1"] = 1170 # cfgparams["seed2"] = 2000 # cfgparams["seed3"] = 3000 # Constants cfgparams["t00"] = 0.0 cfgparams["ang1"] = 90.0 cfgparams["ang2"] = 0.0 cfgparams["akp"] = 0.001 cfgparams["ntc"] = 2 # From the Excel file # cfgparams["sdrp1"] = 100 # cfgparams["sdrp2"] = 100 cfgparams["mu"] = 3.4E+11 cfgparams["fdim"] = 2 cfgparams["plim"] = 1 cfgparams["npole"] = 2 cfgparams["flowf"] = 0.1 cfgparams["fhighf"] = 25 if user_sdrp is not None: cfgparams["sdrp1"] = user_sdrp cfgparams["sdrp2"] = user_sdrp else: # sdrp is calculated from Rake if self.RAKE >= -180 and self.RAKE <= 30: tmp_rake = 125 elif self.RAKE > 30 and self.RAKE <= 60: tmp_rake = 125 + (200.0 - 125.0) / (60.0 - 30.0) * (self.RAKE - 30) elif self.RAKE > 60 and self.RAKE <= 120: tmp_rake = 200 elif self.RAKE > 120 and self.RAKE <= 150: tmp_rake = 200 + (125.0 - 200.0) / (150.0 - 120.0) * (self.RAKE - 120) elif self.RAKE > 150 and self.RAKE <= 360: tmp_rake = 125 else: raise bband_utils.ParameterError("Rake is out of range!") cfgparams["sdrp1"] = tmp_rake cfgparams["sdrp2"] = tmp_rake # User parameters used in the mod files cfgparams["dx"] = 10 cfgparams["dy"] = 10 cfgparams["vrup"] = 2.0 cfgparams["dt"] = 0.02 cfgparams["twin"] = 81.92 # User parameters used in simula.in cfgparams["simula_in"] = {} cfgsimula = cfgparams["simula_in"] cfgsimula["mfiz"] = cfgparams["npole"] cfgsimula["flw"] = cfgparams["flowf"] cfgsimula["fhi"] = cfgparams["fhighf"] cfgsimula["ncoda"] = 400 cfgsimula["m"] = 512 cfgsimula["err"] = 0.001 cfgsimula["gi"] = 0.01 cfgsimula["gs"] = 0.005 cfgsimula["fmax"] = cfgsimula["fhi"] cfgsimula["qf"] = 150.0 cfgsimula["cn"] = 0.5 cfgsimula["nscat"] = 200 cfgsimula["fl"] = 1.5 cfgsimula["flb"] = 0.5 cfgsimula["akap1"] = 0.02 cfgsimula["akap2"] = 0.0 cfgsimula["seed2"] = cfgparams["seed2"] # User parameters used in scat1d.in cfgparams["scat1d_in"] = {} cfgscat1d = cfgparams["scat1d_in"] cfgscat1d["nlay"] = 300 cfgscat1d["damp"] = 1.0 cfgscat1d["dh"] = 0.003 cfgscat1d["ddh"] = 0.0026 cfgscat1d["va"] = 2.5 cfgscat1d["dv"] = 0.2 cfgscat1d["dena"] = 2.8 cfgscat1d["dden"] = 0.2 cfgscat1d["q"] = 100.0 cfgscat1d["mscat"] = 16 cfgscat1d["seed3"] = cfgparams["seed3"] # Now calculate others cfgparams["L"] = self.LENGTH cfgparams["W"] = self.WIDTH cfgparams["D"] = self.DIP cfgparams["R"] = self.RAKE # Set nt, dt, twins, fmax, and fmax1, fnyq cfgparams["nt"] = int(math.ceil(cfgparams["twin"] / cfgparams["dt"])) # Make sure the max number of points we have is 8192. If that # is not the case, adjust nt and dt accordingly if cfgparams["nt"] > 8192: cfgparams["nt"] = 8192 cfgparams["dt"] = cfgparams["twin"] / cfgparams["nt"] cfgparams["twins"] = cfgparams["twin"] cfgparams["fnyq"] = 0.5 / cfgparams["dt"] cfgparams["fmax"] = cfgparams["fnyq"] cfgparams["fmax1"] = cfgparams["fnyq"] # Now, calculate nx and ny zref = self.DEPTH_TO_TOP depth_tor = self.DEPTH_TO_TOP wem = (depth_tor - zref) / math.sin(math.radians(self.DIP)) wep = self.WIDTH + wem # Reference point is middle of the fault, so we have 1/2 # length in each direction lep = self.LENGTH / 2.0 lem = -1 * (self.LENGTH / 2.0) # Using the hypocenter along stk as reference point, which is # incorrect as per JA: 24-Apr-2013 #lep = (self.LENGTH / 2) - self.HYPO_ALONG_STK #lem = lep - self.LENGTH kx1 = int(round(lem / cfgparams["dx"])) kx2 = int(round(lep / cfgparams["dx"])) ky1 = int(round(wem / cfgparams["dy"])) ky2 = int(round(wep / cfgparams["dy"])) cfgparams["nx"] = len( numpy.arange(kx1 * cfgparams["dx"], (kx2 * cfgparams["dx"] + 0.000001), cfgparams["dx"])) cfgparams["ny"] = len( numpy.arange(ky1 * cfgparams["dy"], (ky2 * cfgparams["dy"] + 0.000001), cfgparams["dy"])) # Calculate latftop, longftop, depthftop reflat = self.LAT_TOP_CENTER reflon = self.LON_TOP_CENTER zetaftopdc = [lem, lep] etaftopdc = [wem, wem] xiftopdc = [0, 0] xftopdc, yftopdc, zftopdc, _ = self.zetaetaxi2xyz( zetaftopdc, etaftopdc, xiftopdc, self.STRIKE, self.DIP, zref) latftop, lonftop, depthftop = self.xyz2latlong(xftopdc, yftopdc, zftopdc, reflat, reflon) cfgparams["tlat1"] = latftop[0] cfgparams["tlat2"] = latftop[1] cfgparams["tlon1"] = lonftop[0] cfgparams["tlon2"] = lonftop[1] cfgparams["tdep"] = depthftop[0] cfgparams["sdept"] = ( zref + self.HYPO_DOWN_DIP * math.sin(math.radians(self.DIP))) # Calculate hypolat, hypolon, hypodepth hypoxi = 0 hypox, hypoy, hypoz, _ = self.zetaetaxi2xyz([self.HYPO_ALONG_STK], [self.HYPO_DOWN_DIP], [hypoxi], self.STRIKE, self.DIP, zref) hypolat, hypolon, hypodepth = self.xyz2latlong(hypox, hypoy, hypoz, reflat, reflon) cfgparams["hypolat"] = hypolat[0] cfgparams["hypolon"] = hypolon[0] cfgparams["hypodepth"] = hypodepth[0] # Calculate perw and perf (for nuclear.in) cfgparams["nuclear_in"] = {} cfgnuclear = cfgparams["nuclear_in"] cfgnuclear["perw"] = (self.HYPO_ALONG_STK / self.LENGTH) + 0.5 cfgnuclear["perf"] = self.HYPO_DOWN_DIP / self.WIDTH # Calculate realw, rmax, rmin, rmaxcm, rmincm (for compom.in) cfgparams["compom_in"] = {} cfgcompom = cfgparams["compom_in"] # Calculate moment # cfgcompom["eqmom"] = 10**(1.5 * self.MAGNITUDE + 16.1) # Calculate moment using new equation # Units N.m cfgcompom["eqmom"] = 10**(1.5 * self.MAGNITUDE + 16.05 - 7) # convert from N.m to dyne.cm cfgcompom["eqmom"] = cfgcompom["eqmom"] * 10**7 # Calculate rmax and rmin realw = min(self.LENGTH, self.WIDTH) cfgcompom["rmax"] = realw / 2.0 cfgcompom["rmin"] = cfgcompom["rmax"] / 20.0 # Read velocity model file self.parse_velmodel(a_velmodel) if self.nlay == 0: raise bband_utils.ParameterError("Unable to parse velocity model!") # Calculate vssp = mean(fcz(ddd, depths, vssm)) # Calculate ddd zetafodc = [lep, lep, lem, lem, lep] etafodc = [wem, wep, wep, wem, wem] xifodc = [0, 0, 0, 0, 0] xfodc, yfodc, zfodc, _ = self.zetaetaxi2xyz(zetafodc, etafodc, xifodc, self.STRIKE, self.DIP, zref) #latfo, longfo, depthfo = self.xyz2latlong(xfodc, yfodc, zfodc, # reflat, reflon) _, _, depthfo = self.xyz2latlong(xfodc, yfodc, zfodc, reflat, reflon) d1 = min(depthfo) d2 = max(depthfo) dd = (d2 - d1) / 20 ddd = numpy.arange(d1, d2 + 0.0001, dd) # Calculate depths zabove = [0 for _ in self.vmodel['h']] zbelow = [0 for _ in self.vmodel['h']] for idx, val in enumerate(self.vmodel['h']): if idx == 0: zabove[0] = val continue zabove[idx] = zabove[idx - 1] + val zbelow[0] = 0 zbelow[1:] = zabove[:-1] zabove = [val * 0.995 for val in zabove] zbelow = [val * 1.005 for val in zbelow] depths = [] for zab, zbe in zip(zabove, zbelow): depths.append(zbe) depths.append(zab) # Calculate vss vss_low = [vel * 0.995 for vel in self.vmodel['vs']] vss_hi = [vel * 1.005 for vel in self.vmodel['vs']] vss = [] for vlow, vhi in zip(vss_low, vss_hi): vss.append(vlow) vss.append(vhi) # Now, finally get vssp cfgparams["vssp"] = numpy.mean(list(numpy.interp(ddd, depths, vss))) # Now work on the csevents file fdim = cfgparams["fdim"] plim = cfgparams["plim"] sdrp = (cfgparams["sdrp1"] + (cfgparams["sdrp2"] - cfgparams["sdrp1"]) * random.random()) rmaxcm = cfgcompom["rmax"] * (10**5) rmincm = cfgcompom["rmin"] * (10**5) if fdim <= 3.1 and fdim >= 2.9: p = ((7.0 / 16) * cfgcompom["eqmom"] / (sdrp * (10**6)) * (cfgcompom["rmin"] / cfgcompom["rmax"])) else: cfdim = 3.0 - fdim p = ((7.0 / 16) * cfgcompom["eqmom"] / (sdrp * (10**6)) * (cfdim / (rmaxcm**cfdim - rmincm**cfdim))) nsub = int(math.floor( (p / fdim) * (rmincm**(-fdim) - rmaxcm**(-fdim)))) if nsub > 40000: raise bband_utils.ParameterError("Too many subevents: %d" % nsub) # Create subevents nc = [nsub * random.random() for _ in range(0, nsub)] srcm = [(fdim * val / p + rmaxcm**(-fdim))**(-1.0 / fdim) for val in nc] srkm = [val / 10**5 for val in srcm] sx = [ plim * val + (cfgparams["L"] - 2 * plim * val) * random.random() for val in srkm ] sy = [ val + (cfgparams["W"] - (1 + plim) * val) * random.random() for val in srkm ] submom = [(16.0 / 7) * sdrp * 10**6 * val**3 for val in srcm] # submw = [(2.0 / 3) * (math.log10(val) - 16.1) for val in submom] csmom = sum(submom) ratiom = csmom / cfgcompom["eqmom"] sdrpa = sdrp / ratiom submom = [(16.0 / 7) * sdrpa * 10**6 * val**3 for val in srcm] submw = [(2.0 / 3) * (math.log10(val) - 16.1) for val in submom] cfgparams["csevents_dat"] = {} cfg_csevents = cfgparams["csevents_dat"] cfg_csevents["sdrpa"] = sdrpa cfg_csevents["mu"] = cfgparams["mu"] cfg_csevents["nsub"] = nsub cfg_csevents["sx"] = sx cfg_csevents["sy"] = sy cfg_csevents["srkm"] = srkm cfg_csevents["submw"] = submw cfg_csevents["zetafo"] = zetafodc cfg_csevents["etafo"] = etafodc
def create_bbtoolbox_files(self, stat_file): """ This function creates the files needed by bbtoolbox, including the scattering file (if not provided), the station file, and the parameter file """ sta_base = os.path.basename(os.path.splitext(self.r_stations)[0]) a_indir = os.path.join(self.install.A_IN_DATA_DIR, str(self.sim_id)) a_tmpdir = os.path.join(self.install.A_TMP_DATA_DIR, str(self.sim_id)) a_tmpdir_mod = os.path.join(self.install.A_TMP_DATA_DIR, str(self.sim_id), "bbtoolbox_%s" % (sta_base)) a_outdir = os.path.join(self.install.A_OUT_DATA_DIR, str(self.sim_id)) a_param_outdir = os.path.join(a_outdir, "param_files") stat_list = StationList(stat_file) # Get pointer to the velocity model object vel_obj = velocity_models.get_velocity_model_by_name(self.vmodel_name) if vel_obj is None: raise bband_utils.ParameterError("Cannot find velocity model: %s" % (self.vmodel_name)) vmodel_params = vel_obj.get_codebase_params('sdsu') # Look for the source function parameter if 'SOURCE_FUNC' in vmodel_params: self.source_func = vmodel_params['SOURCE_FUNC'] # Look for correlation file parameter if "CORRELATION_FILE" in vmodel_params: # Set flag self.infcorr_flag = 1 # Find correlation file self.correlation_file = os.path.join( vel_obj.base_dir, vmodel_params['CORRELATION_FILE']) # Also copy file to bbtoolbox directory shutil.copy2( self.correlation_file, os.path.join(a_tmpdir_mod, os.path.basename(self.correlation_file))) else: # Disable flag self.infcorr_flag = 0 self.correlation_file = "correlation_file_not_used.txt" # Take care of scattering file if not self.r_scattering: # Need to create our file scattering_template = os.path.join(self.install.A_SDSU_DATA_DIR, "scattering_generic.dat") self.r_scattering = "scattering.dat" a_scattering = os.path.join(a_indir, self.r_scattering) # Look for KAPPA if 'KAPPA' in vmodel_params: self.kappa = float(vmodel_params['KAPPA']) # Look for FMAX if 'FMAX' in vmodel_params: self.fmax = float(vmodel_params['FMAX']) if 'Q' in vmodel_params: self.q_coda = float(vmodel_params['Q']) if 'FDEC' in vmodel_params: self.fdec = float(vmodel_params['FDEC']) if 'GS_FLAG' in vmodel_params: self.gs_flag = float(vmodel_params['GS_FLAG']) if 'NGAW_FLAG' in vmodel_params: self.ngaw_flag = float(vmodel_params['NGAW_FLAG']) if 'TR_SCA' in vmodel_params: self.tr_sca = float(vmodel_params['TR_SCA']) if 'AFAC' in vmodel_params: self.afac = float(vmodel_params['AFAC']) if 'BFAC' in vmodel_params: self.bfac = float(vmodel_params['BFAC']) if 'STR_FAC' in vmodel_params: self.str_fac = float(vmodel_params['STR_FAC']) # Check if we need to calculate stress if 'CALCULATE_STRESS' in vmodel_params: if float(vmodel_params['CALCULATE_STRESS']) == True: # Calculate stress based on depth of hypocenter self.str_fac = self.config.calculate_stress() # Open template and output files scat_in = open(scattering_template, 'r') scat_out = open(a_scattering, 'w') for line in scat_in: if line.find(r"\* iseed - seed number for scattering") >= 0: # This is the iseed line, insert the random iseed here pos = line.find(r"\* iseed - seed number for scattering") scat_out.write("%d %s" % (self.iseed, line[pos:])) elif line.find(r"\* kappa - kappa at the site") >= 0: # This is the kappa line, insert self.kappa here pos = line.find(r"\* kappa - kappa at the site") scat_out.write("%.3f %s" % (self.kappa, line[pos:])) elif line.find(r"\* fmax - ") >= 0: # This is the fmax line, insert self.fmax here pos = line.find(r"\* fmax - ") scat_out.write("%.2f %s" % (self.fmax, line[pos:])) elif line.find(r"\* Q - Q for the coda") >= 0: # This is the line, insert here pos = line.find(r"\* Q - Q for the coda") scat_out.write("%.1f %s" % (self.q_coda, line[pos:])) elif line.find(r"\* fdec - see equation") >= 0: # This is the line, insert here pos = line.find(r"\* fdec - see equation") scat_out.write("%.2f %s" % (self.fdec, line[pos:])) elif line.find(r"\* gs_flag - determine type") >= 0: # This is the line, insert here pos = line.find(r"\* gs_flag - determine type") scat_out.write("%d %s" % (int(self.gs_flag), line[pos:])) elif line.find(r"\* ngaw_flag - GMPEs") >= 0: # This is the line, insert here pos = line.find(r"\* ngaw_flag - GMPEs") scat_out.write("%d %s" % (int(self.ngaw_flag), line[pos:])) elif line.find(r"\* Tr_sca - scaling factor") >= 0: # This is the line, insert here pos = line.find(r"\* Tr_sca - scaling factor") scat_out.write("%.4f %s" % (self.tr_sca, line[pos:])) elif line.find(r"\* afac - qk factor") >= 0: # This is the line, insert here pos = line.find(r"\* afac - qk factor") scat_out.write("%.1f %s" % (self.afac, line[pos:])) elif line.find(r"\* bfac - qk factor") >= 0: # This is the line, insert here pos = line.find(r"\* bfac - qk factor") scat_out.write("%.1f %s" % (self.bfac, line[pos:])) elif line.find(r"\* str_fac - Brune stress") >= 0: # This is the line, insert here pos = line.find(r"\* str_fac - Brune stress") scat_out.write("%.2e %s" % (self.str_fac, line[pos:])) elif line.find(r"\* cseed - seed number") >= 0: # This is the line, insert here pos = line.find(r"\* cseed - seed number") scat_out.write("%d %s" % (self.config.SEED, line[pos:])) elif line.find(r"\* infcorr_flag") >= 0: # This is the line, insert here pos = line.find(r"\* infcorr_flag") scat_out.write("%d %s" % (int(self.infcorr_flag), line[pos:])) else: scat_out.write(line) # Done scat_in.close() scat_out.flush() scat_out.close() # Keep copy of scattering file in outdata shutil.copy2(a_scattering, os.path.join(a_param_outdir, self.r_scattering)) # Convert station file a_tmpfile = "station_%s.coords" % (sta_base) a_sdsu_stat_list = os.path.join(a_tmpdir_mod, "bbtstations_%s.tmp" % (sta_base)) a_sdsu_extended_fault = os.path.join(a_indir, "extended_fault") param_filename = stas2files.bbp2sdsu_statlist( a_indir, stat_list, a_sdsu_stat_list, self.r_srffile, self.r_xyz_srffile, a_sdsu_extended_fault, a_tmpfile) r_faultfile = os.path.basename(a_sdsu_extended_fault) # param_filename = stas2files.bbp2sdsu_statlist(a_indir, stat_list, # a_sdsu_stat_list, hypo) # now a_sdsu_stat_list has X Y name vs rho kappa # a_sdsu_stat_list.par has bbextension, bbstat, bbhypo # Build real station list self.r_stations = "bbtstations_%s.dat" % (sta_base) stalist_fp = open(os.path.join(a_indir, self.r_stations), 'w') # write headers stalist_fp.write("/* STATIONS FILE FOR BROAD-BAND COMPUTATION CODE " + "(P.M. MAI & K.B.OLSEN) */\n") stalist_fp.write("/* STATIONS COORDINATES ARE IN THE X-Y SYSTEM " + "REPORTED IN FIG.1 OF APPENDIX A */\n\n") stalist_fp.write("/* INPUT DIRECTORY */\n") # Create input directory and file prefix for the stations files file_prefix = os.path.join(a_tmpdir_mod, "%d." % (self.sim_id)) stalist_fp.write("%s\n\n" % (file_prefix)) stalist_fp.write("/* FILES FORMAT [RGF BIN CMP 3SF] */\n") stalist_fp.write("\t3SF\n\n") stalist_fp.write("/* FILES EXTENSION OR BINARY FILE NAME */\n") glob_stat = "%s/*-lf.bbp" % (a_tmpdir) bbp_list = glob.glob(glob_stat) # Now, figure out the file suffix if len(bbp_list) > 0: file_suffix = "-lf.bbp" else: file_suffix = ".bbp" # Write suffix stalist_fp.write("%s\n\n" % (file_suffix)) # Write header for station list stalist_fp.write("/*\tX\tY\tNAME\tVs\tRho\tKappa */\n") # Now, append the station list we have in a_sdsu_stat_list conv_list_fp = open(a_sdsu_stat_list, 'r') for line in conv_list_fp: stalist_fp.write(line) # Figure out if station file path is too long pieces = line.split() st_name = pieces[2] total_length = len(file_prefix) + len(st_name) + len(file_suffix) if total_length >= bband_utils.SDSU_MAX_FILENAME: # Close files stalist_fp.close() conv_list_fp.close() raise ValueError("station path for %s " % (st_name) + " is %d characters long, maximum is %d" % (total_length, bband_utils.SDSU_MAX_FILENAME)) # Flush all data, and close this file stalist_fp.flush() stalist_fp.close() # Close station file conv_list_fp.close() # Keep copy of station file in outdata shutil.copy2(os.path.join(a_indir, self.r_stations), os.path.join(a_param_outdir, self.r_stations)) # Read param file conv_par_fp = open(param_filename, 'r') conv_par_data = conv_par_fp.readlines() conv_par_fp.close() # 2nd line is hypo coordinates hypo_line = conv_par_data[1].split(':')[1] hypo_coords = [] for i in range(0, 3): hypo_coords.append(hypo_line.split()[i]) min_box_dims = [] min_box_line = conv_par_data[0].split(':')[1] for i in range(0, 2): min_box_dims.append(float(min_box_line.split()[i])) # FS: Feb-2013: Get magnitude directly from SRC file # FS: Mar-2013: We use this magnitude only when we don't have # a SRC file # get magnitude from 3rd line magnitude = float(conv_par_data[2].split(':')[1]) self.r_bbparfile = "%d_%s.bbpar" % (self.sim_id, sta_base) parfile_name = os.path.join(a_indir, self.r_bbparfile) parfile_fp = open(parfile_name, 'w') parfile_fp.write("/* MODALITY FLAG: [0] LF-HF MERGING, " + "[1] LF-SCATTERING, [2] LF-ISOCHRONE */\n") parfile_fp.write(" %d\n" % (self.config.MODALITY)) parfile_fp.write("/* OUTPUT DIRECTORY */\n") parfile_fp.write('"%s"\n' % a_tmpdir_mod) parfile_fp.write('/* VELOCITY MODEL FILE (3D MODEL OR 1D MODEL) */\n') parfile_fp.write('"%s"\n' % (os.path.join(a_indir, self.r_velmodel))) parfile_fp.write("/* STATIONS FILE REPORTING [X-Y] COORDINATES, " + "FILENAMES AND PARAMETERS */\n") parfile_fp.write('"%s"\n' % (os.path.join(a_indir, self.r_stations))) parfile_fp.write("/* OPTIONAL 2ND STATIONS FILE REPORTING ONLY " + "FILENAMES - ONLY FOR MODALITY = 0 */\n") parfile_fp.write("2ndstations.dat\n") parfile_fp.write("/* FAULT MODEL TYPE: [POINT], " + "[EXTENDED FAULT-MODEL FILE] */\n") parfile_fp.write(' extended "%s"\n' % (os.path.join(a_indir, r_faultfile))) # parfile_fp.write(' point\n') parfile_fp.write("/* HYPOCENTER COORDINATES [X-Y-Z] IN KM */\n") parfile_fp.write("%.2f %.2f %.2f\n" % (float( hypo_coords[0]), float(hypo_coords[1]), float(hypo_coords[2]))) parfile_fp.write('/* GRID DEFINITION [X-Y-Z] FOR RAYTRACING: ' + '"NEAR-SIDE", GRID-SPACING (IN KM) */\n') parfile_fp.write("0.0 0.0 0.0 1.0\n") parfile_fp.write('/* GRID DEFINITION [X-Y-Z] FOR RAYTRACING: ' + '"FAR-SIDE" (IN KM) */\n') if self.config.grid_x is not None and self.config.grid_y is not None: parfile_fp.write( "%.1f %.1f %.1f\n" % (self.config.grid_x, self.config.grid_y, self.config.grid_z)) else: parfile_fp.write( "%.1f %.1f %.1f\n" % (round(min_box_dims[0] + 20.0, 0), round(min_box_dims[1] + 20.0, 0), self.config.grid_z)) parfile_fp.write("/* SCATTERING PARAMETERS FILE */\n") parfile_fp.write('"%s"\n' % (os.path.join(a_indir, self.r_scattering))) parfile_fp.write("/* EVENT MAGNITUDE */\n") if self.config.MAG is None: parfile_fp.write("%.2f\n" % (magnitude)) else: parfile_fp.write("%.2f\n" % (self.config.MAG)) parfile_fp.write("/* DOMINANT SOURCE MECHANISM [SS RS NS AL] */\n") parfile_fp.write("%s\n" % conv_par_data[3].split(":")[1].strip()) parfile_fp.write("/* SOURCE TIME FUNCTION " "[TRI BOX YOF DREG LIU USER-DEF] */\n") parfile_fp.write("%s\n" % (self.source_func)) parfile_fp.write("/* VERBOSE MODE [ON OFF] */\n") parfile_fp.write("off\n") parfile_fp.write("/* SRF FILE */\n") parfile_fp.write('"%s"\n' % (os.path.join(a_indir, self.r_xyz_srffile))) parfile_fp.write("/* CORRELATION FILE */\n") parfile_fp.write("%s\n" % (os.path.basename(self.correlation_file))) parfile_fp.write("/* RAKE */\n") parfile_fp.write("%.2f\n" % (self.config.RAKE)) parfile_fp.flush() parfile_fp.close() # Keep a copy in the outdata directory shutil.copy2(parfile_name, os.path.join(a_param_outdir, self.r_bbparfile))
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 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 hypo_lon, hypo_lat, _ = get_hypocenter(input_file) return hypo_lon, hypo_lat # If we don't have a SRC file, we should print an error here if not input_file.endswith(".src"): bband_utils.ParameterError("input file should be a SRC or SRF file!") # Ok, we have a SRC file # Get information from SRC file cfgdict = bband_utils.parse_properties(input_file) try: strike = cfgdict["strike"] except KeyError: bband_utils.ParameterError("SRC file missing STRIKE parameter!") strike = float(strike) try: dip = cfgdict["dip"] except KeyError: bband_utils.ParameterError("SRC file missing DIP parameter!") dip = float(dip) try: hypo_down_dip = cfgdict["hypo_down_dip"] except KeyError: bband_utils.ParameterError("SRC file missing " "HYPO_DOWN_DIP parameter!") hypo_down_dip = float(hypo_down_dip) try: hypo_along_strike = cfgdict["hypo_along_stk"] except KeyError: bband_utils.ParameterError("SRC file missing " "HYPO_ALONG_STK parameter!") hypo_along_strike = float(hypo_along_strike) try: lat_top_center = cfgdict["lat_top_center"] except KeyError: bband_utils.ParameterError("SRC file missing " "LAT_TOP_CENTER parameter!") lat_top_center = float(lat_top_center) try: lon_top_center = cfgdict["lon_top_center"] except KeyError: bband_utils.ParameterError("SRC file missing " "LON_TOP_CENTER parameter!") lon_top_center = float(lon_top_center) # Ok, we have all the parameters that we need! hypo_perpendicular_strike = hypo_down_dip * math.cos(math.radians(dip)) # Now call xy2ll program to convert it to lat/long # Create temp directory to avoid any race conditions tmpdir = tempfile.mkdtemp(prefix="bbp-") hypfile = os.path.join(tmpdir, "src_hypo.tmp") install = InstallCfg.getInstance() cmd = ('echo "%f %f" | %s mlat=%f mlon=%f xazim=%f > %s' % (hypo_along_strike, hypo_perpendicular_strike, os.path.join(install.A_GP_BIN_DIR, "xy2ll"), lat_top_center, lon_top_center, strike, hypfile)) bband_utils.runprog(cmd, print_cmd=False) src_hypo_fp = open(hypfile, 'r') src_hypo_data = src_hypo_fp.readline() src_hypo_fp.close() src_hypo = [float(val) for val in src_hypo_data.split()] # Delete temp directory shutil.rmtree(tmpdir) # Return calculated lon/lat return src_hypo[0], src_hypo[1]
def run(self): """ Runs the UCSB site response program """ print("UCSB Site".center(80, '-')) # # Global installation parameters # install = InstallCfg.getInstance() # # Required Inputs are sim_id, SRC file, and station list # sim_id = self.sim_id sta_base = os.path.basename(os.path.splitext(self.r_stations)[0]) self.log = os.path.join(install.A_OUT_LOG_DIR, str(sim_id), "%d.uc_site_%s.log" % (sim_id, sta_base)) a_indir = os.path.join(install.A_IN_DATA_DIR, str(sim_id)) a_tmpdir = os.path.join(install.A_TMP_DATA_DIR, str(sim_id)) a_tmpdir_mod = os.path.join(install.A_TMP_DATA_DIR, str(sim_id), "uc_site_%s" % (sta_base)) a_outdir = os.path.join(install.A_OUT_DATA_DIR, str(sim_id)) a_velocity = os.path.join(a_indir, self.r_velocity) # # Make sure the output and tmp directories exist # bband_utils.mkdirs([a_tmpdir, a_tmpdir_mod, a_outdir], print_cmd=False) # Parse SRC file if self.r_srcfile is None or self.r_srcfile == "": raise bband_utils.ParameterError("SRC file not defined!") a_srcfile = os.path.join(a_indir, self.r_srcfile) self.cfg = UCSiteCfg(a_srcfile) cfg = self.cfg # Store cwd and change over to tmpdir so the executable can # find the files old_cwd = os.getcwd() os.chdir(a_tmpdir_mod) # Copy velocity file to tmpdir_mod shutil.copy2(a_velocity, os.path.join(a_tmpdir_mod, self.r_velocity)) # Read station list a_stations = os.path.join(a_indir, self.r_stations) print(a_stations) slo = StationList(a_stations) site_list = slo.getStationList() # This is not a UCSB format station list, convert station # list to UCSB format, generating the station file and the # vs30 file a_uc_stations = os.path.join(a_tmpdir_mod, cfg.R_UC_STATION_FILE) a_uc_vs30 = os.path.join(a_tmpdir_mod, cfg.R_UC_VS30_FILE) stas2files.gp2uc_stalist(slo, a_uc_stations, a_uc_vs30) # # The UCSB codes require fixed input names. So here, we copy # the UCSB file over to the expected name "stations.ll" # cmd = ("cp %s %s" % (a_uc_stations, os.path.join(a_tmpdir_mod, "stations.ll"))) bband_utils.runprog(cmd) # Copy .bbp files over to .3comp # If we have anything but just a hybrid file, combine them first # Use site 0 as the dummy for site in site_list: if os.path.exists("%s/%d.%s.bbp" % (a_tmpdir, sim_id, site.scode)): shutil.copy2("%s/%d.%s.bbp" % (a_tmpdir, sim_id, site.scode), "%s/%s.3comp" % (a_tmpdir_mod, site.scode)) elif os.path.exists("%s/%s.3comp" % (a_tmpdir, site.scode)): shutil.copy2("%s/%s.3comp" % (a_tmpdir, site.scode), "%s/%s.3comp" % (a_tmpdir_mod, site.scode)) # determine dt for input seismogram bbp_fp = open("%s/%s.3comp" % (a_tmpdir_mod, site.scode), 'r') bbp_data = bbp_fp.readlines() bbp_fp.close() i = 0 while bbp_data[i][0] == '%' or bbp_data[i][0] == '#': i += 1 t0 = float(bbp_data[i].split()[0]) t1 = float(bbp_data[i + 1].split()[0]) input_dt = t1 - t0 print("input_dt: %f\n" % (input_dt)) # # Create deconvBBP.inp, stitchBBP.inp, VMname.list # dBBP_in = open("deconvBBP.inp", "w") dBBP_in.write("%s\n" % self.r_velocity) dBBP_in.write("0.29\n") dBBP_in.write("1\n") dBBP_in.write("%d\n" % len(site_list)) for site in site_list: dBBP_in.write("%s\n" % site.scode) dBBP_in.flush() dBBP_in.close() sBBP_in = open("stitchBBP.inp", "w") sBBP_in.write("stations.xy\n") sBBP_in.write("VMname.list\n") sBBP_in.write("./\n") sBBP_in.write("./\n") sBBP_in.write("1.0, 15.0\n") # depth of hypocenter hypo_dep = fault_utils.calculate_hypo_depth(a_srcfile) sBBP_in.write("%s\n" % hypo_dep) sBBP_in.write("1\n") sBBP_in.write("2\n") sBBP_in.flush() sBBP_in.close() vMname_in = open("VMname.list", "w") for site in site_list: vMname_in.write("%s\n" % self.r_velocity) vMname_in.flush() vMname_in.close() # # Create stations.xy if it doesn't exist yet # if not os.path.exists("stations.xy"): # # Create faultGlobal.in # r_faultfile = "faultGlobal.in" a_faultfile = os.path.join(a_tmpdir_mod, r_faultfile) self.create_fault_global_in(a_faultfile) # # Convert stations to xy # cmd = "%s >> %s 2>&1" % (self.cfg.A_SLL2XY, self.log) bband_utils.runprog(cmd) # # Deconvolve # cmd = "%s >> %s 2>&1" % (self.cfg.A_UC_DECON_EXE, self.log) bband_utils.runprog(cmd) # # Logic of separateStats.csh pulled out into function # stations_to_stitch = self.separate_stats(install, a_uc_vs30, input_dt) # # Stitch # # Update station files to only stitch non class A stations # (Class A stations don't have a non-linear component) # Must use 'stations.xy' because it's in stitchBBP.inp # shutil.copy2("stations.xy", "stations.xy.orig") shutil.copy2("stations.ll", "stations.ll.orig") station_in = open("stations.xy.orig", 'r') station_ll_in = open("stations.ll.orig", "r") station_ll_data = station_ll_in.readlines() station_data = station_in.readlines() station_in.close() station_ll_in.close() station_out = open("stations.xy", "w") station_ll_out = open("stations.ll", "w") pieces = station_data[0].split() station_out.write("%d %f %f %f\n" % (len(stations_to_stitch), float( pieces[1]), float(pieces[2]), float(pieces[3]))) station_ll_out.write("%d\n" % len(stations_to_stitch)) i = 1 while i < len(station_data): inList = False stat_data_name = station_data[i].strip() for site in stations_to_stitch: if stat_data_name == site: inList = True break if inList: station_out.write("%s\n" % stat_data_name) station_out.write("%s" % station_data[i + 1]) station_ll_out.write("%s" % station_ll_data[(i + 1) // 2]) i += 2 station_out.flush() station_ll_out.flush() station_out.close() station_ll_out.close() cmd = "%s >> %s 2>&1" % (self.cfg.A_STITCH, self.log) bband_utils.runprog(cmd) # # Copy original stations file back in # shutil.copy2("stations.xy", "stations.xy.stitch") shutil.copy2("stations.xy.orig", "stations.xy") # Convert to 3-component seismograms # cmd = "%s/conv3CompBB >> %s 2>&1" % (install.A_UCSB_BIN_DIR, self.log) bband_utils.runprog(cmd) shutil.copy2("stations.ll", "stations.ll.stitch") shutil.copy2("stations.ll.orig", "station.ll") # Move the results to the output directory, as bbp format for result_file in os.listdir(a_tmpdir_mod): dot_index = result_file.rfind('.3comp') if dot_index > -1: basename = result_file[0:dot_index] shutil.copy2(result_file, "%s/%d.%s.vel.bbp" % (a_outdir, sim_id, basename)) shutil.copy2(result_file, "%s/%d.%s.vel.bbp" % (a_tmpdir, sim_id, basename)) shutil.copy2(result_file, "%s/%s.3comp" % (a_tmpdir, basename)) # Create acceleration seismogram # Create path names and check if their sizes are # within bounds nsfile = os.path.join(a_tmpdir, "%d.%s.000" % (sim_id, basename)) ewfile = os.path.join(a_tmpdir, "%d.%s.090" % (sim_id, basename)) udfile = os.path.join(a_tmpdir, "%d.%s.ver" % (sim_id, basename)) bbpfile = os.path.join(a_tmpdir, "%d.%s.vel.bbp" % (sim_id, basename)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) cmd = ("%s/wcc2bbp " % (install.A_GP_BIN_DIR) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "wcc2bbp=0 < %s >> %s 2>&1" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True) for comp in cfg.COMPS: # Differentiate each component filein = os.path.join( a_tmpdir, "%d.%s.%s" % (sim_id, basename, comp)) fileout = os.path.join( a_tmpdir, "%d.%s.acc.%s" % (sim_id, basename, comp)) bband_utils.check_path_lengths([filein, fileout], bband_utils.GP_MAX_FILENAME) cmd = ("%s/integ_diff diff=1 filein=%s fileout=%s" % (install.A_GP_BIN_DIR, filein, fileout)) bband_utils.runprog(cmd, abort_on_error=True) # Create path names and check if their sizes are # within bounds nsfile = os.path.join(a_tmpdir, "%d.%s.acc.000" % (sim_id, basename)) ewfile = os.path.join(a_tmpdir, "%d.%s.acc.090" % (sim_id, basename)) udfile = os.path.join(a_tmpdir, "%d.%s.acc.ver" % (sim_id, basename)) bbpfile = os.path.join(a_tmpdir, "%d.%s.acc.bbp" % (sim_id, basename)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) cmd = ("%s/wcc2bbp " % (install.A_GP_BIN_DIR) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "units=cm/s/s wcc2bbp=1 > %s 2>> %s" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True) # Copy acceleration bbp file to outdir shutil.copy2( os.path.join(a_tmpdir, "%d.%s.acc.bbp" % (sim_id, basename)), os.path.join(a_outdir, "%d.%s.acc.bbp" % (sim_id, basename))) os.chdir(old_cwd) print("UCSB Site Completed".center(80, '-'))
def create_velocity_file(self, vel_file, vel_file_p): """ This function creates the Irikura velocity model file """ # Get the parameters we need thick = self.config.vmodel["h"] vs_km = self.config.vmodel["vs"] vp_km = self.config.vmodel["vp"] rho = self.config.vmodel["rho"] qs = self.config.vmodel["qs"] # Convert to meters thick = [item * 1000 for item in thick] vs_m = [item * 1000 for item in vs_km] vp_m = [item * 1000 for item in vp_km] # Convert depths to absolute depths depth = [0] * len(thick) depth[0] = thick[0] for idx in range(1, len(thick)): depth[idx] = depth[idx - 1] + thick[idx] depth[len(thick) - 1] = 9999999999 # Make a copy of the original array self.config.vmodel["depth0"] = depth[:] if self.config.DEPTH_TO_TOP < 1.0: idx = bisect.bisect_left(depth, 1000) if len(depth) == idx: raise bband_utils.ParameterError("Velocity model above ztor!") depth = depth[:idx + 1] else: # Now, only pick the ones up to fault depth idx = bisect.bisect_left(depth, self.config.DEPTH_TO_TOP * 1000) if len(depth) == idx: raise bband_utils.ParameterError("Velocity model above ztor!") if not depth[idx] == self.config.DEPTH_TO_TOP * 1000: depth[idx] = self.config.DEPTH_TO_TOP * 1000 # Select values up to the top of the fault depth = depth[:idx + 1] # Write vel_file out_file = open(vel_file, 'w') out_file.write("# SOIL-LAYER.DAT\n") out_file.write("# SOIL-PARAM(Vs,Ro,Qs)\n") # Write Vs, Rho, Qs for idx in range(0, len(depth) + 1): out_file.write("%d %d %4.2f %d\n" % (idx + 1, vs_m[idx], rho[idx], round(qs[idx]))) out_file.write("# LAYER-DEPTH(GL-m)\n") for idx, _ in enumerate(self.stat_list.getStationList(), 1): out_file.write("%d %d %d" % (idx, 0, 0)) for item in depth: out_file.write(" %.1f" % (item)) out_file.write("\n") out_file.close() # Write vel_file_p out_file = open(vel_file_p, 'w') out_file.write("# SOIL-LAYER.DAT\n") out_file.write("# SOIL-PARAM(Vp,Ro,Qs)\n") # Write Vs, Rho, Qs for idx in range(0, len(depth) + 1): out_file.write("%d %d %4.2f %d\n" % (idx + 1, vp_m[idx], rho[idx], round(qs[idx]))) out_file.write("# LAYER-DEPTH(GL-m)\n") for idx, _ in enumerate(self.stat_list.getStationList(), 1): out_file.write("%d %d %d" % (idx, 0, 0)) for item in depth: out_file.write(" %.1f" % (item)) out_file.write("\n") out_file.close() # Store velocity model results self.config.vmodel["depth"] = depth self.config.vmodel["vs_m"] = vs_m self.config.vmodel["vp_m"] = vp_m
def run(self): """ This function prepares the parameters for HFSim and then calls it """ print("GP HfSims".center(80, '-')) install = InstallCfg.getInstance() sim_id = self.sim_id # Find validation object if this is a validation run if self.val_name is not None: self.val_obj = validation_cfg.VE_EVENTS.get_event_by_name( self.val_name) sta_base = os.path.basename(os.path.splitext(self.r_stations)[0]) self.log = os.path.join(install.A_OUT_LOG_DIR, str(sim_id), "%d.hfsims_%s.log" % (sim_id, sta_base)) a_indir = os.path.join(install.A_IN_DATA_DIR, str(sim_id)) a_tmpdir = os.path.join(install.A_TMP_DATA_DIR, str(sim_id)) a_srffile = os.path.join(a_indir, self.r_srffile) # Make sure we work when starting from an SRF file if self.r_srcfile: a_srcfile = os.path.join(a_indir, self.r_srcfile) else: a_srcfile = "" # Set up basic parameters, read SRC file if provided config = HfsimsCfg(a_srcfile=a_srcfile) # Get pointer to the velocity model object vel_obj = velocity_models.get_velocity_model_by_name(self.vmodel_name) if vel_obj is None: raise bband_utils.ParameterError("Cannot find velocity model: %s" % (self.vmodel_name)) # Check for velocity model-specific parameters vmodel_params = vel_obj.get_codebase_params('gp') # Look for KAPPA if 'KAPPA' in vmodel_params: self.kappa = float(vmodel_params['KAPPA']) else: self.kappa = config.KAPPA # Look for QFEXP if 'QFEXP' in vmodel_params: self.qfexp = float(vmodel_params['QFEXP']) else: self.qfexp = config.DEFAULT_QFEXP # Look for SDROP if 'SDROP' in vmodel_params: self.sdrop = int(vmodel_params['SDROP']) else: self.sdrop = config.DEFAULT_SDROP # Look for C0 and C1 if 'C0' in vmodel_params: self.c0 = int(vmodel_params['C0']) else: self.c0 = config.DEFAULT_C0 if 'C1' in vmodel_params: self.c1 = int(vmodel_params['C1']) else: self.c1 = config.DEFAULT_C1 # Look for DEFAULT_FCFAC if 'DEFAULT_FCFAC' in vmodel_params: self.default_fcfac = float(vmodel_params['DEFAULT_FCFAC']) else: self.default_fcfac = config.DEFAULT_FCFAC # Look for rayset if 'RAYSET' in vmodel_params: self.rayset = ast.literal_eval(vmodel_params['RAYSET']) else: self.rayset = config.RAYSET # Look for a high frequency DT if 'HF_DT' in vmodel_params: self.dt = float(vmodel_params['HF_DT']) else: self.dt = config.DT # Look for MEAN_RVFAC if 'MEAN_RVFAC' in vmodel_params: self.mean_rvfac = float(vmodel_params['MEAN_RVFAC']) else: self.mean_rvfac = config.MEAN_RVFAC # Look for RANGE_RVFAC if 'RANGE_RVFAC' in vmodel_params: self.range_rvfac = float(vmodel_params['RANGE_RVFAC']) else: self.range_rvfac = config.RANGE_RVFAC # Look for SHAL_RVFAC if 'SHAL_RVFAC' in vmodel_params: self.shal_rvfac = float(vmodel_params['SHAL_RVFAC']) else: self.shal_rvfac = config.SHAL_RVFAC # Look for VSMOHO if 'VSMOHO' in vmodel_params: self.vsmoho = float(vmodel_params['VSMOHO']) else: self.vsmoho = config.DEFAULT_VSMOHO # Look for DEEP_RVFAC if 'DEEP_RVFAC' in vmodel_params: self.deep_rvfac = float(vmodel_params['DEEP_RVFAC']) else: self.deep_rvfac = config.DEEP_RVFAC # Look for PATH_DUR_MODEL if 'PATH_DUR_MODEL' in vmodel_params: self.path_dur_model = int(vmodel_params['PATH_DUR_MODEL']) else: self.path_dur_model = config.PATH_DUR_MODEL # Look for RVSIG if 'RVSIG' in vmodel_params: self.rvsig = float(vmodel_params['RVSIG']) else: self.rvsig = config.RVSIG # Look for DX if 'DEFAULT_DX' in vmodel_params: self.default_dx = float(vmodel_params['DEFAULT_DX']) else: self.default_dx = config.DEFAULT_DX # Look for DY if 'DEFAULT_DY' in vmodel_params: self.default_dy = float(vmodel_params['DEFAULT_DY']) else: self.default_dy = config.DEFAULT_DY # Look for ISPAR_ADJUST if 'ISPAR_ADJUST' in vmodel_params: ispar_adjust = int(vmodel_params['ISPAR_ADJUST']) else: ispar_adjust = config.ISPAR_ADJUST # Calculate rvfac if "common_seed" in config.CFGDICT: rvfac = calculate_rvfac(self.mean_rvfac, self.range_rvfac, config.CFGDICT["common_seed"]) else: rvfac = calculate_rvfac(self.mean_rvfac, self.range_rvfac, config.CFGDICT["seed"]) # Look for tlen if "TLEN" in vmodel_params: self.tlen = float(vmodel_params['TLEN']) else: self.tlen = config.TLEN # Start with some default values moment = -1 extra_fcfac = config.DEFAULT_EXTRA_FCFAC if self.val_obj is not None: extra_fcfac = float(self.val_obj.get_input("GP", "EXTRA_FCFAC")) try: tlen = float(self.val_obj.get_input("GP", "TLEN")) self.tlen = tlen except (ValueError, KeyError, TypeError): # No problem, just use the default TLEN for this simulation pass fcfac = round((1 + self.default_fcfac) * (1 + extra_fcfac) - 1, 4) a_slipfile = os.path.join( a_tmpdir, "%s.%s.%fx%f" % (self.r_srffile, sta_base, self.default_dx, self.default_dy)) progstring = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "srf2stoch")) + "infile=%s outfile=%s " % (a_srffile, a_slipfile) + "target_dx=%f target_dy=%f " % (self.default_dx, self.default_dy) + ">> %s 2>&1" % (self.log)) bband_utils.runprog(progstring) a_outp = os.path.join(a_tmpdir, "tmp_hfsim_out") a_velmod = os.path.join(install.A_IN_DATA_DIR, str(sim_id), self.r_velmodel) a_statfile = os.path.join(install.A_IN_DATA_DIR, str(sim_id), self.r_stations) # Create local velocity model vel_in_fp = open(a_velmod, 'r') a_velmod = "%s_%s.local" % (a_velmod, sta_base) vel_out_fp = open(a_velmod, 'w') vel_in_data = vel_in_fp.readlines() vel_in_fp.close() i = 0 for line in vel_in_data: i += 1 if line.startswith('#') or line.startswith('%'): continue pieces = line.split() if len(pieces) >= 4: th = float(pieces[0]) vp = float(pieces[1]) vs = float(pieces[2]) dn = float(pieces[3]) qs = self.c0 + self.c1 * vs if i == len(vel_in_data): th = 0.0 vel_out_fp.write("%8.4f %8.4f %8.4f %8.4f %8.2f %8.2f\n" % (th, vp, vs, dn, qs, qs)) else: vel_out_fp.write(line) vel_out_fp.flush() vel_out_fp.close() # # Scan the station list with this object construction # This scanner removes all the comment lines and the # list that is returned has one station per line in it. # slo = StationList(a_statfile) site_list = slo.getStationList() nstat = len(site_list) # Create rayset param list rayset_param = "" for item in self.rayset: rayset_param = rayset_param + "%d " % (item) rayset_param = rayset_param.strip() # # Run initial hfsim conf # progstring = ( "%s >> %s 2>&1 << END\n" % (os.path.join(install.A_GP_BIN_DIR, config.HFSIM), self.log) + "%d\n" % self.sdrop + "%s\n" % a_statfile + "%s\n" % a_outp + "%s\n" % rayset_param + "%d\n" % config.SITEAMP + "4 0 0.02 19.9\n" + "%d\n" % config.CFGDICT["seed"] + "%d\n" % nstat + "%f %f %f %f %f\n" % (self.tlen, self.dt, config.FMAX, self.kappa, self.qfexp) + "%f %f %f %f %f\n" % (rvfac, self.shal_rvfac, self.deep_rvfac, config.C_ZERO, config.C_ALPHA) + "%s %f\n" % (moment, config.RUPV) + "%s\n" % a_slipfile + "%s\n" % a_velmod + "%f\n" % self.vsmoho + "-99 0.0 0.0 0.0 0.0 1\n" + "-1\n" + "%f 0.0 %f\n" % (config.FA_SIG1, self.rvsig) + "%d\n" % (self.path_dur_model) + "%d -1 -1\n" % (ispar_adjust) + "END") bband_utils.runprog(progstring) # # Start the per station processing # for site in site_list: # Need to integrate each component, since hfsims outputs cm/s/s for comp in ['000', '090', 'ver']: cmd = ("%s integ=1 " % (os.path.join(install.A_GP_BIN_DIR, "integ_diff")) + "filein=%s_%s.%s fileout=%s/%d.%s-hf.%s >> %s 2>&1" % (a_outp, site.scode, comp, a_tmpdir, sim_id, site.scode, comp, self.log)) bband_utils.runprog(cmd, print_cmd=False) progstring1 = ( "%s wcc2bbp=1 " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + 'title="HF Sim NGAH, stat=%s" ' % (site.scode) + "nsfile=%s/%d.%s-hf.000 " % (a_tmpdir, sim_id, site.scode) + "ewfile=%s/%d.%s-hf.090 " % (a_tmpdir, sim_id, site.scode) + "udfile=%s/%d.%s-hf.ver " % (a_tmpdir, sim_id, site.scode) + 'units="%s" > %s/%d.%s-hf.bbp 2>> %s\n' % (str(config.UNITS), a_tmpdir, sim_id, site.scode, self.log)) bband_utils.runprog(progstring1, print_cmd=False) progstring1 = ("%s wcc2bbp=1 " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + 'title="HF Sim NGAH, stat=%s" ' % site.scode + "nsfile=%s_%s.000 " % (a_outp, site.scode) + "ewfile=%s_%s.090 " % (a_outp, site.scode) + "udfile=%s_%s.ver " % (a_outp, site.scode) + '> %s_%s.bbp 2>> %s\n' % (a_outp, site.scode, self.log)) bband_utils.runprog(progstring1, print_cmd=False) print("GP HfSims Completed".center(80, '-'))
def run(self): """ Runs Genslip """ print("GP Rupture Generator GenSlip".center(80, '-')) # Load configuration, set sim_id install = InstallCfg.getInstance() sim_id = self.sim_id # Build directory paths a_tmpdir = os.path.join(install.A_TMP_DATA_DIR, str(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_logdir = os.path.join(install.A_OUT_LOG_DIR, str(sim_id)) # Make sure the output and tmp directories exist bband_utils.mkdirs([a_tmpdir, a_indir, a_outdir], print_cmd=False) # Now, file paths self.log = os.path.join(a_logdir, "%d.genslip.log" % (sim_id)) a_srcfile = os.path.join(a_indir, self.r_srcfile) a_velfile = os.path.join(a_indir, self.r_velmodel) # Read src file cfg = GenslipCfg(a_srcfile) # Define location of input velocity model file a_velmodel = os.path.join(a_tmpdir, self.r_velmodel) # Get pointer to the velocity model object vel_obj = velocity_models.get_velocity_model_by_name(self.vmodel_name) if vel_obj is None: raise bband_utils.ParameterError("Cannot find velocity model: %s" % (self.vmodel_name)) # Check for velocity model-specific parameters vmodel_params = vel_obj.get_codebase_params('gp') # Look for RISETIME_COEF if 'RISETIME_COEF' in vmodel_params: self.risetime_coef = float(vmodel_params['RISETIME_COEF']) else: self.risetime_coef = cfg.RISETIME_COEF # Look for SHAL_VRUP if 'SHAL_VRUP' in vmodel_params: self.shal_vrup = float(vmodel_params['SHAL_VRUP']) else: self.shal_vrup = cfg.SHAL_VRUP # Look for MEAN_RVFAC if 'MEAN_RVFAC' in vmodel_params: self.mean_rvfac = float(vmodel_params['MEAN_RVFAC']) else: self.mean_rvfac = cfg.MEAN_RVFAC # Look for RANGE_RVFAC if 'RANGE_RVFAC' in vmodel_params: self.range_rvfac = float(vmodel_params['RANGE_RVFAC']) else: self.range_rvfac = cfg.RANGE_RVFAC # Look for RISETIME_FAC if 'RISETIME_FAC' in vmodel_params: self.risetime_fac = float(vmodel_params['RISETIME_FAC']) else: self.risetime_fac = cfg.RISETIME_FAC # Look for DEEP_RISETIME_FAC if 'DEEP_RISETIME_FAC' in vmodel_params: self.deep_risetime_fac = float(vmodel_params['DEEP_RISETIME_FAC']) else: self.deep_risetime_fac = cfg.DEEP_RISETIME_FAC # Look for SLIP SIGMA if 'SLIP_SIGMA' in vmodel_params: self.slip_sigma = float(vmodel_params['SLIP_SIGMA']) else: self.slip_sigma = cfg.SLIP_SIGMA # Look for DT if 'GF_DT' in vmodel_params: gf_dt = float(vmodel_params['GF_DT']) else: raise bband_utils.ParameterError("Cannot find GF_DT parameter in" "velocity model %s!" % (self.vmodel_name)) # Calculate nstk,ndip nstk = round(cfg.CFGDICT["fault_length"] / cfg.CFGDICT["dlen"]) ndip = round(cfg.CFGDICT["fault_width"] / cfg.CFGDICT["dwid"]) # Calculate rvfac if "common_seed" in cfg.CFGDICT: rvfac = calculate_rvfac(self.mean_rvfac, self.range_rvfac, cfg.CFGDICT["common_seed"]) else: rvfac = calculate_rvfac(self.mean_rvfac, self.range_rvfac, cfg.CFGDICT["seed"]) # moment = math.pow(10, 1.5 * (cfg.MAG + 10.7)) # For multi-segment SRC files if "rupture_delay" in cfg.CFGDICT: rupture_delay = cfg.CFGDICT["rupture_delay"] else: rupture_delay = 0.0 if "moment_fraction" in cfg.CFGDICT: moment_fraction = cfg.CFGDICT["moment_fraction"] else: moment_fraction = -1.0 if "max_fault_length" in cfg.CFGDICT: flen_max = cfg.CFGDICT["max_fault_length"] else: flen_max = -1.0 r_gsftmp = "m%.2f-%.2fx%.2f.gsf" % ( cfg.CFGDICT["magnitude"], cfg.CFGDICT["dlen"], cfg.CFGDICT["dwid"]) a_gsftmp = os.path.join(a_tmpdir, r_gsftmp) r_outroot = "m%.2f-%.2fx%.2f_s%d-v5.2.2" % ( cfg.CFGDICT["magnitude"], cfg.CFGDICT["dlen"], cfg.CFGDICT["dwid"], cfg.CFGDICT["seed"]) a_srffile = os.path.join(a_indir, "%s.srf" % (r_outroot)) progstring = ( "%s/fault_seg2gsf read_slip_vals=0 << EOF > %s 2>> %s\n" % (install.A_GP_BIN_DIR, a_gsftmp, self.log) + "1\n" + "%f %f %f %f %f %f %f %f %d %d\n" % (cfg.CFGDICT["lon_top_center"], cfg.CFGDICT["lat_top_center"], cfg.CFGDICT["depth_to_top"], cfg.CFGDICT["strike"], cfg. CFGDICT["dip"], cfg.CFGDICT["rake"], cfg.CFGDICT["fault_length"], cfg.CFGDICT["fault_width"], nstk, ndip) + "EOF") bband_utils.runprog(progstring) progstring = ("%s/genslip-v5.2.2 read_erf=0 write_srf=1 " % (install.A_GP_BIN_DIR) + "read_gsf=1 write_gsf=0 infile=%s " % (a_gsftmp) + "mag=%.2f nstk=%d ndip=%d " % (cfg.CFGDICT["magnitude"], nstk, ndip) + "ns=1 nh=1 " + "kmodel=2 seed=%d slip_sigma=%f " % (cfg.CFGDICT["seed"], self.slip_sigma) + "circular_average=0 modified_corners=0 " + "velfile=%s shypo=%f dhypo=%f rvfrac=%f " % (a_velfile, cfg.CFGDICT["hypo_along_stk"], cfg.CFGDICT["hypo_down_dip"], rvfac) + "shal_vrup_dep=%f shal_vrup_deprange=%f shal_vrup=%f " % (cfg.RTDEP, cfg.RTDEP_RANGE, self.shal_vrup) + "side_taper=0.02 bot_taper=0.0 top_taper=0.0 " + "dt=%f risetime_coef=%f plane_header=1 " % (gf_dt, self.risetime_coef) + "risetimefac=%f risetimedep=%f risetimedep_range=%f " % (self.risetime_fac, cfg.RTDEP, cfg.RTDEP_RANGE) + "rt_scalefac=%f slip_water_level=%f " % (cfg.RT_SCALEFAC, cfg.SLIP_WATER_LEVEL) + "deep_risetimedep=%f deep_risetimedep_range=%f " % (cfg.DEEP_RISETIMEDEP, cfg.DEEP_RISETIMEDEP_RANGE) + "deep_risetimefac=%f " % (self.deep_risetime_fac) + "flen_max=%f rupture_delay=%f moment_fraction=%f " % (flen_max, rupture_delay, moment_fraction) + "srf_version=2.0 rake_sigma=15.0 fdrup_time=1 " + "deep_vrup=0.6 use_gaus=1 alpha_rough=0.01 " + "lambda_min=0.08 tsfac_coef=1.1 tsfac1_sigma=1.0 " + "tsfac1_scor=0.8 rtime1_sigma=0.85 rtime1_scor=0.8 " + "> %s 2>> %s" % (a_srffile, self.log)) bband_utils.runprog(progstring) # # mv result to outputfile # progstring = "cp %s %s" % (a_srffile, os.path.join(a_tmpdir, self.r_srffile)) bband_utils.runprog(progstring) progstring = "cp %s %s" % (a_srffile, os.path.join(a_indir, self.r_srffile)) bband_utils.runprog(progstring) progstring = "cp %s %s" % (a_srffile, os.path.join(a_outdir, self.r_srffile)) bband_utils.runprog(progstring) # Plot SRF plot_srf.run(self.r_srffile, sim_id=self.sim_id) print("GP GenSlip Completed".center(80, '-'))
def run(self): """ This function prepares the parameter file for CSM, invokes it, and formats its output to be compatible with the Broadband Platform """ print("UNR CSM".center(80, '-')) self.install = InstallCfg.getInstance() install = self.install sim_id = self.sim_id # Get pointer to the velocity model object vel_obj = velocity_models.get_velocity_model_by_name(self.vmodel_name) if vel_obj is None: raise bband_utils.ParameterError("Cannot find velocity model: %s" % (self.vmodel_name)) vmodel_params = vel_obj.get_codebase_params('csm') if 'SDROP' in vmodel_params: sdrp = float(vmodel_params['SDROP']) else: sdrp = None # Find validation object if this is a validation run if self.val_name is not None: self.val_obj = validation_cfg.VE_EVENTS.get_event_by_name(self.val_name) sta_base = os.path.basename(os.path.splitext(self.r_stations)[0]) self.log = os.path.join(install.A_OUT_LOG_DIR, str(sim_id), "%d.csm_%s.log" % (sim_id, sta_base)) a_indir = os.path.join(install.A_IN_DATA_DIR, str(sim_id)) a_tmpdir = os.path.join(install.A_TMP_DATA_DIR, str(sim_id)) a_tmpdir_mod = os.path.join(install.A_TMP_DATA_DIR, str(sim_id), "csm_%s" % (sta_base)) a_outdir = os.path.join(install.A_OUT_DATA_DIR, str(sim_id)) # # Make sure the output and two tmp directories exist # bband_utils.mkdirs([a_tmpdir, a_tmpdir_mod, a_outdir], print_cmd=False) a_velmodel = os.path.join(a_indir, self.r_velmodel) a_stations = os.path.join(a_indir, self.r_stations) self.stat_list = StationList(a_stations) self.num_stations = len(self.stat_list.site_list) self.csm_dir = a_tmpdir_mod # Read input files, calculate CSM parameters self.config = CSMCfg(os.path.join(install.A_IN_DATA_DIR, str(sim_id), self.r_srcfile)) self.config.calculate_params(a_velmodel, sdrp) # Create CSM station list self.create_station_list() # Create mod files self.create_mod_files() # Create Simula's station list self.create_simula_stations() # Create nuclear.in file self.create_nuclear_in() # Create simula.in file self.create_simula_in() # Create the random number file needed by Simula self.create_simula_random() # Create scat1d.in file self.create_scat1d_in() # Create compom.in file self.create_compom_in() # Create csevents01.dat file self.create_csevents() # Run in tmpdir subdir to isolate temp fortran files # Save cwd, change back to it at the end old_cwd = os.getcwd() os.chdir(a_tmpdir_mod) # Calculate the Greens Functions csm_gf_bin = os.path.join(install.A_UNR_BIN_DIR, "green_99v8") cmd = ("%s >> %s 2>&1" % (csm_gf_bin, self.log)) bband_utils.runprog(cmd, abort_on_error=True) # Now, generate the simulations csm_sim_bin = os.path.join(install.A_UNR_BIN_DIR, "simula") cmd = ("%s >> %s 2>&1" % (csm_sim_bin, self.log)) bband_utils.runprog(cmd, abort_on_error=True) # Restore working directory os.chdir(old_cwd) # Need to copy and re-format output seismograms self.process_seismograms() print("UNR CSM Completed".center(80, '-'))
def run(self): """ Runs the match module to merge low and high frequency seismograms """ print("Match".center(80, '-')) install = InstallCfg.getInstance() config = MatchCfg() sim_id = self.sim_id sta_base = os.path.basename(os.path.splitext(self.r_stations)[0]) self.log = os.path.join(install.A_OUT_LOG_DIR, str(sim_id), "%d.match_%s.log" % (sim_id, sta_base)) a_statfile = os.path.join(install.A_IN_DATA_DIR, str(sim_id), self.r_stations) a_tmpdir = os.path.join(install.A_TMP_DATA_DIR, str(sim_id)) a_outdir = os.path.join(install.A_OUT_DATA_DIR, str(sim_id)) # Make sure tmpdir exists dirs = [a_tmpdir] bband_utils.mkdirs(dirs, print_cmd=False) pow2_param = 0 if self.pow2: pow2_param = 1 # Start with defaults self.phase = config.PHASE self.hf_fhi = config.HF_FHI self.lf_flo = config.LF_FLO # Set match method if config.MATCH_METHOD == 1: self.phase = 1 elif config.MATCH_METHOD == 2: val = 1.0 / (2.0 * config.HF_ORD) self.hf_fhi = (self.hf_fhi * math.exp(val * math.log(math.sqrt(2.0) - 1.0))) val = -1.0 / (2.0 * config.LF_ORD) self.lf_flo = (self.lf_flo * math.exp(val * math.log(math.sqrt(2.0) - 1.0))) # # Read and parse the station list with this call # slo = StationList(a_statfile) site_list = slo.getStationList() # Get pointer to the velocity model object vel_obj = velocity_models.get_velocity_model_by_name(self.vmodel_name) if vel_obj is None: raise bband_utils.ParameterError("Cannot find velocity model: %s" % (self.vmodel_name)) # Check for velocity model-specific parameters vmodel_params = vel_obj.get_codebase_params('gp') # Figure out what DT we should use when resampling # Figure out the LF DT value if self.acc: seis_ext = '.acc.bbp' else: seis_ext = '.bbp' lf_seis = None hf_seis = None # Find one LF seismogram and one HF seismogram for sites in site_list: site = sites.scode if os.path.exists( os.path.join(a_tmpdir, "%d.%s-lf%s" % (sim_id, site, seis_ext))): lf_seis = os.path.join(a_tmpdir, "%d.%s-lf%s" % (sim_id, site, seis_ext)) if os.path.exists( os.path.join(a_tmpdir, "%d.%s-hf%s" % (sim_id, site, seis_ext))): hf_seis = os.path.join( a_tmpdir, "%d.%s-hf%s" % (sim_id, site, seis_ext)) break # Need one of each if lf_seis is None: raise bband_utils.ParameterError("Cannot find a LF seismogram") if hf_seis is None: raise bband_utils.ParameterError("Cannot find a HF seismogram") # Pick DT from these files lf_dt = None lf_file = open(lf_seis) for line in lf_file: line = line.strip() if line.startswith("#") or line.startswith("%"): continue # Got to first timestamp. Now, pick two consecutive # timestamps values lf_t1 = float(line.strip().split()[0]) lf_t2 = float(lf_file.next().strip().split()[0]) # Subtract the two times lf_dt = lf_t2 - lf_t1 # All done! break lf_file.close() if lf_dt is None: raise bband_utils.ParameterError("Cannot find LF_DT!") hf_dt = None hf_file = open(hf_seis) for line in hf_file: line = line.strip() if line.startswith("#") or line.startswith("%"): continue # Got to first timestamp. Now, pick two consecutive # timestamps values hf_t1 = float(line.strip().split()[0]) hf_t2 = float(hf_file.next().strip().split()[0]) # Subtract the two times hf_dt = hf_t2 - hf_t1 # All done! break hf_file.close() if hf_dt is None: raise bband_utils.ParameterError("Cannot find HF_DT!") # In the GP method, we can potentially have two independent DT # values, one used by the rupture generator and the # low-frequency jbsim seismogram simulator, and another value # used by the high-frequency hfsims program. We have to use # the smaller of these two values in order to properly combine # the low-, and high-frequency seismograms. new_dt = min(lf_dt, hf_dt) # Go through the stations for sites in site_list: # Pick station name site = sites.scode # # We have a verbose of silent invocation. This is a very # verbose program so our default writes to dev/null # # # There are multiple possibilities; either we have # separate HF and LF files, we have HF and .bbp, LF and # .bbp, or just .bbp. In all cases, we need to separate # them to get components. # hf_exists = False lf_exists = False if not self.acc: print("==> Processing velocity seismograms for station: %s" % (site)) # Need to convert to acc first if os.path.exists( os.path.join(a_tmpdir, "%d.%s-hf.bbp" % (sim_id, site))): hf_exists = True if os.path.exists( os.path.join(a_tmpdir, "%d.%s-lf.bbp" % (sim_id, site))): lf_exists = True # If no files exist for this station, make a note and continue if not hf_exists and not lf_exists: print("===> No velocity seismograms found!") print("===> Skipping station...") continue # First process HF files to convert velocity to acceleration # Create path names and check if their sizes are # within bounds nsfile = os.path.join(a_tmpdir, "%d.%s-hf.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s-hf.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s-hf.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s-hf.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) # Run wcc2bbp cmd = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "wcc2bbp=0 < %s >> %s 2>&1" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) for comp in config.COMPS: # Create path names and check if their sizes # are within bounds filein = os.path.join(a_tmpdir, "%d.%s-hf.%s" % (sim_id, site, comp)) fileout = os.path.join( a_tmpdir, "%d.%s-hf.acc.%s" % (sim_id, site, comp)) bband_utils.check_path_lengths([filein, fileout], bband_utils.GP_MAX_FILENAME) cmd = ("%s diff=1 " % (os.path.join(install.A_GP_BIN_DIR, "integ_diff")) + "filein=%s fileout=%s" % (filein, fileout)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) cmd = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "units=cm/s/s wcc2bbp=1 > %s 2>> %s" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) # Then process LF files to convert velocity to acceleration # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s-lf.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s-lf.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s-lf.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s-lf.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) cmd = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "wcc2bbp=0 < %s >> %s 2>&1" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) for comp in config.COMPS: # Create path names and check if their sizes # are within bounds filein = os.path.join(a_tmpdir, "%d.%s-lf.%s" % (sim_id, site, comp)) fileout = os.path.join( a_tmpdir, "%d.%s-lf.acc.%s" % (sim_id, site, comp)) bband_utils.check_path_lengths([filein, fileout], bband_utils.GP_MAX_FILENAME) cmd = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "integ_diff")) + "diff=1 filein=%s fileout=%s" % (filein, fileout)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) cmd = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "units=cm/s/s wcc2bbp=1 > %s 2>> %s" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) # We should have acceleration files at this point hf_exists = False lf_exists = False if os.path.exists( os.path.join(a_tmpdir, "%d.%s-hf.acc.bbp" % (sim_id, site))): hf_exists = True if os.path.exists( os.path.join(a_tmpdir, "%d.%s-lf.acc.bbp" % (sim_id, site))): lf_exists = True print("==> Processing acceleration seismograms for station: %s" % (site)) # If no files exist for this station, make a note and continue if not hf_exists and not lf_exists: print("===> No acceleration seismograms found!") print("===> Skipping station...") continue # # Convert HF file to wcc components # # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s-hf.acc.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) progstring = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "wcc2bbp=0 < %s >> %s 2>&1" % (bbpfile, self.log)) bband_utils.runprog(progstring, abort_on_error=True, print_cmd=False) # # Convert LF file to wcc components # # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s-lf.acc.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) progstring = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "wcc2bbp=0 < %s >> %s 2>&1" % (bbpfile, self.log)) bband_utils.runprog(progstring, abort_on_error=True, print_cmd=False) # # Process each component # for entries in config.COMPS: compo = entries # # HF First # listfile = os.path.join( a_tmpdir, "%s.%s.hf.%s" % (config.FILTLIST, sta_base, compo)) bband_utils.check_path_lengths([listfile], bband_utils.GP_MAX_FILENAME) # Create wcc_tfilter input file out = open(listfile, 'w') # Contains HF input file infile = os.path.join( a_tmpdir, "%d.%s-hf.acc.%s" % (sim_id, site, compo)) out.write("%s\n" % infile) out.flush() out.close() # Also check infile bband_utils.check_path_lengths([infile], bband_utils.GP_MAX_FILENAME) # # Pre-filter and resample HF file # shutil.copy2(infile, "%s.prefilter" % infile) progstring = ( "%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc_tfilter")) + "filelist=%s order=%d fhi=%f flo=%s " % (listfile, config.HF_ORD, self.hf_fhi, config.HF_FLO) + "inbin=0 outbin=0 phase=%d " % (self.phase) + "outpath=%s >> %s 2>&1" % (a_tmpdir, self.log)) bband_utils.runprog(progstring, abort_on_error=True, print_cmd=False) outfile = os.path.join( a_tmpdir, "%d.%s-hf-resamp.%s" % (sim_id, site, compo)) bband_utils.check_path_lengths([outfile], bband_utils.GP_MAX_FILENAME) progstring = ("%s newdt=%f " % (os.path.join( install.A_GP_BIN_DIR, "wcc_resamp_arbdt"), new_dt) + "pow2=%d infile=%s outfile=%s >> %s 2>&1" % (pow2_param, infile, outfile, self.log)) bband_utils.runprog(progstring, abort_on_error=True, print_cmd=False) # # LF Next # listfile = os.path.join( a_tmpdir, "%s.%s.lf.%s" % (config.FILTLIST, sta_base, compo)) bband_utils.check_path_lengths([listfile], bband_utils.GP_MAX_FILENAME) # Create wcc_tfilter input file out = open(listfile, 'w') # Contains LF input file infile = os.path.join( a_tmpdir, "%d.%s-lf.acc.%s" % (sim_id, site, compo)) out.write("%s\n" % infile) out.flush() out.close() # Also check infile bband_utils.check_path_lengths([infile], bband_utils.GP_MAX_FILENAME) # # Pre-filter and resample LF file # shutil.copy2(infile, "%s.prefilter" % infile) progstring = ( "%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc_tfilter")) + "filelist=%s order=%d fhi=%f flo=%s " % (listfile, config.LF_ORD, config.LF_FHI, self.lf_flo) + "inbin=0 outbin=0 phase=%d " % (self.phase) + "outpath=%s >> %s 2>&1 " % (a_tmpdir, self.log)) bband_utils.runprog(progstring, print_cmd=False) outfile = os.path.join( a_tmpdir, "%d.%s-lf-resamp.%s" % (sim_id, site, compo)) bband_utils.check_path_lengths([outfile], bband_utils.GP_MAX_FILENAME) progstring = ( "%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc_resamp_arbdt")) + "newdt=%f pow2=%d " % (new_dt, pow2_param) + "infile=%s outfile=%s >> %s 2>&1" % (infile, outfile, self.log)) bband_utils.runprog(progstring, abort_on_error=True, print_cmd=False) # # Add LF and HF resampled acc seismograms # # Check all path lengths infile1 = os.path.join( a_tmpdir, "%d.%s-lf-resamp.%s" % (sim_id, site, compo)) infile2 = os.path.join( a_tmpdir, "%d.%s-hf-resamp.%s" % (sim_id, site, compo)) outfile = os.path.join( a_tmpdir, "%d.%s.acc.add.%s" % (sim_id, site, compo)) bband_utils.check_path_lengths([infile1, infile2, outfile], bband_utils.GP_MAX_FILENAME) progstring = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc_add")) + "f1=1.00 t1=%f inbin1=0 infile1=%s " % (config.LF_TSTART, infile1) + "f2=1.00 t2=%f inbin2=0 infile2=%s " % (config.HF_TSTART, infile2) + "outbin=0 outfile=%s >> %s 2>&1" % (outfile, self.log)) bband_utils.runprog(progstring, abort_on_error=True, print_cmd=False) # # Create combined velocity files # # Check path lengths filein = os.path.join( a_tmpdir, "%d.%s.acc.add.%s" % (sim_id, site, compo)) fileout = os.path.join(a_tmpdir, "%d.%s.%s" % (sim_id, site, compo)) bband_utils.check_path_lengths([filein, fileout], bband_utils.GP_MAX_FILENAME) cmd = ("%s integ=1 filein=%s fileout=%s" % (os.path.join( install.A_GP_BIN_DIR, "integ_diff"), filein, fileout)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) # We have all the component files, create velocity seismogram # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) progstring = ("%s wcc2bbp=1 " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + 'title="Sim NGAH, stat=%s" ' % site + 'nsfile=%s ewfile=%s udfile=%s > %s 2>> %s' % (nsfile, ewfile, udfile, bbpfile, self.log)) bband_utils.runprog(progstring, abort_on_error=True, print_cmd=False) # Copy velocity bbp file to outdir shutil.copy2( os.path.join(a_tmpdir, "%d.%s.bbp" % (sim_id, site)), os.path.join(a_outdir, "%d.%s.vel.bbp" % (sim_id, site))) # Also create acceleration bbp file in outdir # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) cmd = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "wcc2bbp=0 < %s >> %s 2>&1" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) for comp in config.COMPS: # Create path names and check if their sizes are within bounds filein = os.path.join(a_tmpdir, "%d.%s.%s" % (sim_id, site, comp)) fileout = os.path.join(a_tmpdir, "%d.%s.acc.%s" % (sim_id, site, comp)) bband_utils.check_path_lengths([filein, fileout], bband_utils.GP_MAX_FILENAME) cmd = ("%s diff=1 filein=%s fileout=%s" % (os.path.join( install.A_GP_BIN_DIR, "integ_diff"), filein, fileout)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) # Create path names and check if their sizes are within bounds nsfile = os.path.join(a_tmpdir, "%d.%s.acc.000" % (sim_id, site)) ewfile = os.path.join(a_tmpdir, "%d.%s.acc.090" % (sim_id, site)) udfile = os.path.join(a_tmpdir, "%d.%s.acc.ver" % (sim_id, site)) bbpfile = os.path.join(a_tmpdir, "%d.%s.acc.bbp" % (sim_id, site)) bband_utils.check_path_lengths([nsfile, ewfile, udfile], bband_utils.GP_MAX_FILENAME) cmd = ("%s " % (os.path.join(install.A_GP_BIN_DIR, "wcc2bbp")) + "nsfile=%s ewfile=%s udfile=%s " % (nsfile, ewfile, udfile) + "units=cm/s/s wcc2bbp=1 > %s 2>> %s" % (bbpfile, self.log)) bband_utils.runprog(cmd, abort_on_error=True, print_cmd=False) # Copy acceleration bbp file to outdir shutil.copy2( os.path.join(a_tmpdir, "%d.%s.acc.bbp" % (sim_id, site)), os.path.join(a_outdir, "%d.%s.acc.bbp" % (sim_id, site))) print("Match Completed".center(80, '-'))
def create_exsim_param_file(self): """ This function creates the parameter file needed by ExSim """ sta_base = os.path.basename(os.path.splitext(self.r_stations)[0]) a_indir = os.path.join(self.install.A_IN_DATA_DIR, str(self.sim_id)) a_tmpdir_mod = os.path.join(self.install.A_TMP_DATA_DIR, str(self.sim_id), "exsim_%s" % (sta_base)) a_param_template = os.path.join(a_indir, self.r_param_template) a_param_out = os.path.join(a_tmpdir_mod, self.config.PARAM_FILE) output_stem = "exsim-output-%s" % (sta_base) # Get pointer to the velocity model object vel_obj = velocity_models.get_velocity_model_by_name(self.vmodel_name) if vel_obj is None: raise bband_utils.ParameterError("Cannot find velocity model: %s" % (self.vmodel_name)) vmodel_params = vel_obj.get_codebase_params('exsim') # Look for additional files needed by ExSim if 'CRUSTAL_AMP' in vmodel_params: self.crustal_amp = os.path.join(vel_obj.base_dir, vmodel_params['CRUSTAL_AMP']) else: raise bband_utils.ParameterError("Cannot find crustal_amp " "parameter in velocity " "model %s" % (self.vmodel_name)) if 'SITE_AMP' in vmodel_params: self.site_amp = os.path.join(vel_obj.base_dir, vmodel_params['SITE_AMP']) else: raise bband_utils.ParameterError("Cannot find site_amp " "parameter in velocity " "model %s" % (self.vmodel_name)) if 'EMPIRICAL_DIR' in vmodel_params: self.empirical_dir = os.path.join(vel_obj.base_dir, vmodel_params['EMPIRICAL_DIR']) else: raise bband_utils.ParameterError("Cannot find empirical_dir " "parameter in velocity " "model %s" % (self.vmodel_name)) if 'EMPIRICAL_RANGES' in vmodel_params: self.empirical_ranges = os.path.join( vel_obj.base_dir, vmodel_params['EMPIRICAL_RANGES']) else: raise bband_utils.ParameterError("Cannot find empirical_ranges " "parameter in velocity " "model %s" % (self.vmodel_name)) if 'SLIP_WEIGHTS' in vmodel_params: self.slip_weights = os.path.join(vel_obj.base_dir, vmodel_params['SLIP_WEIGHTS']) else: raise bband_utils.ParameterError("Cannot find slip_weights " "parameter in velocity " "model %s" % (self.vmodel_name)) # Look for KAPPA and STRESS if 'KAPPA' in vmodel_params: self.kappa = float(vmodel_params['KAPPA']) if 'STRESS' in vmodel_params: self.stress = float(vmodel_params['STRESS']) # Check if we need to calculate stress if 'CALCULATE_STRESS' in vmodel_params: if float(vmodel_params['CALCULATE_STRESS']) == True: # Calculate stress based on depth of hypocenter self.stress = self.config.calculate_stress() # Stage these files into tmpdir_mod directory shutil.copy2(self.crustal_amp, a_tmpdir_mod) shutil.copy2(self.site_amp, a_tmpdir_mod) shutil.copy2(self.slip_weights, a_tmpdir_mod) # Now we need to figure out which empirical_amps file to use empirical_file = self.find_empirical_file() empirical_in = os.path.join(self.empirical_dir, empirical_file) empirical_out = os.path.join(a_tmpdir_mod, self.config.EMPIRICAL_AMPS) shutil.copy2(empirical_in, empirical_out) # Ok, need to write ExSim's param file now! self.template_in = open(a_param_template, 'r') self.param_out = open(a_param_out, 'w') # Replace parameters in the order they appear in ExSim's template self.template_replace(["<MAG>", "<STRESS>"], [self.config.CFGDICT['magnitude'], self.stress]) self.template_replace( ["<MAG>", "<STRESS>", "<KAPPA>"], [self.config.CFGDICT['magnitude'], self.stress, self.kappa]) self.template_replace(["<LAT>", "<LON>"], [ self.config.CFGDICT['lat_top_edge'], self.config.CFGDICT['lon_top_edge'] ]) self.template_replace(["<STRIKE>", "<DIP>", "<DEPTH>"], [ self.config.CFGDICT['strike'], self.config.CFGDICT['dip'], self.config.CFGDICT['depth_to_top'] ]) self.template_replace(["<F_LEN>", "<F_WID>"], [ self.config.CFGDICT["fault_length"], self.config.CFGDICT["fault_width"] ]) self.template_replace(["<HYPO_ALONG_STK>", "<HYPO_DOWN_DIP>"], [ self.config.CFGDICT["hypo_along_stk"], self.config.CFGDICT["hypo_down_dip"] ]) self.template_replace(["<OUTPUT_STEM>"], [output_stem]) self.template_replace(["<CRUSTAL_AMP_FILE>"], [os.path.basename(self.crustal_amp)]) self.template_replace(["<SITE_AMP_FILE>"], [os.path.basename(self.site_amp)]) self.template_replace(["<EMPIRICAL_AMP_FILE>"], [os.path.basename(self.config.EMPIRICAL_AMPS)]) self.template_replace(["<SEED>"], [int(self.config.CFGDICT['seed'])]) self.template_replace(["<SLIP_WEIGHTS_FILE>"], [os.path.basename(self.slip_weights)]) self.template_replace(["<NUM_STATIONS>"], [self.num_stations]) # Now, copy everything else! self.template_replace(["<END_OF_TEMPLATE_FILE>"], [""]) # Almost done, now we need to add stations site_list = self.stat_list.getStationList() # Check for maximum number of stations if len(site_list) > self.config.MAX_STATIONS: raise bband_utils.ParameterError("Too many stations in " "the station list: %d. " % (len(site_list)) + "Maximum limit is %d." % (self.config.MAX_STATIONS)) for site in site_list: self.param_out.write("%f %f\n" % (site.lat, site.lon)) # Done! Close files. self.template_in.close() self.param_out.close() # Make copy of ExSIM param file in input directory shutil.copy2(a_param_out, a_indir)
def load_correction_factors(self): """ This function loads the correction factors from the corr_file provided """ try: cfile = open(self.corr_file, 'r') except IOError: raise bband_utils.ParameterError("Cannot read correction file %s" % (self.corr_file)) # We are looking for the header first headers = None # Loop through the lines for line in cfile: if line.startswith("#StaName"): headers = line.split() break # Make sure we got the header line if headers is None: cfile.close() raise bband_utils.ProcessingError("Cannot find header line in " "correction file %s" % (self.corr_file)) skip_headers = 0 # Pick up the periods while len(headers) > 0: try: tmp = float(headers[0]) except: # Skip this one, and remove from list skip_headers = skip_headers + 1 headers.pop(0) else: # Found first period, get out break # Make sure we have at least 1 period if not headers: cfile.close() raise bband_utils.ProcessingError("Cannot find any periods in " "correction file %s" % (self.corr_file)) # Convert periods to floats self.periods = [float(value) for value in headers] # Now read the rest of the correction file for line in cfile: if line.startswith("#"): continue factors = line.split() station = factors[0] to_skip = skip_headers # Remove everything other than the correction factors while to_skip > 0: factors.pop(0) to_skip = to_skip - 1 factors = [float(value) for value in factors] # Make sure we have the proper number of correction factors if len(factors) != len(self.periods): cfile.close() raise bband_utils.ProcessingError("Station %s has %d periods" % (station, len(factors)) + ", expecting %s periods" % (len(self.periods))) self.factors[station] = factors # All done cfile.close()
def calculate_observations(self, a_indir, a_statfile, a_tmpdir_seis, a_dstdir): """ This function calculates RotD100/RotD50 for the observation seismograms. It corrects the observations using the user-provided correction coefficients. """ sim_id = self.sim_id slo = StationList(a_statfile) site_list = slo.getStationList() # Inialize the CorrectPSA module if self.obs_corrections: corr_psa = CorrectPSA(self.r_stations, "rd100", os.path.join(a_indir, self.obs_corrections), a_tmpdir_seis, sim_id) else: corr_psa = None # List of observed seismogram files filelist = os.listdir(self.a_obsdir) # Go through each station for site in site_list: stat = site.scode print("==> Calculating observations RotD100 for station: %s" % (stat)) # Check if we have the corresponding calculated seismogram expected_calculated_file = os.path.join( a_dstdir, "%d.%s.rd100" % (sim_id, stat)) if not os.path.exists(expected_calculated_file): # Just skip it print("Couldn't find file: %s" % (expected_calculated_file) + "This is not necessarily an error, as you may have " + "run with a subset of a stations. Continuing " + "with available stations.") continue # Ok, we have a simulated seismogram for this station, # let's look for the observed file r_e_peer_file = None r_n_peer_file = None r_z_peer_file = None r_bbp_file = "%s.bbp" % (stat) # Do different things depending on the format of the # observed seismograms if self.obs_format == "acc_bbp": # We need to look for the bbp file if r_bbp_file not in filelist: # No bbp file for this station continue print(r_bbp_file) # Copy bbp file to the tmp seismogram directory a_src_bbp_file = os.path.join(self.a_obsdir, r_bbp_file) a_dst_bbp_file = os.path.join(a_tmpdir_seis, r_bbp_file) shutil.copy2(a_src_bbp_file, a_dst_bbp_file) # Now we need to create the peer files to process with rotd50 r_e_peer_file = os.path.join(a_tmpdir_seis, "%s_E.acc" % (stat)) r_n_peer_file = os.path.join(a_tmpdir_seis, "%s_N.acc" % (stat)) r_z_peer_file = os.path.join(a_tmpdir_seis, "%s_Z.acc" % (stat)) bbp_formatter.bbp2peer(a_dst_bbp_file, r_n_peer_file, r_e_peer_file, r_z_peer_file) elif self.obs_format == "acc_peer": # Look for the E, N, and Z files for my_file in filelist: if my_file.endswith("%s_E.acc" % (stat)): r_e_peer_file = my_file if (r_n_peer_file is not None and r_z_peer_file is not None): break elif my_file.endswith("%s_N.acc" % (stat)): r_n_peer_file = my_file if (r_e_peer_file is not None and r_z_peer_file is not None): break elif my_file.endswith("%s_Z.acc" % (stat)): r_z_peer_file = my_file if (r_e_peer_file is not None and r_n_peer_file is not None): break if ((r_e_peer_file is None) or (r_n_peer_file is None) or (r_z_peer_file is None)): # Couldn't find all 3 files continue #print(r_e_peer_file, r_n_peer_file, r_z_peer_file) # Copy all three files to the tmp seismogram directory for eachfile in (r_e_peer_file, r_n_peer_file, r_z_peer_file): a_src_peer_file = os.path.join(self.a_obsdir, eachfile) a_dst_peer_file = os.path.join(a_tmpdir_seis, eachfile) shutil.copy2(a_src_peer_file, a_dst_peer_file) # Now we need to convert them into bbp format bbp_formatter.peer2bbp( os.path.join(a_tmpdir_seis, r_n_peer_file), os.path.join(a_tmpdir_seis, r_e_peer_file), os.path.join(a_tmpdir_seis, r_z_peer_file), os.path.join(a_tmpdir_seis, r_bbp_file)) else: raise bband_utils.ParameterError("Format %s for " % (self.obs_format) + "observed seismograms " "not supported") # Run RotD100 on this file if corr_psa is not None: # First calculate rd100/50 and psa5 files do_rotd100(a_tmpdir_seis, r_e_peer_file, r_n_peer_file, "%s-orig.rd100" % (stat), self.log) # Now we need to correct the RotD100/RotD50 output # using the user-supplied correction factors corr_psa.correct_station(stat, "rd100") else: # Use final names for output files do_rotd100(a_tmpdir_seis, r_e_peer_file, r_n_peer_file, "%s.rd100" % (stat), self.log) shutil.copy2(os.path.join(a_tmpdir_seis, "%s.rd100" % (stat)), os.path.join(a_dstdir, "%s.rd100" % (stat)))
def generate_src_files(numsim, source_file, srcdir, prefix, hypo_rand, variation, multiseg, segment, first_seg_dir): """ Generates num_sim source files in the srcdir using different random seeds """ src_props = bband_utils.parse_properties(source_file) # Delete "seed" and "common_seed" from the property set if "seed" in src_props: src_props.pop("seed") if "common_seed" in src_props: src_props.pop("common_seed") # Get FAULT_LENGTH and FAULT_WIDTH from the SRC file try: flen = float(src_props["fault_length"]) fwid = float(src_props["fault_width"]) except KeyError: raise bband_utils.ParameterError("Cannot read fault_length/fault_width" " parameters from SRC file!") if hypo_rand: # Delete HYPO_ALONG_STK and HYPO_DOWN_DIP if "hypo_along_stk" in src_props: src_props.pop("hypo_along_stk") if "hypo_down_dip" in src_props: src_props.pop("hypo_down_dip") # Create common list of keys for all files output = "" for key in src_props: output = output + "%s = %s\n" % (key.upper(), src_props[key]) common_seeds = [] # Check if we are doing a multi-segment run if multiseg and first_seg_dir is not None: # Read common seeds from seed file seed_file = open(os.path.join(first_seg_dir, "Src", "seeds.txt"), 'r') first_seg_sims = int(seed_file.readline().strip()) if first_seg_sims != numsim: print("ERROR: Number of simulations must match across segments!") sys.exit(1) for line in seed_file: common_seeds.append(int(line.strip())) seed_file.close() # Generate the numsim SRC files all_seeds = [] for sim in range(0, numsim): random.seed((sim + 1) + (variation - 1) * 500) seed = int(math.exp(7 * math.log(10.0)) * random.random()) all_seeds.append(seed) hypo_along_stk = flen * (0.2 + 0.6 * random.random() - 0.5) hypo_down_dip = fwid * (0.2 + 0.6 * random.random()) if multiseg: srcfile = os.path.join( srcdir, "%s-%04d_seg%02d.src" % (prefix, sim, segment)) else: srcfile = os.path.join(srcdir, "%s-%04d.src" % (prefix, sim)) outfile = open(srcfile, 'w') outfile.write(output) if hypo_rand: outfile.write("HYPO_ALONG_STK = %.2f\n" % (hypo_along_stk)) outfile.write("HYPO_DOWN_DIP = %.2f\n" % (hypo_down_dip)) outfile.write("SEED = %d\n" % (seed)) if multiseg and first_seg_dir is not None: outfile.write("COMMON_SEED = %d\n" % (common_seeds[sim])) outfile.close() # Check if we need to write file with all seeds if multiseg and first_seg_dir is None: # This is the first segment, write seeds file seed_file = open(os.path.join(srcdir, "seeds.txt"), 'w') seed_file.write("%d\n" % (numsim)) for seed in all_seeds: seed_file.write("%d\n" % (seed)) seed_file.close()
def run(self): """ This function copies the observed seismograms for the stations specified in r_stations to a temporary directory inside the tmpdata directory and converts them to the format needed by the goodness of fitness module """ print("ObsSeismograms".center(80, '-')) # Initialize basic variables install = InstallCfg.getInstance() sim_id = self.sim_id sta_base = os.path.basename(os.path.splitext(self.r_stations)[0]) self.log = os.path.join(install.A_OUT_LOG_DIR, str(sim_id), "%d.obs_seis.log" % (sim_id)) # Input, tmp, and output directories a_indir = os.path.join(install.A_IN_DATA_DIR, str(sim_id)) a_tmpdir = os.path.join(install.A_TMP_DATA_DIR, str(sim_id)) a_tmpdir_seis = os.path.join(install.A_TMP_DATA_DIR, str(sim_id), "obs_seis_%s" % (sta_base)) a_outdir = os.path.join(install.A_OUT_DATA_DIR, str(sim_id)) a_outdir_seis = os.path.join(a_outdir, "obs_seis_%s" % (sta_base)) a_outdir_gmpe = os.path.join(a_outdir, "gmpe_data_%s" % (sta_base)) # # Make sure the output and tmp directories exist # dirs = [ a_tmpdir, a_tmpdir_seis, a_outdir, a_outdir_seis, a_outdir_gmpe ] bband_utils.mkdirs(dirs, print_cmd=False) # Station file a_statfile = os.path.join(a_indir, self.r_stations) # List of observed seismogram files filelist = os.listdir(self.a_obsdir) slo = StationList(a_statfile) site_list = slo.getStationList() # Inialize the CorrectPSA module if self.obs_corrections: corr_psa = CorrectPSA(self.r_stations, "rd100", os.path.join(a_indir, self.obs_corrections), a_tmpdir_seis, sim_id) else: corr_psa = None # Go through each station for site in site_list: slon = float(site.lon) slat = float(site.lat) stat = site.scode print("==> Processing data for station: %s" % (stat)) # Look for the files we need expected_rd50_file = os.path.join(a_outdir, "%d.%s.rd50" % (sim_id, stat)) if not os.path.exists(expected_rd50_file): # just skip it print("Couldn't find file %s. " % (expected_rd50_file) + "This is not necessarily an error, as you may have " + "run with a subset of a stations. Continuing " + "with available stations.") continue # Ok, we have a calculated rd50/rd100 files for this station, # let's look for the observed file r_e_peer_file = None r_n_peer_file = None r_z_peer_file = None r_bbp_file = "%s.bbp" % (stat) # Do different things depending on the format of the # observed seismograms if self.obs_format == "acc_bbp": # We need to look for the bbp file if r_bbp_file not in filelist: # No bbp file for this station continue print("==> Converting file: %s" % (r_bbp_file)) # Copy bbp file to the tmp seismogram directory a_src_bbp_file = os.path.join(self.a_obsdir, r_bbp_file) a_dst_bbp_file = os.path.join(a_tmpdir_seis, r_bbp_file) shutil.copy2(a_src_bbp_file, a_dst_bbp_file) # Now we need to create the peer files to process with rotd50 r_e_peer_file = os.path.join(a_tmpdir_seis, "%s_E.acc" % (stat)) r_n_peer_file = os.path.join(a_tmpdir_seis, "%s_N.acc" % (stat)) r_z_peer_file = os.path.join(a_tmpdir_seis, "%s_Z.acc" % (stat)) bbp_formatter.bbp2peer(a_dst_bbp_file, r_n_peer_file, r_e_peer_file, r_z_peer_file) elif self.obs_format == "acc_peer": # Look for the E, N, and Z files for my_file in filelist: if my_file.endswith("%s_E.acc" % (stat)): r_e_peer_file = my_file if (r_n_peer_file is not None and r_z_peer_file is not None): break elif my_file.endswith("%s_N.acc" % (stat)): r_n_peer_file = my_file if (r_e_peer_file is not None and r_z_peer_file is not None): break elif my_file.endswith("%s_Z.acc" % (stat)): r_z_peer_file = my_file if (r_e_peer_file is not None and r_n_peer_file is not None): break if ((r_e_peer_file is None) or (r_n_peer_file is None) or (r_z_peer_file is None)): # Couldn't find all 3 files continue # print(r_e_peer_file, r_n_peer_file, r_z_peer_file) # Copy all three files to the tmp seismogram directory for eachfile in (r_e_peer_file, r_n_peer_file, r_z_peer_file): a_src_peer_file = os.path.join(self.a_obsdir, eachfile) a_dst_peer_file = os.path.join(a_tmpdir_seis, eachfile) shutil.copy2(a_src_peer_file, a_dst_peer_file) # Now we need to convert them into bbp format bbp_formatter.peer2bbp( os.path.join(a_tmpdir_seis, r_n_peer_file), os.path.join(a_tmpdir_seis, r_e_peer_file), os.path.join(a_tmpdir_seis, r_z_peer_file), os.path.join(a_tmpdir_seis, r_bbp_file)) elif self.obs_format == "gmpe": # GMPE verification packages don't have actual # seismograms, so there's nothing we need to do here! a_src_gmpe_file = os.path.join(a_outdir_gmpe, "%s-gmpe.ri50" % (stat)) # Create a copy in outdata averaging all gmpes a_avg_rd50_file = os.path.join(a_outdir_seis, "%s.rd50" % (stat)) gmpe_config.average_gmpe(stat, a_src_gmpe_file, a_avg_rd50_file) # All done! continue else: raise bband_utils.ParameterError("Format %s for " % (self.obs_format) + "observed seismograms " "not supported") out_rotd100_base = "%s.rd100" % (stat) out_rotd100v_base = "%s.rd100.vertical" % (stat) out_rotd50_base = "%s.rd50" % (stat) out_rotd50v_base = "%s.rd50.vertical" % (stat) # Run RotDXX on this file if corr_psa is not None: # First calculate rdXX print("===> Calculating RotDXX for station: %s" % (stat)) rotd100.do_rotd100(a_tmpdir_seis, r_e_peer_file, r_n_peer_file, "%s-orig.rd100" % (stat), self.log) #rotd100.do_rotd100(a_tmpdir_seis, r_z_peer_file, # r_z_peer_file, # "%s-orig.rd100.vertical" % (stat), self.log) # Now we need to correct the RotD100 outputs using the # user-supplied correction factors print("===> Correcting PSA for station: %s" % (stat)) corr_psa.correct_station(stat, "rd100") #corr_psa.correct_station(stat, "rd100.vertical") else: # Use final names for output files print("===> Calculating RotDXX for station: %s" % (stat)) rotd100.do_rotd100(a_tmpdir_seis, r_e_peer_file, r_n_peer_file, out_rotd100_base, self.log) #rotd100.do_rotd100(a_tmpdir_seis, r_z_peer_file, # r_z_peer_file, # out_rotd100v_base % (stat), self.log) # Create rotd50 files as well rotd100.do_split_rotd50(a_tmpdir_seis, out_rotd100_base, out_rotd50_base, self.log) #rotd100.do_split_rotd50(a_tmpdir_seis, out_rotd100v_base, # out_rotd50v_base, self.log) shutil.copy2(os.path.join(a_tmpdir_seis, out_rotd100_base), os.path.join(a_outdir_seis, out_rotd100_base)) #shutil.copy2(os.path.join(a_tmpdir_seis, out_rotd100v_base), # os.path.join(a_outdir_seis, out_rotd100v_base)) shutil.copy2(os.path.join(a_tmpdir_seis, out_rotd50_base), os.path.join(a_outdir_seis, out_rotd50_base)) #shutil.copy2(os.path.join(a_tmpdir_seis, out_rotd50v_base), # os.path.join(a_outdir_seis, out_rotd50v_base)) print("ObsSeismograms Completed".center(80, '-'))