def __get_stream(self, start_time: UTCDateTime, end_time: UTCDateTime) -> Stream: st = ObspyUtil.merge_files_to_stream( [self.path_z, self.path_n, self.path_e]) ObspyUtil.trim_stream(st, start_time, end_time) self.start_time = st[0].stats.starttime self.end_time = st[0].stats.endtime return st
def get_waveform(self, filter_error_callback=None, **kwargs): filter_value = kwargs.get("filter_value", Filters.Default) f_min = kwargs.get("f_min", 0.) f_max = kwargs.get("f_max", 0.) start_time = kwargs.get("start_time", self.stats.StartTime) end_time = kwargs.get("end_time", self.stats.EndTime) tr = self.tracer tr.detrend(type="demean") try: if not ObspyUtil.filter_trace(tr, filter_value, f_min, f_max): self.__send_filter_error_callback( filter_error_callback, "Lower frequency {} must be " "smaller than Upper frequency {}".format(f_min, f_max)) except ValueError as e: print(e) self.__send_filter_error_callback(filter_error_callback, str(e)) try: tr.trim(starttime=start_time, endtime=end_time) except: print("Please Check Starttime and Endtime") return tr
def get_metadata(self, file_path): self.__metadata_files = MseedUtil.get_dataless_files(self.__root_path) #self.__metadata_files = MseedUtil.get_xml_files(self.__root_path) mseed_stats = ObspyUtil.get_stats(file_path) metadata = self.check_metadata(self.__metadata_files, mseed_stats) return metadata
def __init__(self, data, **kwargs): """ Class to apply wavelet convolution to a mseed file. The bank of atoms is computed at the class initialisation. :param data: Either the mseed file path or an obspy Tracer. :keyword kwargs: :keyword wmin: Minimum number of cycles. Default = 6. :keyword wmax: Maximum number of cycles. Default = 6. :keyword tt: Period of the Morlet Wavelet. Default = 2. :keyword fmin: Minimum Central frequency (in Hz). Default = 2. :keyword fmax: Maximum Central frequency (in Hz). Default = 12. :keyword m: Parameter for Paul Wavelet. Default = 30. :keyword nf: Number of logarithmically spaced frequencies between fmin and fmax. Default = 20. :keyword use_wavelet: Default = Complex Morlet :keyword use_rfft: True if it should use rfft instead of fft. Default = True. :keyword decimate: True if it should try to decimate the trace. Default = False. The decimation factor is equal to q = 0.4*SR/fmax. For SR=200Hz and fmax=40Hz, q=2. This will downsize the sample rate to 100 Hz. :raise InvalidFile: If file is not a valid mseed. :example: >>> cw = ConvolveWavelet(data) >>> cw.setup_wavelet() >>> sc = cw.scalogram_in_dbs >>> cf = cw.cf_lowpass() """ if isinstance(data, Trace): self.stats = TracerStats.from_dict(data.stats) self.trace: Trace = data else: if not MseedUtil.is_valid_mseed(data): raise InvalidFile("The file: {} is not a valid mseed.".format(data)) self.trace: Trace = read(data)[0] self.stats = ObspyUtil.get_stats(data) self._wmin = float(kwargs.get("wmin", 6.)) self._wmax = float(kwargs.get("wmax", 6.)) self._tt = float(kwargs.get("tt", 2.)) self._fmin = float(kwargs.get("fmin", 2.)) self._fmax = float(kwargs.get("fmax", 12.)) self._nf = int(kwargs.get("nf", 20)) self._use_wavelet = kwargs.get("use_wavelet", "Complex Morlet") self._m = int(kwargs.get("m", 30)) self._use_rfft = kwargs.get("use_rfft", False) self._decimate = kwargs.get("decimate", False) self._validate_kwargs() # print(self.stats) self._data = None self._npts = 0 self._tf = None self._start_time = self.stats.StartTime self._end_time = self.stats.EndTime self._sample_rate = self.stats.Sampling_rate self._frex = None self._n_cycles = None self._wtime = None self._half_wave = None
def plot_cwt_spectrogram(self, canvas: MatplotlibCanvas): tr = ObspyUtil.get_tracer_from_file(self.file_selector.file_path) ts, te = self.get_time_window() tr.trim(starttime=ts, endtime=te) tr.detrend(type="demean") fs = tr.stats.sampling_rate f_min = 1. / self.spectrum_box.win_bind.value if self.filter.min_freq == 0 else self.filter.min_freq f_max = self.filter.max_freq ObspyUtil.filter_trace(tr, self.filter.filter_value, f_min, f_max) nf = 40 tt = int(self.spectrum_box.win_bind.value * self.tracer_stats.Sampling_rate) wmin = self.spectrum_box.w1_bind.value wmax = self.spectrum_box.w2_bind.value npts = len(tr.data) [ba, nConv, frex, half_wave] = ccwt_ba_fast(npts, self.tracer_stats.Sampling_rate, f_min, f_max, wmin, wmax, tt, nf) cf, sc, scalogram = cwt_fast(tr.data, ba, nConv, frex, half_wave, fs) #scalogram = ccwt(tr.data, self.tracer_stats.Sampling_rate, f_min, f_max, wmin, wmax, tt, nf) scalogram = np.abs(scalogram)**2 t = np.linspace(0, self.tracer_stats.Delta * npts, npts) scalogram2 = 10 * (np.log10(scalogram / np.max(scalogram))) x, y = np.meshgrid(t, np.linspace(f_min, f_max, scalogram2.shape[0])) max_cwt = np.max(scalogram2) min_cwt = np.min(scalogram2) canvas.plot(t[0:len(t) - 1], cf, 0, clear_plot=False, is_twinx=True, color="red", linewidth=0.5) norm = Normalize(vmin=min_cwt, vmax=max_cwt) canvas.plot_contour(x, y, scalogram2, axes_index=1, clabel="Power [dB]", levels=100, cmap=plt.get_cmap("jet"), norm=norm) canvas.set_xlabel(1, "Time (s)")
def plot_map_stations(self): md = MessageDialog(self) md.hide() try: stations = [] obsfiles = MseedUtil.get_mseed_files(self.root_path_bind.value) obsfiles.sort() try: if len(self.stream) > 0: stations = ObspyUtil.get_stations_from_stream(self.stream) except: pass map_dict = {} sd = [] for file in obsfiles: if len(stations) == 0: st = SeismogramDataAdvanced(file) name = st.stats.Network + "." + st.stats.Station sd.append(name) st_coordinates = self.__metadata_manager.extract_coordinates( self.inventory, file) map_dict[name] = [ st_coordinates.Latitude, st_coordinates.Longitude ] else: st = SeismogramDataAdvanced(file) if st.stats.Station in stations: name = st.stats.Network + "." + st.stats.Station sd.append(name) st_coordinates = self.__metadata_manager.extract_coordinates( self.inventory, file) map_dict[name] = [ st_coordinates.Latitude, st_coordinates.Longitude ] else: pass self.map_stations = StationsMap(map_dict) self.map_stations.plot_stations_map(latitude=self.latDB.value(), longitude=self.lonDB.value()) md.set_info_message("Station Map OK !!! ") except: md.set_error_message( " Please check you have process and plot seismograms and opened stations info," "Please additionally check that your metada fits with your mseed files" ) md.show()
def extrac_coordinates_from_trace(self, inventory, trace): stats = ObspyUtil.get_stats_from_trace(trace) selected_inv = inventory.select(network=stats['net'], station=stats['station'], channel=stats['channel'], starttime=stats['starttime'], endtime=stats['endtime']) cont = selected_inv.get_contents() coords = selected_inv.get_coordinates(cont['channels'][0]) return StationCoordinates.from_dict(coords)
def _readHypFile(self, file_abs_path): origin: Origin = ObspyUtil.reads_hyp_to_origin(file_abs_path) try: event_model = EventLocationModel.create_from_origin(origin) event_model.save() except AttributeError: # TODO: what to do if it is already inserted? event_model = EventLocationModel.find_by(latitude=origin.latitude, longitude=origin.longitude, depth=origin.depth, origin_time=origin.time.datetime) return event_model
def get_station_stats_by_mseed_file(self, file_path: str): mseed_stats = ObspyUtil.get_stats(file_path) return mseed_stats
def get_waveform_advanced(self, parameters, inventory, filter_error_callback=None, **kwargs): start_time = kwargs.get("start_time", self.stats.StartTime) end_time = kwargs.get("end_time", self.stats.EndTime) trace_number = kwargs.get("trace_number", 0) tr = self.tracer tr.trim(starttime=start_time, endtime=end_time) N = len(parameters) for j in range(N): if parameters[j][0] == 'rmean': tr.detrend(type=parameters[j][1]) if parameters[j][0] == 'taper': tr.taper(max_percentage=parameters[j][2], type=parameters[j][1]) if parameters[j][0] == 'normalize': if parameters[j][1] == 0: tr.normalize(norm=None) else: tr.normalize(norm=parameters[j][1]) if parameters[j][0] == "differentiate": tr.differentiate(method=parameters[j][1]) if parameters[j][0] == "integrate": tr.integrate(method=parameters[j][1]) if parameters[j][0] == 'filter': filter_value = parameters[j][1] f_min = parameters[j][2] f_max = parameters[j][3] zero_phase = parameters[j][4] poles = parameters[j][5] try: if not ObspyUtil.filter_trace(tr, filter_value, f_min, f_max, corners=poles, zerophase=zero_phase): self.__send_filter_error_callback( filter_error_callback, "Lower frequency {} must be " "smaller than Upper frequency {}".format( f_min, f_max)) except ValueError as e: self.__send_filter_error_callback(filter_error_callback, str(e)) if parameters[j][0] == "wiener filter": print("applying wiener filter") time_window = parameters[j][1] noise_power = parameters[j][2] print(time_window, noise_power) tr = wiener_filter(tr, time_window=time_window, noise_power=noise_power) if parameters[j][0] == 'shift': shifts = parameters[j][1] for c, value in enumerate(shifts, 1): if value[0] == trace_number: tr.stats.starttime = tr.stats.starttime + value[1] if parameters[j][0] == 'remove response': f1 = parameters[j][1] f2 = parameters[j][2] f3 = parameters[j][3] f4 = parameters[j][4] water_level = parameters[j][5] units = parameters[j][6] pre_filt = (f1, f2, f3, f4) if inventory and units != "Wood Anderson": #print("Deconvolving") try: tr.remove_response(inventory=inventory, pre_filt=pre_filt, output=units, water_level=water_level) except: print("Coudn't deconvolve", tr.stats) tr.data = np.array([]) elif inventory and units == "Wood Anderson": #print("Simulating Wood Anderson Seismograph") resp = inventory.get_response(tr.id, tr.stats.starttime) resp = resp.response_stages[0] paz_wa = { 'sensitivity': 2800, 'zeros': [0j], 'gain': 1, 'poles': [-6.2832 - 4.7124j, -6.2832 + 4.7124j] } paz_mine = { 'sensitivity': resp.stage_gain * resp.normalization_factor, 'zeros': resp.zeros, 'gain': resp.stage_gain, 'poles': resp.poles } try: tr.simulate(paz_remove=paz_mine, paz_simulate=paz_wa, water_level=water_level) except: print("Coudn't deconvolve", tr.stats) tr.data = np.array([]) if parameters[j][0] == 'add white noise': tr = add_white_noise(tr, parameters[j][1]) if parameters[j][0] == 'whitening': tr = whiten(tr, parameters[j][1], taper_edge=parameters[j][2]) if parameters[j][0] == 'remove spikes': tr = hampel(tr, parameters[j][1], parameters[j][2]) if parameters[j][0] == 'time normalization': tr = normalize(tr, norm_win=parameters[j][1], norm_method=parameters[j][2]) if parameters[j][0] == 'wavelet denoise': tr = wavelet_denoise(tr, dwt=parameters[j][1], threshold=parameters[j][2]) if parameters[j][0] == 'resample': tr.resample(sampling_rate=parameters[j][1], window='hanning', no_filter=parameters[j][2]) if parameters[j][0] == 'fill gaps': st = Stream(tr) st.merge(fill_value=parameters[j][1]) tr = st[0] if parameters[j][0] == 'smoothing': tr = smoothing(tr, type=parameters[j][1], k=parameters[j][2], fwhm=parameters[j][3]) return tr
def get_NLL_info(self) -> Origin: location_file = os.path.join(self.get_loc_dir, "last.hyp") return ObspyUtil.reads_hyp_to_origin(location_file)
def trace(self): return ObspyUtil.get_tracer_from_file(self.file_selector.file_path)
def plot_egfs(self): if self.st: del self.st self.canvas.clear() ## self.nums_clicks = 0 all_traces = [] if self.sortCB.isChecked(): if self.comboBox_sort.currentText() == "Distance": self.files_path.sort(key=self.sort_by_distance_advance) elif self.comboBox_sort.currentText() == "Back Azimuth": self.files_path.sort(key=self.sort_by_baz_advance) self.set_pagination_files(self.files_path) files_at_page = self.get_files_at_page() ## if len(self.canvas.axes) != len(files_at_page): self.canvas.set_new_subplot(nrows=len(files_at_page), ncols=1) last_index = 0 min_starttime = [] max_endtime = [] parameters = self.parameters.getParameters() for index, file_path in enumerate(files_at_page): if os.path.basename(file_path) != ".DS_Store": sd = SeismogramDataAdvanced(file_path) tr = sd.get_waveform_advanced( parameters, self.inventory, filter_error_callback=self.filter_error_message, trace_number=index) print(tr.data) if len(tr) > 0: t = tr.times("matplotlib") s = tr.data self.canvas.plot_date(t, s, index, color="black", fmt='-', linewidth=0.5) if self.pagination.items_per_page >= 16: ax = self.canvas.get_axe(index) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.tick_params(top=False) ax.tick_params(labeltop=False) if index != (self.pagination.items_per_page - 1): ax.tick_params(bottom=False) last_index = index st_stats = ObspyUtil.get_stats(file_path) if st_stats and self.sortCB.isChecked() == False: info = "{}.{}.{}".format(st_stats.Network, st_stats.Station, st_stats.Channel) self.canvas.set_plot_label(index, info) elif st_stats and self.sortCB.isChecked( ) and self.comboBox_sort.currentText() == "Distance": dist = self.sort_by_distance_advance(file_path) dist = "{:.1f}".format(dist / 1000.0) info = "{}.{}.{} Distance {} km".format( st_stats.Network, st_stats.Station, st_stats.Channel, str(dist)) self.canvas.set_plot_label(index, info) elif st_stats and self.sortCB.isChecked( ) and self.comboBox_sort.currentText() == "Back Azimuth": back = self.sort_by_baz_advance(file_path) back = "{:.1f}".format(back) info = "{}.{}.{} Back Azimuth {}".format( st_stats.Network, st_stats.Station, st_stats.Channel, str(back)) self.canvas.set_plot_label(index, info) try: min_starttime.append(min(t)) max_endtime.append(max(t)) except: print("Empty traces") all_traces.append(tr) self.st = Stream(traces=all_traces) try: if min_starttime and max_endtime is not None: auto_start = min(min_starttime) auto_end = max(max_endtime) self.auto_start = auto_start self.auto_end = auto_end ax = self.canvas.get_axe(last_index) ax.set_xlim(mdt.num2date(auto_start), mdt.num2date(auto_end)) formatter = mdt.DateFormatter('%y/%m/%d/%H:%M:%S.%f') ax.xaxis.set_major_formatter(formatter) self.canvas.set_xlabel(last_index, "Date") except: pass
def tracer_stats(self): return ObspyUtil.get_stats(self.file_selector.file_path)