def read_file_her(filename): """ The function is to read 10-column .her files. Return a list of psignals for each orientation. """ time, dis_ns, dis_ew, dis_up = [np.array([], float) for _ in xrange(4)] vel_ns, vel_ew, vel_up = [np.array([], float) for _ in xrange(3)] acc_ns, acc_ew, acc_up = [np.array([], float) for _ in xrange(3)] try: (time, dis_ns, dis_ew, dis_up, vel_ns, vel_ew, vel_up, acc_ns, acc_ew, acc_up) = np.loadtxt(filename, comments='#', unpack=True) except IOError: print("[ERROR]: error loading her file.") return False samples = dis_ns.size delta_t = time[1] # samples, dt, orientation, acceleration, velocity, displacement # right now the values for orientation for the her file are hardcoded here signal_ns = TimeseriesComponent(samples, delta_t, 0.0, acc_ns, vel_ns, dis_ns) signal_ew = TimeseriesComponent(samples, delta_t, 90.0, acc_ew, vel_ew, dis_ew) signal_up = TimeseriesComponent(samples, delta_t, "UP", acc_up, vel_up, dis_up) station = [signal_ns, signal_ew, signal_up] return station
def read_file_bbp(filename): """ This function reads timeseries data from a set of BBP files """ # Get filenames for displacement, velocity and acceleration bbp files work_dir = os.path.dirname(filename) base_file = os.path.basename(filename) base_tokens = base_file.split('.')[0:-2] if not base_tokens: print("[ERROR]: Invalid BBP filename: %s" % (filename)) sys.exit(1) dis_tokens = list(base_tokens) vel_tokens = list(base_tokens) acc_tokens = list(base_tokens) dis_tokens.append('dis') vel_tokens.append('vel') acc_tokens.append('acc') dis_tokens.append('bbp') vel_tokens.append('bbp') acc_tokens.append('bbp') dis_file = os.path.join(work_dir, '.'.join(dis_tokens)) vel_file = os.path.join(work_dir, '.'.join(vel_tokens)) acc_file = os.path.join(work_dir, '.'.join(acc_tokens)) # Read 3 bbp files [time, dis_h1, dis_h2, dis_ver] = read_file_bbp2(dis_file) [_, vel_h1, vel_h2, vel_ver] = read_file_bbp2(vel_file) [_, acc_h1, acc_h2, acc_ver] = read_file_bbp2(acc_file) # Read orientation from one of the files orientation = read_orientation_bbp(vel_file) # Read padding information from one of the files padding = read_padding_bbp(vel_file) samples = dis_h1.size delta_t = time[1] # samples, dt, data, acceleration, velocity, displacement signal_h1 = TimeseriesComponent(samples, delta_t, orientation[0], acc_h1, vel_h1, dis_h1, padding=padding) signal_h2 = TimeseriesComponent(samples, delta_t, orientation[1], acc_h2, vel_h2, dis_h2, padding=padding) signal_ver = TimeseriesComponent(samples, delta_t, orientation[2], acc_ver, vel_ver, dis_ver, padding=padding) station = [signal_h1, signal_h2, signal_ver] return station
def read_rwg_obs_data(input_file): """ Reads and processes a RWG observation file """ record_list = [] # Read file print("[READING]: %s..." % (input_file)) # First, read the headers headers = [] try: bbp_file = open(input_file, 'r') for line in bbp_file: line = line.strip() if line.startswith('#') or line.startswith('%'): headers.append(line) bbp_file.close() except IOError: print("[ERROR]: error reading bbp file: %s" % (input_file)) sys.exit(1) # Now read the data [times, vel_h1, vel_h2, vel_ver] = read_file_bbp2(input_file) for data, orientation in zip([vel_h1, vel_h2, vel_ver], [0.0, 90.0, 'up']): # Get network code and station id basefile = os.path.splitext(os.path.basename(input_file))[0] tokens = basefile.split("_") network = tokens[0].upper() station_id = tokens[1].upper() # Get location's latitude and longitude latitude = "N/A" longitude = "N/A" for line in headers: if "lon=" in line: longitude = float(line.split()[2]) if "lat=" in line: latitude = float(line.split()[2]) # Get filtering information high_pass = 0.1 low_pass = 5.0 date = '00/00/00' hour = '00' minute = '00' seconds = '00' fraction = '0' tzone = '---' # Put it all together time = "%s:%s:%s.%s %s" % (hour, minute, seconds, fraction, tzone) # Get number of samples and dt samples = data.size delta_t = times[1] - times[0] acc_data = data vel_data = integrate(acc_data, delta_t) dis_data = integrate(vel_data, delta_t) print("[PROCESSING]: Found component: %s" % (orientation)) record_list.append(TimeseriesComponent(samples, delta_t, orientation, acc_data, vel_data, dis_data)) station_metadata = {} station_metadata['network'] = network station_metadata['station_id'] = station_id station_metadata['type'] = "RWGOBS" station_metadata['date'] = date station_metadata['time'] = time station_metadata['longitude'] = longitude station_metadata['latitude'] = latitude station_metadata['high_pass'] = high_pass station_metadata['low_pass'] = low_pass return record_list, station_metadata
def her2bbp_main(): """ Main function for her to bbp converter """ parser = argparse.ArgumentParser(description="Converts a Hercules .her" "file to BBP format, generating " "displacement, velocity and acceleration " "BBP files.") parser.add_argument("-s", "--station-name", dest="station_name", default="NoName", help="provides the name for this station") parser.add_argument("--lat", dest="latitude", type=float, default=0.0, help="provides the latitude for the station") parser.add_argument("--lon", dest="longitude", type=float, default=0.0, help="provides the longitude for the station") parser.add_argument("-t", "--time", default="00/00/00,0:0:0.0 UTC", help="provides timing information for this timeseries") parser.add_argument("-o", "--orientation", default="0,90,UP", dest="orientation", help="orientation, default: 0,90,UP") parser.add_argument("--azimuth", type=float, dest="azimuth", help="azimuth for rotation (degrees)") parser.add_argument("input_file", help="Hercules input timeseries") parser.add_argument("output_stem", help="output BBP filename stem without the " " .{dis,vel,acc}.bbp extensions") parser.add_argument("-d", dest="output_dir", default="", help="output directory for the BBP file") args = parser.parse_args() # Check orientation orientation = args.orientation.split(",") if len(orientation) != 3: print("[ERROR]: Need to specify orientation for all 3 components!") sys.exit(-1) orientation[0] = float(orientation[0]) orientation[1] = float(orientation[1]) orientation[2] = orientation[2].lower() if orientation[2] != "up" and orientation[2] != "down": print("[ERROR]: Vertical orientation must be up or down!") sys.exit(-1) input_file = args.input_file output_file_dis = "%s.dis.bbp" % (os.path.join(args.output_dir, args.output_stem)) output_file_vel = "%s.vel.bbp" % (os.path.join(args.output_dir, args.output_stem)) output_file_acc = "%s.acc.bbp" % (os.path.join(args.output_dir, args.output_stem)) # Try to get the units used in the her file units = {"m": ["m", "m/s", "m/s^2"], "cm": ["cm", "cm/s", "cm/s^2"]} unit = parse_her_header(input_file) # Covert from her to BBP format print("[INFO]: Reading file %s ..." % (os.path.basename(input_file))) (headers, delta_t, times, acc_h1, acc_h2, acc_ver, vel_h1, vel_h2, vel_ver, dis_h1, dis_h2, dis_ver) = read_hercules(input_file) # Create station data structures samples = vel_h1.size # samples, dt, data, acceleration, velocity, displacement signal_h1 = TimeseriesComponent(samples, delta_t, orientation[0], acc_h1, vel_h1, dis_h1) signal_h2 = TimeseriesComponent(samples, delta_t, orientation[1], acc_h2, vel_h2, dis_h2) signal_ver = TimeseriesComponent(samples, delta_t, orientation[2], acc_ver, vel_ver, dis_ver) station = [signal_h1, signal_h2, signal_ver] # Rotate timeseries if needed if args.azimuth is not None: print("[INFO]: Rotating timeseries - %f degrees" % (args.azimuth)) station = rotate_timeseries(station, args.azimuth) # Update orientation after rotation so headers reflect any changes args.orientation = "%s,%s,%s" % (str( station[0].orientation), str( station[1].orientation), str(station[2].orientation)) # Pull data back acc_h1 = station[0].acc.tolist() vel_h1 = station[0].vel.tolist() dis_h1 = station[0].dis.tolist() acc_h2 = station[1].acc.tolist() vel_h2 = station[1].vel.tolist() dis_h2 = station[1].dis.tolist() acc_ver = station[2].acc.tolist() vel_ver = station[2].vel.tolist() dis_ver = station[2].dis.tolist() o_dis_file = open(output_file_dis, 'w') o_vel_file = open(output_file_vel, 'w') o_acc_file = open(output_file_acc, 'w') write_bbp_header(o_dis_file, "displacement", units[unit][0], args) write_bbp_header(o_vel_file, "velocity", units[unit][1], args) write_bbp_header(o_acc_file, "acceleration", units[unit][2], args) # Write headers from original Hercules file dis_header = headers[0] vel_header = headers[1] acc_header = headers[2] for line in dis_header: o_dis_file.write(line) for line in vel_header: o_vel_file.write(line) for line in acc_header: o_acc_file.write(line) # Write files for (time, disp_h1, disp_h2, disp_ver, velo_h1, velo_h2, velo_ver, accel_h1, accel_h2, accel_ver) in zip(times, dis_h1, dis_h2, dis_ver, vel_h1, vel_h2, vel_ver, acc_h1, acc_h2, acc_ver): o_dis_file.write("%1.9E %1.9E %1.9E %1.9E\n" % (time, disp_h1, disp_h2, disp_ver)) o_vel_file.write("%1.9E %1.9E %1.9E %1.9E\n" % (time, velo_h1, velo_h2, velo_ver)) o_acc_file.write("%1.9E %1.9E %1.9E %1.9E\n" % (time, accel_h1, accel_h2, accel_ver)) # All done o_dis_file.close() o_vel_file.close() o_acc_file.close()
def edge2bbp_main(): """ Script to convert RWG files to BBP format """ parser = argparse.ArgumentParser(description="Converts an EDGE " "file to BBP format, generating " "displacement, velocity and acceleration " "BBP files.") parser.add_argument("-s", "--station-name", dest="station_name", default="NoName", help="provides the name for this station") parser.add_argument("--lat", dest="latitude", type=float, default=0.0, help="provides the latitude for the station") parser.add_argument("--lon", dest="longitude", type=float, default=0.0, help="provides the longitude for the station") parser.add_argument("-t", "--time", default="00/00/00,0:0:0.0 UTC", help="provides timing information for this timeseries") parser.add_argument("-o", "--orientation", default="0,90,UP", dest="orientation", help="orientation, default: 0,90,UP") parser.add_argument("--azimuth", type=float, dest="azimuth", help="azimuth for rotation (degrees)") parser.add_argument("input_file", help="AWP input timeseries") parser.add_argument("output_stem", help="output BBP filename stem without the " " .{dis,vel,acc}.bbp extensions") parser.add_argument("-d", dest="output_dir", default="", help="output directory for the BBP file") args = parser.parse_args() input_file = args.input_file output_file_dis = "%s.dis.bbp" % (os.path.join(args.output_dir, args.output_stem)) output_file_vel = "%s.vel.bbp" % (os.path.join(args.output_dir, args.output_stem)) output_file_acc = "%s.acc.bbp" % (os.path.join(args.output_dir, args.output_stem)) # Check orientation orientation = args.orientation.split(",") if len(orientation) != 3: print("[ERROR]: Need to specify orientation for all 3 components!") sys.exit(-1) orientation[0] = float(orientation[0]) orientation[1] = float(orientation[1]) orientation[2] = orientation[2].lower() if orientation[2] != "up" and orientation[2] != "down": print("[ERROR]: Vertical orientation must be up or down!") sys.exit(-1) # Read RWG file print("[INFO]: Reading file %s ..." % (os.path.basename(input_file))) header, delta_t, times, vel_h1, vel_h2, vel_ver = read_edge(input_file) edge_params = parse_edge_header(header) # Figure out what unit to use units = {"m": ["m", "m/s", "m/s^2"], "cm": ["cm", "cm/s", "cm/s^2"]} if "unit" in edge_params: unit = edge_params["unit"] else: # Defaults to meters unit = "m" # Override command-line defaults if "lat" in edge_params: if args.latitude == 0.0: args.latitude = edge_params["lat"] if "lon" in edge_params: if args.longitude == 0.0: args.longitude = edge_params["lon"] if "station" in edge_params: if args.station_name == "NoName": args.station_name = edge_params["station"] # Calculate displacement dis_h1 = integrate(vel_h1, delta_t) dis_h2 = integrate(vel_h2, delta_t) dis_ver = integrate(vel_ver, delta_t) # Calculate acceleration acc_h1 = derivative(vel_h1, delta_t) acc_h2 = derivative(vel_h2, delta_t) acc_ver = derivative(vel_ver, delta_t) # Create station data structures samples = vel_h1.size # samples, dt, data, acceleration, velocity, displacement signal_h1 = TimeseriesComponent(samples, delta_t, orientation[0], acc_h1, vel_h1, dis_h1) signal_h2 = TimeseriesComponent(samples, delta_t, orientation[1], acc_h2, vel_h2, dis_h2) signal_ver = TimeseriesComponent(samples, delta_t, orientation[2], acc_ver, vel_ver, dis_ver) station = [signal_h1, signal_h2, signal_ver] # Rotate timeseries if needed if args.azimuth is not None: print("[INFO]: Rotating timeseries - %f degrees" % (args.azimuth)) station = rotate_timeseries(station, args.azimuth) # Update orientation after rotation so headers reflect any changes args.orientation = "%s,%s,%s" % (str( station[0].orientation), str( station[1].orientation), str(station[2].orientation)) # Pull data back acc_h1 = station[0].acc.tolist() vel_h1 = station[0].vel.tolist() dis_h1 = station[0].dis.tolist() acc_h2 = station[1].acc.tolist() vel_h2 = station[1].vel.tolist() dis_h2 = station[1].dis.tolist() acc_ver = station[2].acc.tolist() vel_ver = station[2].vel.tolist() dis_ver = station[2].dis.tolist() # Write header o_dis_file = open(output_file_dis, 'w') o_vel_file = open(output_file_vel, 'w') o_acc_file = open(output_file_acc, 'w') write_bbp_header(o_dis_file, "displacement", units[unit][0], args, header) write_bbp_header(o_vel_file, "velocity", units[unit][1], args, header) write_bbp_header(o_acc_file, "acceleration", units[unit][2], args, header) # Write files for (time, disp_h1, disp_h2, disp_ver, velo_h1, velo_h2, velo_ver, accel_h1, accel_h2, accel_ver) in zip(times, dis_h1, dis_h2, dis_ver, vel_h1, vel_h2, vel_ver, acc_h1, acc_h2, acc_ver): o_dis_file.write("%1.9E %1.9E %1.9E %1.9E\n" % (time, disp_h1, disp_h2, disp_ver)) o_vel_file.write("%1.9E %1.9E %1.9E %1.9E\n" % (time, velo_h1, velo_h2, velo_ver)) o_acc_file.write("%1.9E %1.9E %1.9E %1.9E\n" % (time, accel_h1, accel_h2, accel_ver)) # All done o_dis_file.close() o_vel_file.close() o_acc_file.close()
def read_smc_v1(input_file): """ Reads and processes a V1 file """ record_list = [] # Loads station into a string try: fp = open(input_file, 'r') except IOError as e: print("[ERROR]: opening input file %s" % (input_file)) return False # Print status message print("[READING]: %s..." % (input_file)) # Read data channels = fp.read() fp.close() # Splits the string by channels channels = channels.split('/&') del(channels[len(channels)-1]) # Splits the channels for i in range(len(channels)): channels[i] = channels[i].split('\n') # Clean the first row in all but the first channel for i in range(1, len(channels)): del channels[i][0] for i in range(len(channels)): # Check this is the uncorrected acceleration data ctype = channels[i][0][0:24].lower() if ctype != "uncorrected accelerogram": print("[ERROR]: processing uncorrected accelerogram ONLY.") return False else: dtype = 'a' network = input_file.split('/')[-1].split('.')[0][0:2].upper() station_id = input_file.split('/')[-1].split('.')[0][2:].upper() # Get location's latitude and longitude tmp = channels[i][4].split() latitude = tmp[3][:-1] longitude = tmp[4] # Get station name station_name = channels[i][5][0:40].strip() # Get orientation, convert to int if it's digit tmp = channels[i][6].split() orientation = tmp[2] if orientation.isdigit(): orientation = float(int(orientation)) if orientation == 360: orientation = 0.0 else: orientation = orientation.lower() # Get date and time; set to fixed format start_time = channels[i][3][37:80].split() date = start_time[2][:-1] tmp = channels[i][14].split() hour = tmp[0] minute = tmp[1] seconds = tmp[2] fraction = tmp[3] tzone = channels[i][3].split()[-2] time = "%s:%s:%s.%s %s" % (hour, minute, seconds, fraction, tzone) # Get number of samples and dt tmp = channels[i][27].split() samples = int(tmp[0]) delta_t = 1.0 / int(tmp[4]) # Get signals' data tmp = channels[i][28:] signal = str() for s in tmp: signal += s acc_data_g = read_data(signal) # Convert from g to cm/s/s acc_data = acc_data_g * G2CMSS # Now integrate to get velocity and displacement vel_data = integrate(acc_data, delta_t) dis_data = integrate(vel_data, delta_t) print("[PROCESSING]: Found component: %s" % (orientation)) record_list.append(TimeseriesComponent(samples, delta_t, orientation, acc_data, vel_data, dis_data)) station_metadata = {} station_metadata['network'] = network station_metadata['station_id'] = station_id station_metadata['type'] = "V1" station_metadata['date'] = date station_metadata['time'] = time station_metadata['longitude'] = longitude station_metadata['latitude'] = latitude station_metadata['high_pass'] = -1 station_metadata['low_pass'] = -1 return record_list, station_metadata
def read_smc_v2(input_file): """ Reads and processes a V2 file """ record_list = [] # Loads station into a string try: fp = open(input_file, 'r') except IOError as e: print("[ERROR]: opening input file %s" % (input_file)) return False # Print status message print("[READING]: %s..." % (input_file)) # Read data channels = fp.read() fp.close() # Splits the string by channels channels = channels.split('/&') del(channels[len(channels)-1]) # Splits the channels for i in range(len(channels)): channels[i] = channels[i].split('\n') # Clean the first row in all but the first channel for i in range(1, len(channels)): del channels[i][0] for i in range(len(channels)): tmp = channels[i][0].split() # Check this is the corrected acceleration data ctype = (tmp[0] + " " + tmp[1]).lower() if ctype != "corrected accelerogram": print("[ERROR]: processing corrected accelerogram ONLY.") return False # Get network code and station id network = input_file.split('/')[-1].split('.')[0][0:2].upper() station_id = input_file.split('/')[-1].split('.')[0][2:].upper() # Get location's latitude and longitude tmp = channels[i][5].split() latitude = tmp[3][:-1] longitude = tmp[4] # Make sure we captured the right values if latitude[-1].upper() != "N" and latitude.upper() != "S": # Maybe it is an old file, let's try to get the values again... latitude = (float(tmp[3]) + (float(tmp[4]) / 60.0) + (float(tmp[5][:-2]) / 3600.0)) latitude = "%s%s" % (str(latitude), tmp[5][-2]) longitude = (float(tmp[6]) + (float(tmp[7]) / 60.0) + (float(tmp[8][:-1]) / 3600.0)) longitude = "%s%s" % (str(longitude), tmp[8][-1]) # Get orientation from integer header orientation = float(int(channels[i][26][50:55])) if orientation == 360: orientation = 0.0 elif orientation == 500: orientation = "up" elif orientation == 600: orientation = "down" # Get filtering information tmp = channels[i][14].split() high_pass = float(tmp[8]) low_pass = float(tmp[10]) # Get station name station_name = channels[i][6][0:40].strip() # Get date and time; set to fixed format start_time = channels[i][4][37:80].split() try: date = start_time[2][:-1] tmp = start_time[3].split(':') hour = tmp[0] minute = tmp[1] seconds, fraction = tmp[2].split('.') # Works for both newer and older V2 files tzone = channels[i][4].split()[5] except IndexError: date = '00/00/00' hour = '00' minute = '00' seconds = '00' fraction = '0' tzone = '---' # Put it all together time = "%s:%s:%s.%s %s" % (hour, minute, seconds, fraction, tzone) # Get number of samples and dt tmp = channels[i][45].split() samples = int(tmp[0]) delta_t = float(tmp[8]) # Get signals' data tmp = channels[i][45:] a_signal = str() v_signal = str() d_signal = str() for s in tmp: # Detecting separate line and get data type if "points" in s.lower(): line = s.split() if line[3].lower() == "accel" or line[3].lower() == "acc": dtype = 'a' elif line[3].lower() == "veloc" or line[3].lower() == "vel": dtype = 'v' elif line[3].lower() == "displ" or line[3].lower() == "dis": dtype = 'd' else: dtype = "unknown" # Processing data else: if dtype == 'a': a_signal += s elif dtype == 'v': v_signal += s elif dtype == 'd': d_signal += s acc_data = read_data(a_signal) vel_data = read_data(v_signal) dis_data = read_data(d_signal) print("[PROCESSING]: Found component: %s" % (orientation)) record_list.append(TimeseriesComponent(samples, delta_t, orientation, acc_data, vel_data, dis_data)) station_metadata = {} station_metadata['network'] = network station_metadata['station_id'] = station_id station_metadata['type'] = "V2" station_metadata['date'] = date station_metadata['time'] = time station_metadata['longitude'] = longitude station_metadata['latitude'] = latitude station_metadata['high_pass'] = high_pass station_metadata['low_pass'] = low_pass return record_list, station_metadata