def xml2df(xml): """ Parameters ---------- xml: str xml path Returns ------- all_coords : DataFrame DataFrame with the coordinates info of each channel of station in each network """ inv = read_inventory(xml) all_coords = [] for network in inv: for station in network: for channel in station: sta_coords = {} sta_coords['network'] = network.code sta_coords['station'] = station.code sta_coords['location_id'] = channel.location_code sta_coords['channel'] = channel.code sta_coords['latitude'] = station.latitude sta_coords['longitude'] = station.longitude sta_coords["elevation"] = station.elevation all_coords.append(sta_coords) return pd.DataFrame(all_coords)
def join(self, inv_path, n_processor=1, concurrent_feature="thread"): """ Gathering all npz downloaded files and create one MassivePPSD file according to dld_restrictions. parameters: ----------- inv_path: str Inventory that contain the metadata of the filtered stations in dld_restrictions. Returns: -------- Massive PPSD saved in my_storage/{network}.{station}.{location}.{channel}/mass_ppsd/ """ inv = read_inventory(inv_path) channels_contents = inv.get_contents()['channels'] times = utils.get_chunktimes( starttime=self.dld_restrictions.starttime, endtime=self.dld_restrictions.endtime, chunklength_in_sec=self.dld_restrictions.chunklength, overlap_in_sec=self.dld_restrictions.overlap) for single_cha_contents in channels_contents: if n_processor == 1: paths = [] for starttime, endtime in times: path = utils.get_path2join_ppsd( my_storage=self.my_storage, content=single_cha_contents, starttime=starttime, endtime=endtime) paths.append(path) utils.get_MassPPSD(self.my_storage, paths, self.dld_restrictions) else: def run_get_path2join_ppsd(times): path = utils.get_path2join_ppsd( my_storage=self.my_storage, content=single_cha_contents, starttime=times[0], endtime=times[1]) return path if n_processor > len(times): n_processor = len(times) with concurrent.futures.ThreadPoolExecutor( max_workers=n_processor) as executor: paths = executor.map(run_get_path2join_ppsd, times) utils.get_MassPPSD(self.my_storage, list(paths), self.dld_restrictions)
def download(self, inv_path, ppsd_restrictions, n_processor=1, concurrent_feature="thread"): """ Download all ppsd according to download and ppsd restrictions. parameters: ----------- inv_path: str Inventory that contain the metadata ppsd_restrictions: PPSDRestrictions object Class that contain all parameters to calculate the PPSD. n_processor: int Number maximum of threads concurrent_feature: str 'thread' or 'process'. Proccess is obsolete until now. Returns: -------- PPSD saved in my_storage/{network}.{station}.{location}.{channel}/ppsd """ times = utils.get_chunktimes( starttime=self.dld_restrictions.starttime, endtime=self.dld_restrictions.endtime, chunklength_in_sec=self.dld_restrictions.chunklength, overlap_in_sec=self.dld_restrictions.overlap) inv = read_inventory(inv_path) channels_contents = inv.get_contents()['channels'] for starttime, endtime in times: def run_ppsd(single_cha_contents): utils.get_ppsd(self.my_storage, self.client, inv, ppsd_restrictions, single_cha_contents, starttime, endtime, self.dld_restrictions.plot_trace) if n_processor == 1: for single_cha_contents in channels_contents: utils.get_ppsd(self.my_storage, self.client, inv, ppsd_restrictions, single_cha_contents, starttime, endtime, self.dld_restrictions.plot_trace) else: if n_processor > len(channels_contents): n_processor = len(channels_contents) with concurrent.futures.ThreadPoolExecutor( max_workers=n_processor) as executor: executor.map(run_ppsd, channels_contents)
def solve_dldR(client=None, from_xml=None, download_restrictions=None): """ Parameters ---------- client: obspy.Client object fdsn client download_restrictions: DownloadRestrictions object It is necessary to restrict some features of the data Returns: -------- inv_new: Inventory object Restricted inventory according to download_Restrictions """ if from_xml != None: inv = read_inventory(from_xml, format="STATIONXML") inv = inv.select(network=download_restrictions.network, station=download_restrictions.station, location=download_restrictions.location, channel=download_restrictions.channel, starttime=download_restrictions.starttime, endtime=download_restrictions.endtime) print(inv) else: inv = client.get_stations(network=download_restrictions.network, station=download_restrictions.station, location=download_restrictions.location, channel=download_restrictions.channel, starttime=download_restrictions.starttime, endtime=download_restrictions.endtime, level="response") # Lets go with feature restrictions. if download_restrictions is not None: if not download_restrictions.exclude: inv_new = inv.copy() else: inv_new = inv.copy() for to_exclude in download_restrictions.exclude: net, sta, loc, cha = to_exclude net, sta, loc, cha = list( map(lambda x: x.split(","), [net, sta, loc, cha])) for n in net: for s in sta: for l in loc: for c in cha: inv_new = inv_new.remove(network=n, station=s, location=l, channel=c) inv = inv_new.copy() return inv
def loads_inv(bytestr): '''Returns the inventory object given an input bytes sequence representing an inventory (xml) from, e.g., downloaded data :param bytestr: the sequence of bytes. It can be compressed with any of the function defined here. The method will first try to de-compress data. Then, the de-compressed data (if de-compression does not fail) or the data passed as argument will be passed to obspy `read_inventory` :return: an `class: obspy.core.inventory.inventory.Inventory` object ''' try: bytestr = decompress(bytestr) except (IOError, zipfile.BadZipfile, zlib.error) as _: pass # we might actually have uncompressed data which starts accidentally with the wrong return read_inventory(BytesIO(bytestr), format="STATIONXML")
def loads_inv(bytestr): # FIXME: move to different package? try: bytestr = decompress(bytestr) except(IOError, zipfile.BadZipfile, zlib.error) as _: pass # we might actually have uncompressed data which starts accidentally with the wrong # bytes # s = StringIO(bytestr) # s.seek(0) # FIXME: necessary ?? # try: # inv = read_inventory(StringIO(bytestr), format="STATIONXML") # finally: # s.close() # return inv return read_inventory(StringIO(bytestr), format="STATIONXML")
def test_inventory_with_multiple_channels(self): filename = os.path.join(self.path, 'gse_2.0_non_standard.txt') inventory_filename = os.path.join(self.path, 'inventory_multiple_channels.xml') inventory = read_inventory(inventory_filename) fields = { 'line_1': { 'author': slice(105, 113), 'id': slice(114, 123), }, 'line_2': { 'az': slice(40, 46), 'antype': slice(105, 106), 'loctype': slice(107, 108), 'evtype': slice(109, 111), }, 'arrival': { 'amp': slice(94, 104), }, } warnings.simplefilter("ignore", UserWarning) catalog = _read_gse2(filename, inventory, fields=fields, event_point_separator=True) warnings.filters.pop(0) self.assertEqual(len(catalog), 2) # Test a station present in the inventory event = catalog[0] self.assertEqual(len(event.picks), 9) pick = event.picks[0] waveform = pick.waveform_id self.assertEqual(waveform.network_code, 'ZU') self.assertEqual(waveform.channel_code, 'HHZ') self.assertEqual(waveform.location_code, '1') # Test a station with several channels pick_2 = event.picks[2] waveform_2 = pick_2.waveform_id self.assertEqual(waveform_2.network_code, 'ZU') self.assertEqual(waveform_2.channel_code, None) self.assertEqual(waveform_2.location_code, None) # Test a station not present in the inventory pick_3 = event.picks[3] waveform_3 = pick_3.waveform_id self.assertEqual(waveform_3.network_code, 'XX') self.assertEqual(waveform_3.channel_code, None) self.assertEqual(waveform_3.location_code, None)
def loadSummary(self): # If the user quits or cancels this dialog, '' is returned loadPath = str(QtWidgets.QFileDialog.getExistingDirectory( parent=self.mainWindow, caption="Load Summary from")) if loadPath != '': try: catalog = read_events(os.path.join(loadPath, 'events.xml')) self.on_events_loaded(catalog) self.mainWindow.selectAllEvents() except Exception as e: LOGGER.error("Unable to load events! %s", e) try: inventory = read_inventory(os.path.join(loadPath, 'stations.xml')) self.on_stations_loaded(inventory) self.mainWindow.selectAllStations() except Exception as e: LOGGER.error("Unable to load stations! %s", e)
def loadSummary(self): # If the user quits or cancels this dialog, '' is returned loadPath = str(QtGui.QFileDialog.getExistingDirectory( parent=self.mainWindow, caption="Load Summary from")) if loadPath != '': try: catalog = read_events(os.path.join(loadPath, 'events.xml')) self.on_events_loaded(catalog) self.mainWindow.selectAllEvents() except Exception as e: LOGGER.error("Unable to load events! %s", e) try: inventory = read_inventory(os.path.join(loadPath, 'stations.xml')) self.on_stations_loaded(inventory) self.mainWindow.selectAllStations() except Exception as e: LOGGER.error("Unable to load stations! %s", e)
def main2(segment, config): '''calls _main with the normal inventory and all possible wrong inventories''' # annoying print statementin obspy 1.1.1 when calling the function 'psd' # (see below) and when adding a trace shorter than # the ppsd_length: workaround? redirect to stderr (which is captured by the caller): temp = sys.stdout try: sys.stdout = sys.stderr stream = segment.stream(True) assert1trace(stream) # raise and return if stream has more than one trace raw_trace = stream[0].copy() trace = stream[0] # work with the (surely) one trace now # compute amplitude ratio only once on the raw trace: amp_ratio = ampratio(trace) # if amp_ratio >= config['amp_ratio_threshold']: # saturated = True # @UnusedVariable data = [] # bandpass the trace, according to the event magnitude. # This modifies the segment.stream() permanently: trace = _bandpass_remresp(segment, config, trace, segment.inventory()) data.append(_main(segment, config, raw_trace.copy(), segment.inventory())) data[-1]['amplitude_ratio'] = amp_ratio # add gain (1). Decide whether to compute gain x2,10,100 or x1/2.1/10,1/100 # (not both, try to speed up a bit the computations) # "randomly" according to the segment id (even or odd) gain_factors = config['stage_gain_factors'] if segment.id % 2 == 0: gain_factors = gain_factors[:3] else: gain_factors = gain_factors[3:] for gain_factor in gain_factors: newtrace = trace.copy() newtrace.data *= float(gain_factor) stream[0] = newtrace assert segment.stream()[0] is newtrace # need to change alkso the raw trace for the noisepsd, otherwise # we calculate the same psd as if we did not change the gain: raw_trace_ = raw_trace.copy() raw_trace_dtype_ = raw_trace_.data.dtype raw_trace_.data = raw_trace_.data * float(gain_factor) if np.issubdtype(raw_trace_dtype_, np.integer): raw_trace_.data = (0.5 + raw_trace_.data).astype(raw_trace_dtype_) data.append(_main(segment, config, raw_trace_, segment.inventory())) data[-1]['outlier'] = 1 data[-1]['modified'] = "STAGEGAIN:X%s" % str(gain_factor) data[-1]['amplitude_ratio'] = amp_ratio # acceleromters/velocimeters: if segment.station.id in config['station_ids_both_accel_veloc']: # reload inventory (takes more time, but we won't modify cached version): inventory = get_inventory(segment.station) cha_obj = get_cha_obj(segment, inventory) resp_tmp = cha_obj.response for other_cha in get_other_chan_objs(segment, inventory): cha_obj.response = other_cha.response # force reloading the segment stream: stream = segment.stream(True) # re-apply bandpass with the "wrong" inventory # (modifying segment.stream() inplace): _test_trace = _bandpass_remresp(segment, config, stream[0], inventory) assert _test_trace is segment.stream()[0] data.append(_main(segment, config, raw_trace.copy(), inventory)) data[-1]['outlier'] = 1 data[-1]['modified'] = "CHARESP:%s" % other_cha.code data[-1]['amplitude_ratio'] = amp_ratio cha_obj.response = resp_tmp if segment.station.id in config['station_ids_with_wrong_local_inventory']: channels_ = config['station_ids_with_wrong_local_inventory'][segment.station.id] filename = channels_.get(segment.data_seed_id, None) if filename is None: raise ValueError('%s not found in wrong inventories dict' % segment.data_seed_id) if filename is not None: inventories_dir = config['inventories_dir'] wrong_inventory = read_inventory(os.path.join(os.getcwd(), inventories_dir, filename)) # force reloading the segment stream: stream = segment.stream(True) # re-apply bandpass with the "wrong" inventory # (modifying segment.stream() inplace): _test_trace = _bandpass_remresp(segment, config, stream[0], wrong_inventory) assert _test_trace is segment.stream()[0] data.append(_main(segment, config, raw_trace.copy(), wrong_inventory)) data[-1]['outlier'] = 1 data[-1]['modified'] = "INVFILE:%s" % filename data[-1]['amplitude_ratio'] = amp_ratio return pd.DataFrame(data) finally: sys.stdout = temp
# size of window and overlap for PSD window = 3600 overlap = 0.5 # Data completeness for each window Comp_Thres = 0.9 ######################################################################## seed_ID = net + "." + sta + "." + loc + "." + chan TestHour = UTCDateTime("2019-" + SDay + "T" + SHour + ":" + SMin + ":00") # Get the response resppath = "/APPS/metadata/RESPS/RESP." + net + "." + sta + "." + loc + "." + chan inv = read_inventory(resppath) inv_Resp = inv.get_response(seed_ID, TestHour) resp, freqR = inv_Resp.get_evalresp_response(t_samp=1. / fs, nfft=nfft, output='ACC') resp = resp[1:] # read the first 11 days of ANMO data st = Stream() for day in range(1, 12): try: st += read("/msd/" + net + "_" + sta + "/" + str(TestHour.year) + "/" + str(day).zfill(3) + "/" + loc + "_" + chan + "*.seed") except: print("No Data Here")
st_folded[i_].data[0:npts] = (causal + acausal) / 2 #Keep only the first half of the stream, as that is where all the action is. st_folded.trim(starttime=starttime, endtime=starttime + npts * delta) # make sure the order is R,T,Z (or E, N, Z). Maybe better to use st.select() with a custom key header? st_folded.sort() ZZ = st_folded[2].data RZ = st_folded[0].data TZ = st_folded[1].data return ZZ, RZ, TZ, flag # get station list from inventory: inv = read_inventory(os.getcwd() + "\inv.xml") net = inv[0] for orienstation in net: if orienstation.code != 'WTAZ': #In our network, WTAZ only has a vertical component. print(orienstation.code) # for each station pair, read the CCFs, rotate, and find # optimal rotation, based on Zha's method: angles = [] for station in net: if station.code != orienstation.code: # get the data from fn: [ZZ, RZ, TZ, flag] = readandfold(datadir, station.code,\ orienstation.code) # we are going to compare the RT with a 90 degree
def get_response_obj(self, stc): sensor_keys = [stc.sensor_type] datalogger_keys = [stc.das_manufacturer, stc.das_model, stc.sample_rate] if not self.resp_manager.is_already_requested(sensor_keys, datalogger_keys): self.ph5.read_response_t() Response_t = self.ph5.get_response_t_by_n_i(stc.response_n_i) response_file_das_a_name = Response_t.get('response_file_das_a', None) response_file_sensor_a_name = Response_t.get( 'response_file_sensor_a', None) # parse datalogger response if response_file_das_a_name: response_file_das_a = \ self.ph5.ph5_g_responses.get_response( response_file_das_a_name ) with io.BytesIO(response_file_das_a) as buf: buf.seek(0, 0) dl_resp = read_inventory(buf, format="RESP") dl_resp = dl_resp[0][0][0].response # parse sensor response if present if response_file_sensor_a_name: response_file_sensor_a = \ self.ph5.ph5_g_responses.get_response( response_file_sensor_a_name ) with io.BytesIO(response_file_sensor_a) as buf: buf.seek(0, 0) sensor_resp = read_inventory(buf, format="RESP") sensor_resp = sensor_resp[0][0][0].response inv_resp = None if response_file_das_a_name and response_file_sensor_a_name: # both datalogger and sensor response dl_resp.response_stages.pop(0) dl_resp.response_stages.insert(0, sensor_resp.response_stages[0]) dl_resp.recalculate_overall_sensitivity() inv_resp = dl_resp elif response_file_das_a_name: # only datalogger response inv_resp = dl_resp elif response_file_sensor_a_name: # only sensor response inv_resp = sensor_resp # Add addtional information that is in Response_t inv_resp.stats = AttribDict() inv_resp.stats.gain_value = Response_t["gain/value_i"] inv_resp.stats.gain_units = Response_t["gain/units_s"] inv_resp.stats.bitweight_value = Response_t["bit_weight/value_d"] inv_resp.stats.bitweight_units = Response_t["bit_weight/units_s"] if inv_resp: # update response manager and return response self.resp_manager.add_response(sensor_keys, datalogger_keys, inv_resp) return inv_resp else: return self.resp_manager.get_response(sensor_keys, datalogger_keys)
def read_metadata(path_or_url): try: return read_inventory(path_or_url, format="STATIONXML") except Exception as exc: raise Exception(f'Invalid station (xml) file: {str(exc)}\n' f'(path/url: {path_or_url})')
# i1 = np.searchsorted(a, v1, side='left') # i2 = np.searchsorted(a, v1, side='right') # a[i1:i2].mean() # tsearch.append(time.time() -t) # tmean, tsearch = np.array(tmean), np.array(tsearch) # print(f'array with {len(a)} elements (sorted ascending)') # print(f'Computational costs (in seconds)') # print(f'Using expr (min median max): {tmean.min():.5f}, {np.median(tmean):.5f}, {tmean.max():.5f} ') # print(f'Using bin search (min median max): {tsearch.min():.5f}, {np.median(tsearch):.5f}, {tsearch.max():.5f} ') # # sys.exit(0) trace, inv = 'trace_GE.APE.mseed', 'inventory_GE.APE.xml' # trace, inv = 'GE.FLT1..HH?.mseed', 'GE.FLT1.xml' stream = read(join(dirname(__file__), 'miniseed', trace)) inv = read_inventory(join(dirname(__file__), 'miniseed', inv)) periods = [.2, 5] # [0.05, 0.2, 2, 5, 9, 20] print(f'Periods to calculate on test miniseed: {periods}') t = time.time() _ = old.psd_values(periods, stream[0], inv) t = time.time() - t print(f'Old method, values: {str(_)}, time: {t} s') t = time.time() _ = psd_values(periods, stream[0], inv) t = time.time() - t print(f'New method (old func), values: {str(_)}, time: {t} s') t = time.time() _ = psd_values(periods, stream[0], inv, method='new') t = time.time() - t print(f'New method (new func), values: {str(_)}, time: {t} s')
def process(self, sort_by_time=False, aggregate: str or None = None, progress: TextIO or None = sys.stderr, info: TextIO or None = None): """Processes all added files/URLs and yields the results""" if aggregate: aggregates = ('min', 'max', 'median', 'mean') if aggregate not in aggregates: raise ValueError(f'"aggregate" not in {str(aggregates)}') count, total = 0, sum(_[-1] for _ in self._data) data = {} messages = None if info is None else [] # load model now: it takes ~=1 second and is usually lazy loaded, # but this means that the progressbar would show misleading results # at the beginning load_default_trained_model() with ProgressBar(progress) as pbar: # self._data has generally only one element in the current # implementation (see module function `process`), however, it # already supports multiple call of its `add_*` methods above for key, streamiterator, metadata_path, length in self._data: try: inv = read_inventory(metadata_path) except Exception as exc: if messages is not None: messages.append(f'Metadata error, {str(exc)}. {key}') streamiterator = [] # hack to skip iteration below feats = [] ids = [] kount = 0 try: for fpath, stream in streamiterator: kount += 1 for trace in stream: (id_, st_, et_), feat = trace_idfeatures(trace, inv) feats.append(feat) ids.append((fpath, id_, st_, et_)) except Exception as exc: if messages is not None: messages.append(f'{str(exc)}. {key}') feats = [] # hack to stop after updating the pbar count += 1 pbar.update(count / total) if kount < length: count += length - kount pbar.update(count / total) if not feats: continue scores = aa_scores(np.asarray(feats)) iter_ = zip(ids, scores) if aggregate: data = defaultdict(lambda: [None, []]) for (fpath, id_, stime, etime), score in iter_: timeranges, scores_ = data[id_] if not timeranges: data[id_][0] = [stime, etime] else: timeranges[0] = min(stime, timeranges[0]) timeranges[1] = max(etime, timeranges[1]) scores_.append(score) ids = [] scores = [] for id_, (timeranges, scores_) in data.items(): ids.append(('', id_, *timeranges)) scores_ = np.asarray(scores_) if np.isnan(scores_).all(): scores.append(np.nan) elif aggregate == 'mean': scores.append(np.nanmean(scores_)) elif aggregate == 'min': scores.append(np.nanmin(scores_)) elif aggregate == 'max': scores.append(np.nanmax(scores_)) else: scores.append(np.nanmedian(scores_)) # now sort (if needed) and print them at once: iter_ = zip(ids, scores) if sort_by_time: yield sorted(iter_, key=lambda _: _[0][1]) yield iter_ for msg in (messages or []): print(msg, file=info)
def test_ppsd(self): """tests that the psd with the algorithm used in this module and the original evaluation algorithm (see _old class) produce the same results with scores that do not differ by more than 0.01 (roughly) """ psd_periods_to_test = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 15, 20] feats_rtol = 0.01 # 1e-2 scores_rtol = 0.013 # 1.2e-2 # dataroot = join(dirname(__file__), 'data') for file, inv in ( [ join(dataroot, 'trace_GE.APE.mseed'), join(dataroot, 'inventory_GE.APE.xml') ], [ join(dataroot, 'GE.FLT1..HH?.mseed'), join(dataroot, 'GE.FLT1.xml') ], [ ('http://service.iris.edu/fdsnws/dataselect/1/query?' '&net=TA&sta=A2*&start=2019-01-04T23:22:00&cha=BH?' '&end=2019-01-04T23:24:00'), ('http://service.iris.edu/fdsnws/station/1/query?&net=TA' '&sta=A2*&start=2019-01-04T23:22:00&cha=BH?' '&end=2019-01-04T23:24:00&level=response') ], ): # trace, inv = 'GE.FLT1..HH?.mseed', 'GE.FLT1.xml' orig_stream = read(file) # print([_.get_id() for _ in orig_stream]) metadata = read_inventory(inv) for multip_fact in [-1000, 1, 10000]: stream = Stream() for t in orig_stream: t = t.copy() t.data *= multip_fact stream.append(t) # calculate features but do not capture stderr cause it causes # problems with temporarily set output captures: feats = traces_features(stream, metadata) feats_old = np.asarray([obspyPSD.psd_values([5], _, metadata) for _ in stream]) self.assertTrue(np.allclose(feats, feats_old, rtol=feats_rtol, atol=0, equal_nan=True)) scores = aa_scores(feats) scores_old = aa_scores(feats_old) self.assertTrue(np.allclose(scores, scores_old, rtol=scores_rtol, atol=0, equal_nan=True)) # test that the current version of psd is the same as our # first implementation (copied below in this module): feats_old2 = np.asarray([_old_psd_values([5], _, metadata) for _ in stream]) assert np.allclose(feats, feats_old2, rtol=1.e-8) # test actually that more PSDs are the same (not only at the # feature(s) computed above) for _ in stream: _psds_old = _old_psd_values(psd_periods_to_test, _, metadata) _psds_new = trace_psd(_, metadata, psd_periods_to_test)[0] assert np.allclose(_psds_old, _psds_new, equal_nan=True)
from obspy.core.inventory.inventory import read_inventory #from obspy import read_inventory inv = read_inventory('yn_station.xml', format='stationxml') #inv.plot() nets = inv.get_contents()['networks'] print(nets) n = inv.select('YN') #print(n) for net in inv: #print(net.get_contents()) pass
def test_import_export_1(self): inv = read_inventory( path.join(self.FILES_FOLDER, 'station_from_obspy.xml')) errors = ValidateInventory(inv, self, True).run() self.assertEqual(len(errors), 2, 'Number of errors is different')
HANDLABELLED_COL = 'hand_labelled' OUTLIER_COL = 'outlier' WINDOWTYPE_COL = 'window_type' # Instead of implementing the old wrong inventories in the config, # Put them here at module level, so that we load the inventories once per # module hopefully speeding up calculations: _path = os.path.join( os.path.abspath(os.path.dirname(os.path.dirname(__file__))), 'inventories', 's2s_2017_10') assert os.path.isdir(_path) WRONG_OLD_INVENTORIES = { 5831: (read_inventory(os.path.join(_path, "CH.GRIMS.2011-11-09T00:00:00.xml")), set(['CH.GRIMS..HHE', 'CH.GRIMS..HHN', 'CH.GRIMS..HHZ'])), 5833: (read_inventory(os.path.join(_path, "CH.GRIMS.2015-10-30T10:50:00.xml")), set(['CH.GRIMS..HHE', 'CH.GRIMS..HHN', 'CH.GRIMS..HHZ'])), 10179: (read_inventory(os.path.join(_path, "SK.MODS.2004-03-17T00:00:00.xml")), set(['SK.MODS..HHE', 'SK.MODS..HHN', 'SK.MODS..HHZ'])), 10186: (read_inventory(os.path.join(_path, "SK.ZST.2004-03-17T00:00:00.xml")), set(['SK.ZST..HHE', 'SK.ZST..HHN', 'SK.ZST..HHZ'])), 890: (read_inventory(os.path.join(_path, "FR.PYLO.2010-01-17T10:00:00.xml")), set(['FR.PYLO.00.HNE', 'FR.PYLO.00.HNN', 'FR.PYLO.00.HNZ'])) }
def main2(segment, config): '''calls _main with the normal inventory and all possible wrong inventories''' # annoying print statementin obspy 1.1.1 when calling the function 'psd' # (see below) and when adding a trace shorter than # the ppsd_length: workaround? redirect to stderr (which is captured by the caller): temp = sys.stdout try: sys.stdout = sys.stderr stream = segment.stream(True) assert1trace( stream) # raise and return if stream has more than one trace raw_trace = stream[0].copy() # store channel's channel via data_seed_id (might be faster): # calculate it here so in case of error we avoid unnecessary calculations channel_code = segment.data_seed_id.split('.')[3] # compute amplitude ratio only once on the raw trace: amp_ratio = ampratio(raw_trace) # if amp_ratio >= config['amp_ratio_threshold']: # saturated = True # @UnusedVariable data = [] # bandpass the trace, according to the event magnitude. # This modifies the segment.stream() permanently: data.append(_main(segment, config, raw_trace, segment.inventory())) # add gain (1). Decide whether to compute gain x2,10,100 or x1/2.1/10,1/100 # (not both, try to speed up a bit the computations) # "randomly" according to the segment id (even or odd) gain_factors = config['stage_gain_factors'] if segment.id % 2 == 0: gain_factors = gain_factors[:3] else: gain_factors = gain_factors[3:] for gain_factor in gain_factors: # need to change alkso the raw trace for the noisepsd, otherwise # we calculate the same psd as if we did not change the gain: raw_trace_ = raw_trace.copy() raw_trace_dtype_ = raw_trace_.data.dtype raw_trace_.data = raw_trace_.data * float(gain_factor) if np.issubdtype(raw_trace_dtype_, np.integer): raw_trace_.data = (0.5 + raw_trace_.data).astype(raw_trace_dtype_) data.append(_main(segment, config, raw_trace_, segment.inventory())) data[-1]['outlier'] = True data[-1]['modified'] = "STAGEGAIN:X%s" % str(gain_factor) # acceleromters/velocimeters: if segment.station.id in config['station_ids_both_accel_veloc']: # reload inventory (takes more time, but we won't modify cached version): inventory = get_inventory(segment.station) cha_obj = get_cha_obj(segment, inventory) resp_tmp = cha_obj.response for other_cha in get_other_chan_objs(segment, inventory): cha_obj.response = other_cha.response data.append(_main(segment, config, raw_trace, inventory)) data[-1]['outlier'] = True data[-1]['modified'] = "CHARESP:%s" % other_cha.code cha_obj.response = resp_tmp if segment.station.id in config[ 'station_ids_with_wrong_local_inventory']: channels_ = config['station_ids_with_wrong_local_inventory'][ segment.station.id] filename = channels_.get(segment.data_seed_id, None) if filename is None: raise ValueError('%s not found in wrong inventories dict' % segment.data_seed_id) if filename is not None: inventories_dir = config['inventories_dir'] wrong_inventory = read_inventory( os.path.join(os.getcwd(), inventories_dir, filename)) data.append(_main(segment, config, raw_trace, wrong_inventory)) data[-1]['outlier'] = True data[-1]['modified'] = "INVFILE:%s" % filename ret = pd.concat(data, sort=False, ignore_index=True, copy=True, axis=0) ret['amplitude_ratio'] = amp_ratio ret['event_id'] = segment.event_id ret['station_id'] = segment.station.id ret['event_time'] = segment.event.time ret['channel_code'] = channel_code ret['magnitude'] = segment.event.magnitude ret['distance_km'] = segment.event_distance_km return ret finally: sys.stdout = temp