Example #1
0
 def __init__(self, origin, inventory, chop):
     super(MagnitudeCalc, self).__init__()
     self.setupUi(self)
     self.spectrum_Widget_Canvas = MatplotlibCanvas(self.spectrumWidget,
                                                    nrows=2,
                                                    ncols=1,
                                                    sharex=False,
                                                    constrained_layout=True)
     self.event = origin
     self.chop = chop
     self.inventory = inventory
     self.runBtn.clicked.connect(self.run_magnitudes)
     self.saveBtn.clicked.connect(self.save_results)
     self.plotBtn.clicked.connect(self.plot_comparison)
     self.Mw = []
     self.Mw_std = []
     self.Ms = []
     self.Ms_std = []
     self.Mb = []
     self.Mb_std = []
     self.ML = []
     self.ML_std = []
     self.Mc = []
     self.Mc_std = []
     self.ML = []
     self.ML_std = []
     self.Magnitude_Ws = []
     self.Mss = []
     self.Mcs = []
     self.Mcs = []
     self.MLs = []
    def __init__(self, parent, current_index=-1, parent_name=None):

        super(TimeAnalysisWidget, self).__init__()
        self.setupUi(self)
        ParentWidget.set_parent(parent, self, current_index)

        if parent_name:  # add parent name if given. Helps to make difference between the same widget
            self.parent_name = parent_name

        # embed matplotlib to qt widget
        self.canvas = MatplotlibCanvas(self.plotMatWidget, nrows=2)
        self.canvas.set_xlabel(1, "Time (s)")
        self.canvas.on_double_click(self.on_double_click_matplotlib)

        self.time_selector = TimeSelectorBox(self.PlotToolsWidget, 0)
        self.filter = FilterBox(self.PlotToolsWidget, 1)
        self.spectrum_box = SpectrumBox(self.PlotToolsWidget, 3)
        self.station_info = StationInfoBox(self.PlotToolsWidget, 4)

        # bind buttons
        self.plotSeismogramBtn.clicked.connect(
            lambda: self.on_click_plot_seismogram(self.canvas))
        self.plotArrivalsBtn.clicked.connect(
            lambda: self.on_click_plot_arrivals(self.canvas))
        self.spectrum_box.register_plot_mtp(
            lambda: self.on_click_mtp(self.canvas))
        self.spectrum_box.register_plot_cwt(
            lambda: self.on_click_cwt(self.canvas))

        self.__file_selector = None
        self.__event_info = None
        self.is_envelop_checked = False
Example #3
0
    def __init__(self, parameters, settings):
        super(EGFFrame, self).__init__()
        self.setupUi(self)

        self.parameters = parameters
        self.settings_dialog = settings

        self.progressbar = pw.QProgressDialog(self)
        self.progressbar.setWindowTitle('Ambient Noise Tomography')
        self.progressbar.setLabelText(" Computing ")
        self.progressbar.setWindowIcon(pqg.QIcon(':\icons\map-icon.png'))
        self.progressbar.close()

        self.inventory = {}
        self.files = []
        self.total_items = 0
        self.items_per_page = 1
        self.__dataless_manager = None
        self.__metadata_manager = None
        self.st = None
        self.output = None
        self.root_path_bind = BindPyqtObject(self.rootPathForm,
                                             self.onChange_root_path)
        self.root_path_bind2 = BindPyqtObject(self.rootPathForm2,
                                              self.onChange_root_path)
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.updateBtn.clicked.connect(self.plot_egfs)
        self.output_bind = BindPyqtObject(self.outPathForm,
                                          self.onChange_root_path)
        self.pagination = Pagination(self.pagination_widget, self.total_items,
                                     self.items_per_page)
        self.pagination.set_total_items(0)

        self.canvas = MatplotlibCanvas(self.plotMatWidget,
                                       nrows=self.items_per_page,
                                       constrained_layout=False)
        self.canvas.set_xlabel(0, "Time (s)")
        self.canvas.figure.tight_layout()

        # Bind buttons

        self.readFilesBtn.clicked.connect(lambda: self.get_now_files())
        self.selectDirBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind))
        self.selectDirBtn2.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind2))
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.selectDatalessDirBtn.clicked.connect(
            lambda: self.on_click_select_file(self.metadata_path_bind))
        self.outputBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.output_bind))
        self.preprocessBtn.clicked.connect(self.run_preprocess)
        self.cross_stackBtn.clicked.connect(self.stack)
        self.mapBtn.clicked.connect(self.map)
Example #4
0
    def __init__(self, parent: pw.QWidget = None):

        super(SyntheticsAnalisysFrame, self).__init__(parent)

        self.setupUi(self)
        ParentWidget.set_parent(parent, self)
        self.setWindowTitle('Synthetics Analysis Frame')
        self.setWindowIcon(pqg.QIcon(':\icons\pen-icon.png'))

        #Initialize parametrs for plot rotation
        self._z = {}
        self._r = {}
        self._t = {}
        self._st = {}
        self.inventory = {}
        parameters = {}

        self._generator = SyntheticsGeneratorDialog(self)

        # 3C_Component
        self.focmec_canvas = FocCanvas(self.widget_fp)
        self.canvas = MatplotlibCanvas(self.plotMatWidget_3C)
        self.canvas.set_new_subplot(3, ncols=1)

        # Map
        self.cartopy_canvas = CartopyCanvas(self.map_widget)

        # binds
        self.root_path_bind_3C = BindPyqtObject(self.rootPathForm_3C, self.onChange_root_path_3C)
        self.vertical_form_bind = BindPyqtObject(self.verticalQLineEdit)
        self.north_form_bind = BindPyqtObject(self.northQLineEdit)
        self.east_form_bind = BindPyqtObject(self.eastQLineEdit)
        self.generation_params_bind = BindPyqtObject(self.paramsPathLineEdit)

        # accept drops
        self.vertical_form_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.north_form_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.east_form_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.generation_params_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.paramsPathLineEdit.textChanged.connect(self._generationParamsChanged)

        # Add file selector to the widget
        self.file_selector = FilesView(self.root_path_bind_3C.value, parent=self.fileSelectorWidget)
        self.file_selector.setDragEnabled(True)

        self.selectDirBtn_3C.clicked.connect(self.on_click_select_directory_3C)
        self.plotBtn.clicked.connect(self.on_click_rotate)
        ###
        self.stationsBtn.clicked.connect(self.stationsInfo)
        ###

        self.actionGenerate_synthetics.triggered.connect(lambda : self._generator.show())
Example #5
0
    def __init__(self, parent: pw.QWidget):

        super(Earthquake3CFrame, self).__init__(parent)

        self.setupUi(self)
        ParentWidget.set_parent(parent, self)
        #Initialize parametrs for plot rotation
        self._z = {}
        self._r = {}
        self._t = {}
        self._st = {}
        self.inventory = {}
        #self.filter_3ca = FilterBox(self.toolQFrame, 1)  # add filter box component.
        self.parameters = ParametersSettings()

        # 3C_Component
        self.canvas = MatplotlibCanvas(self.plotMatWidget_3C)
        self.canvas.set_new_subplot(3, ncols=1)
        self.canvas_pol = MatplotlibCanvas(self.Widget_polarization)
        self.canvas.mpl_connect('key_press_event', self.key_pressed)
        # binds
        self.root_path_bind_3C = BindPyqtObject(self.rootPathForm_3C,
                                                self.onChange_root_path_3C)
        self.degreeSB_bind = BindPyqtObject(self.degreeSB)
        self.vertical_form_bind = BindPyqtObject(self.verticalQLineEdit)
        self.north_form_bind = BindPyqtObject(self.northQLineEdit)
        self.east_form_bind = BindPyqtObject(self.eastQLineEdit)

        # accept drops
        self.vertical_form_bind.accept_dragFile(
            drop_event_callback=self.drop_event)
        self.north_form_bind.accept_dragFile(
            drop_event_callback=self.drop_event)
        self.east_form_bind.accept_dragFile(
            drop_event_callback=self.drop_event)

        # Add file selector to the widget
        self.file_selector = FilesView(self.root_path_bind_3C.value,
                                       parent=self.fileSelectorWidget)
        self.file_selector.setDragEnabled(True)

        self.selectDirBtn_3C.clicked.connect(self.on_click_select_directory_3C)
        self.rotateplotBtn.clicked.connect(
            lambda: self.on_click_rotate(self.canvas))
        self.rot_macroBtn.clicked.connect(
            lambda: self.open_parameters_settings())
        self.polarizationBtn.clicked.connect(self.on_click_polarization)
        ###
        self.plotpolBtn.clicked.connect(self.plot_particle_motion)
        self.stationsBtn.clicked.connect(self.stationsInfo)
        self.save_rotatedBtn.clicked.connect(self.save_rotated)
Example #6
0
    def __init__(self):

        super(TimeFrequencyFrame, self).__init__()
        self.setupUi(self)
        self.__stations_dir = None
        self.__metadata_manager = None
        self.inventory = {}
        self._stations_info = {}
        self.tr1 = []
        self.tr2 = []
        self.canvas_plot1 = MatplotlibCanvas(self.widget_plot_up, nrows=2)
        # self.canvas_plot1.set_xlabel(1, "Time (s)")
        # self.canvas_plot1.set_ylabel(0, "Amplitude ")
        # self.canvas_plot1.set_ylabel(1, "Frequency (Hz)")
        self.canvas_plot2 = MatplotlibCanvas(self.widget_plot_down, nrows=2)
        # self.canvas_plot2.set_xlabel(1, "Time (s)")
        # self.canvas_plot2.set_ylabel(0, "Amplitude ")
        # self.canvas_plot2.set_ylabel(1, "Frequency (Hz)")
        # Binding
        self.canvas_plot1.mpl_connect('key_press_event', self.key_pressed)
        self.canvas_plot2.mpl_connect('key_press_event', self.key_pressed)
        self.root_path_bind = BindPyqtObject(self.rootPathForm,
                                             self.onChange_root_path)
        self.dataless_path_bind = BindPyqtObject(self.datalessPathForm)
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        # Add file selector to the widget
        self.file_selector = FilesView(
            self.root_path_bind.value,
            parent=self.fileSelectorWidget,
            on_change_file_callback=lambda file_path: self.onChange_file(
                file_path))
        # Binds
        self.selectDirBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind))
        self.datalessBtn.clicked.connect(
            lambda: self.on_click_select_file(self.dataless_path_bind))
        # Action Buttons
        self.actionSettings.triggered.connect(
            lambda: self.open_parameters_settings())
        self.actionOpen_Help.triggered.connect(lambda: self.open_help())
        self.actionOpen_Spectral_Analysis.triggered.connect(
            self.time_frequency_advance)
        self.plotBtn.clicked.connect(self.plot_seismogram)
        self.stationsBtn.clicked.connect(self.stations_info)

        # help Documentation
        self.help = HelpDoc()

        # Parameters settings
        self.parameters = ParametersSettings()
Example #7
0
 def __init__(self, z, r, t):
     super(PlotPolarization, self).__init__()
     self.setupUi(self)
     self._z = z-np.mean(z)
     self._r = r-np.mean(r)
     self._t = t-np.mean(t)
     all_traces = [self._z, self._r, self._t]
     self.st = Stream(traces=all_traces)
     self._r_max = max(r)
     self._t_max = max(t)
     self._z_max=max(z)
     self.max_value=max([max(abs(z)), max(abs(t)), max(abs(r))])
     self.canvas = MatplotlibCanvas(self.plotMatWidget_polarization)
     self.canvas2D = MatplotlibCanvas(self.plotMatWidget_polarization2, nrows=2, ncols=2, constrained_layout=True)
     self.canvas.figure.gca(projection='3d')
     self.plotBtn.clicked.connect(lambda: self.plot_particle())
Example #8
0
    def __init__(self):
        super(FrequencyTimeFrame, self).__init__()
        self.setupUi(self)
        self.solutions = []
        self.periods_now = []
        self.colors = ["white", "green", "black"]
        self._stations_info = {}
        self.parameters = ParametersSettings()
        # Binds
        self.root_path_bind = BindPyqtObject(self.rootPathForm_2, self.onChange_root_path)
        self.canvas_plot1 = MatplotlibCanvas(self.widget_plot_up, ncols=2, sharey  = True)
        top = 0.900
        bottom = 0.180
        left = 0.045
        right = 0.720
        wspace = 0.135
        self.canvas_plot1.figure.subplots_adjust(left=left, bottom=bottom, right=right, top=top, wspace=wspace, hspace=0.0)

        ax = self.canvas_plot1.get_axe(0)
        left,width = 0.2, 0.55
        bottom, height = 0.180, 0.72
        spacing = 0.02
        coords_ax = [left+width+spacing, bottom, 0.2, height]
        self.fig = ax.get_figure()
        #self.ax_seism1 = self.fig.add_axes(coords_ax, sharey = ax)
        self.ax_seism1 = self.fig.add_axes(coords_ax)
        self.ax_seism1.yaxis.tick_right()


        # Add file selector to the widget
        self.file_selector = FilesView(self.root_path_bind.value, parent=self.fileSelectorWidget_2,
                                       on_change_file_callback=lambda file_path: self.onChange_file(file_path))

        # Binds
        self.selectDirBtn_2.clicked.connect(lambda: self.on_click_select_directory(self.root_path_bind))

        # action
        self.plotBtn.clicked.connect(self.plot_seismogram)
        self.plot2Btn.clicked.connect(self.run_phase_vel)
        self.stationsBtn.clicked.connect(self.stations_info)
        self.macroBtn.clicked.connect(lambda: self.open_parameters_settings())
        # clicks
        self.canvas_plot1.on_double_click(self.on_click_matplotlib)
        self.canvas_plot1.mpl_connect('key_press_event', self.key_pressed)
Example #9
0
    def __init__(self, st, inv, t1, t2):
        super(Vespagram, self).__init__()
        self.setupUi(self)
        """
        Vespagram, computed a fixed slowness or backazimuth

        :param params required to initialize the class:
            
        
        """

        self.st = st
        self.inv = inv
        self.t1 = t1
        self.t2 = t2
        self.canvas_vespagram = MatplotlibCanvas(self.widget_vespagram,
                                                 nrows=2)
        self.run_vespaBtn.clicked.connect(self.run_vespa)
        self.plotBtn.clicked.connect(self.plot_vespa)
    def plot_mt_spectrogram(self, canvas: MatplotlibCanvas):
        win = int(self.spectrum_box.win_bind.value *
                  self.tracer_stats.Sampling_rate)
        tbp = self.spectrum_box.tw_bind.value
        ntapers = self.spectrum_box.ntapers_bind.value
        f_min = self.filter.min_freq
        f_max = self.filter.max_freq
        ts, te = self.get_time_window()

        mtspectrogram = MTspectrogram(self.file_selector.file_path, win, tbp,
                                      ntapers, f_min, f_max)
        x, y, log_spectrogram = mtspectrogram.compute_spectrogram(
            start_time=ts, end_time=te, trace_filter=self.filter.filter_value)
        canvas.plot_contour(x,
                            y,
                            log_spectrogram,
                            axes_index=1,
                            clabel="Power [dB]",
                            cmap=plt.get_cmap("jet"))
        canvas.set_xlabel(1, "Time (s)")
Example #11
0
    def __init__(self, parent: pw.QWidget):
        super(EarthquakeLocationFrame, self).__init__(parent)

        self.setupUi(self)
        ParentWidget.set_parent(parent, self)
        self.__pick_output_path = PickerManager.get_default_output_path()
        self.__dataless_dir = None
        self.__nll_manager = None
        self.__first_polarity = None

        # Map
        self.cartopy_canvas = CartopyCanvas(self.widget_map)
        # Canvas for Earthquake Location Results
        self.residuals_canvas = MatplotlibCanvas(self.plotMatWidget_residuals)
        #self.residuals_canvas.figure.subplots_adjust(left = 0.03, bottom = 0.36, right=0.97, top=0.95, wspace=0.2,
        #                                         hspace=0.0)

        # Canvas for FOCMEC  Results
        self.focmec_canvas = FocCanvas(self.widget_focmec)
        self.grid_latitude_bind = BindPyqtObject(self.gridlatSB)
        self.grid_longitude_bind = BindPyqtObject(self.gridlonSB)
        self.grid_depth_bind = BindPyqtObject(self.griddepthSB)
        self.grid_xnode_bind = BindPyqtObject(self.xnodeSB)
        self.grid_ynode_bind = BindPyqtObject(self.ynodeSB)
        self.grid_znode_bind = BindPyqtObject(self.znodeSB)
        self.grid_dxsize_bind = BindPyqtObject(self.dxsizeSB)
        self.grid_dysize_bind = BindPyqtObject(self.dysizeSB)
        self.grid_dzsize_bind = BindPyqtObject(self.dzsizeSB)

        self.genvelBtn.clicked.connect(lambda: self.on_click_run_vel_to_grid())
        self.grdtimeBtn.clicked.connect(
            lambda: self.on_click_run_grid_to_time())
        self.runlocBtn.clicked.connect(lambda: self.on_click_run_loc())
        self.plotmapBtn.clicked.connect(lambda: self.on_click_plot_map())
        self.stationsBtn.clicked.connect(
            lambda: self.on_click_select_metadata_file())
        self.firstpolarityBtn.clicked.connect(self.first_polarity)
        self.plotpdfBtn.clicked.connect(self.plot_pdf)
Example #12
0
    def __init__(self, tr1, tr2):
        super(TimeFrequencyAdvance, self).__init__()
        self.setupUi(self)
        self.spectrum_Widget_Canvas = MatplotlibCanvas(self.spectrumWidget, nrows=2, ncols=2,
                                                      sharex=False, constrained_layout=True)

        self.spectrum_Widget_Canvas2 = MatplotlibCanvas(self.spectrumWidget2, nrows=1, ncols=1,
                                                      sharex=False, constrained_layout=True)

        self.coherence_Widget_Canvas = MatplotlibCanvas(self.coherenceWidget, nrows=2, ncols=1, sharex=False,
                                                       constrained_layout=True)
        self.cross_correlation_Widget_Canvas = MatplotlibCanvas(self.cross_correlationWidget, nrows = 3, ncols = 1)

        self.cross_spectrumWidget_Widget_Canvas = MatplotlibCanvas(self.cross_spectrumWidget,nrows = 2, ncols = 1,
                                sharex=True, constrained_layout=True)


        self.plot_spectrumBtn.clicked.connect(self.plot_spectrum)
        self.coherenceBtn.clicked.connect(self.coherence)
        self.cross_correlationsBtn.clicked.connect(self.plot_correlation)
        #self.Cross_spectrumBtn.clicked.connect(self.plot_cross_spectrogram)
        self.Cross_scalogramBtn.clicked.connect(self.plot_cross_scalogram)
        self.tr1 = tr1
        self.tr2 = tr2
    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)")
Example #14
0
class MagnitudeCalc(pw.QFrame, UiMagnitudeFrame, metaclass=SettingsLoader):
    def __init__(self, origin, inventory, chop):
        super(MagnitudeCalc, self).__init__()
        self.setupUi(self)
        self.spectrum_Widget_Canvas = MatplotlibCanvas(self.spectrumWidget,
                                                       nrows=2,
                                                       ncols=1,
                                                       sharex=False,
                                                       constrained_layout=True)
        self.event = origin
        self.chop = chop
        self.inventory = inventory
        self.runBtn.clicked.connect(self.run_magnitudes)
        self.saveBtn.clicked.connect(self.save_results)
        self.plotBtn.clicked.connect(self.plot_comparison)
        self.Mw = []
        self.Mw_std = []
        self.Ms = []
        self.Ms_std = []
        self.Mb = []
        self.Mb_std = []
        self.ML = []
        self.ML_std = []
        self.Mc = []
        self.Mc_std = []
        self.ML = []
        self.ML_std = []
        self.Magnitude_Ws = []
        self.Mss = []
        self.Mcs = []
        self.Mcs = []
        self.MLs = []

    def closeEvent(self, ce):
        self.save_values()

    def __load__(self):
        self.load_values()

    def moment_magnitude(self):
        density = self.densityDB.value()
        vp = self.vpDB.value() * 1000
        vs = self.vsDB.value() * 1000

        if self.phaseCB.currentText() == 'P-Wave':
            radiation_pattern = 0.52
            velocity = vp
            k = 0.32
        elif self.phaseCB.currentText() == "S-Wave":
            radiation_pattern = 0.63
            velocity = vs
            k = 0.21

        Mws = []
        Mws_std = []
        Magnitude_Ws = []
        origin_time = self.event.time
        moments = []
        source_radii = []
        corner_frequencies = []
        corner_freqs = []
        self.spectrum_Widget_Canvas.plot([], [], 0)
        ax1 = self.spectrum_Widget_Canvas.get_axe(0)
        ax1.cla()

        for key in self.chop['Body waves']:

            magnitude_dict = self.chop['Body waves'][key]
            # Calculate distance
            coords = get_coordinates_from_metadata(self.inventory,
                                                   magnitude_dict[0])
            dist, _, _ = gps2dist_azimuth(coords.Latitude, coords.Longitude,
                                          self.event.latitude,
                                          self.event.longitude)
            pick_time = UTCDateTime(mdt.num2date(magnitude_dict[1][0]))
            data = np.array(magnitude_dict[2])

            delta = 1 / magnitude_dict[0][6]

            # Calculate the spectrum.

            spec, freq, jackknife_errors, _, _ = mtspec(data,
                                                        delta=delta,
                                                        time_bandwidth=3.5,
                                                        statistics=True)
            spec = spec[1:]
            freq = freq[1:]
            # go to amplitude and displacement
            spec = np.sqrt(spec) / (2 * np.pi * freq)
            # Plot spectrum

            ax1.loglog(freq,
                       spec,
                       '0.1',
                       linewidth=0.5,
                       color='black',
                       alpha=0.5)
            ax1.set_ylim(spec.min() / 10.0, spec.max() * 100.0)
            ax1.set_xlim(freq[1], freq[len(freq) - 1])
            ax1.set_ylabel('Amplitude')
            ax1.set_xlabel('Frequency [Hz]')
            ax1.grid(True, which="both", ls="-", color='grey')
            ax1.legend()

            # Finish Plot
            tt = pick_time - origin_time
            #print("Distance",dist,"Vp",vp,"Q",quality,"Density",density, "Travel Time", tt)

            # Q as a function of freq
            Qo = self.qualityDB.value()
            a = self.coeffDB.value()
            quality = (Qo) * (freq)**a

            try:
                fit = fit_spectrum(spec, freq, tt, spec.max(), 10.0, quality)
            except:
                continue

            if fit is None:
                continue

            Omega_0, f_c, err, _ = fit

            # Second Plot

            theoretical_spectrum = calculate_source_spectrum(
                freq, Omega_0, f_c, quality, tt)
            ax1.loglog(freq,
                       theoretical_spectrum,
                       color="red",
                       alpha=0.5,
                       lw=0.5)
            ax1.set_xlim(freq[1], freq[len(freq) - 1])
            ax1.set_ylabel('Amplitude')
            ax1.set_xlabel('Frequency [Hz]')
            ax1.grid(True, which="both", ls="-", color='grey')

            corner_freqs.append(f_c)
            M_0 = 4.0 * np.pi * density * velocity**3 * dist * np.sqrt(
                Omega_0**2) / radiation_pattern
            Magnitude_Ws.append(2.0 / 3.0 * (np.log10(M_0) - 9.1))
            r = 3 * k * vs / sum(corner_freqs)
            moments.append(M_0)
            source_radii.append(r)
            corner_frequencies.extend(corner_freqs)

        # Calculate the seismic moment via basic statistics.
        moments = np.array(moments)
        moment = moments.mean()
        moment_std = moments.std()

        corner_frequencies = np.array(corner_frequencies)
        corner_frequency = corner_frequencies.mean()
        corner_frequency_std = corner_frequencies.std()

        # Calculate the source radius.
        source_radii = np.array(source_radii)
        source_radius = source_radii.mean()
        self.source_radius = source_radius
        source_radius_std = source_radii.std()

        # Calculate the stress drop of the event based on the average moment and
        # source radii.
        stress_drop = (7 * moment) / (16 * source_radius**3)
        stress_drop_std = np.sqrt((stress_drop ** 2) * \
                                  (((moment_std ** 2) / (moment ** 2)) + \
                                   (9 * source_radius * source_radius_std ** 2)))
        if source_radius > 0 and source_radius_std < source_radius:
            print("Source radius:", source_radius, " Std:", source_radius_std)
            print("Stress drop:", stress_drop / 1E5, " Std:",
                  stress_drop_std / 1E5)

        self.stress_drop = stress_drop
        self.Magnitude_Ws = Magnitude_Ws
        Mw = 2.0 / 3.0 * (np.log10(moment) - 9.1)
        Mw_std = 2.0 / 3.0 * moment_std / (moment * np.log(10))
        Mws_std.append(Mw_std)
        Mws.append(Mw)
        print("Moment Magnitude", Mws, "Moment Magnitude deviation", Mws_std)
        label = "Mw"
        self.plot_histograms(Magnitude_Ws, label)
        self.Mw = Mw
        self.Mw_std = Mw_std

    def magnitude_surface(self):
        Ms = []
        for key in self.chop['Surf Waves']:
            magnitude_dict = self.chop['Surf Waves'][key]

            coords = get_coordinates_from_metadata(self.inventory,
                                                   magnitude_dict[0])

            dist = locations2degrees(coords.Latitude, coords.Longitude,
                                     self.event.latitude, self.event.longitude)
            data = np.array(magnitude_dict[2]) * 1e6  # convert to nm
            Ms_value = np.log10(np.max(data) /
                                (2 * np.pi)) + 1.66 * np.log10(dist) + 3.3
            Ms.append(Ms_value)

        Ms = np.array(Ms)
        self.Mss = Ms
        Ms_mean = Ms.mean()
        Ms_deviation = Ms.std()
        print("Surface Magnitude", Ms_mean, "Variance", Ms_deviation)
        label = "Ms"
        self.plot_histograms(Ms, label)
        self.Ms = Ms_mean
        self.Ms_std = Ms_deviation

    def magnitude_body(self):
        Mb = []
        path_to_atenuation_file = os.path.join(ROOT_DIR,
                                               "earthquakeAnalisysis",
                                               "magnitude_atenuation",
                                               "atenuation.txt")
        x, y = np.loadtxt(path_to_atenuation_file, skiprows=1, unpack=True)

        for key in self.chop['Body waves']:
            magnitude_dict = self.chop['Body waves'][key]
            coords = get_coordinates_from_metadata(self.inventory,
                                                   magnitude_dict[0])
            dist = locations2degrees(coords.Latitude, coords.Longitude,
                                     self.event.latitude, self.event.longitude)
            dist = np.floor(dist)
            if dist < 16:
                print(
                    "Epicentral Distance ", dist,
                    " is less than 16 degrees, Body-wave Magnitude couldn't be calculated"
                )
            else:
                loc = np.where(x == dist)[0][0]
                atenuation = y[loc]
                data = np.array(magnitude_dict[2]) * 1e6  # convert to nm
                Mb_value = (np.log10(np.max(data)) / (2 * np.pi)) + atenuation
                Mb.append(Mb_value)
                Mbs = np.array(Mb)
                Mb_mean = Mbs.mean()
                Mb_deviation = Mb.std()
                self.Mb = Mb_mean
                self.Mb_std = Mb_deviation
                print("Body Magnitude", Mb_mean, "Variance", Mb_deviation)
        label = "Mb"
        self.Mbs = Mbs
        if len(Mb) > 0:
            self.plot_histograms(Mb, label)

    def magnitude_coda(self):
        Mc = []
        # values for california
        a = 2.0
        b = 0.0035
        c = -0.87
        #
        for key in self.chop['Coda']:
            magnitude_dict = self.chop['Coda'][key]
            coords = get_coordinates_from_metadata(self.inventory,
                                                   magnitude_dict[0])
            dist, _, _ = gps2dist_azimuth(coords.Latitude, coords.Longitude,
                                          self.event.latitude,
                                          self.event.longitude)
            dist = dist / 1000
            #data = np.array(magnitude_dict[2])
            pick_time = UTCDateTime(mdt.num2date(magnitude_dict[1][0]))
            end_time = UTCDateTime(mdt.num2date(magnitude_dict[1][-1]))
            t_coda = end_time - pick_time
            Mc_value = a * np.log10(t_coda) + b * dist + c
            Mc_value = Mc_value
            Mc.append(Mc_value)
            Mcs = np.array(Mc)
            Mc_mean = Mcs.mean()
            Mc_deviation = Mcs.std()

        print("Coda Magnitude", Mc_mean, "Variance", Mc_deviation)
        label = "Mc"
        self.plot_histograms(Mc, label)
        self.Mcs = Mcs
        self.Mc = Mc_mean
        self.Mc_std = Mc_deviation

    def magnitude_local(self):
        ML = []
        for key in self.chop['Body waves']:
            magnitude_dict = self.chop['Body waves'][key]
            coords = get_coordinates_from_metadata(self.inventory,
                                                   magnitude_dict[0])
            dist, _, _ = gps2dist_azimuth(coords.Latitude, coords.Longitude,
                                          self.event.latitude,
                                          self.event.longitude)
            dist = dist / 1000
            data = np.array(
                magnitude_dict[2]
            )  # already converted Wood Anderson (Gain in mm 2800 +-60)
            max_amplitude = np.max(data) * 1e3  # convert to  mm --> nm
            ML_value = np.log10(
                max_amplitude) + 1.11 * np.log10(dist) + 0.00189 * dist - 2.09
            ML.append(ML_value)
            MLs = np.array(ML)
            ML_mean = MLs.mean()
            ML_deviation = MLs.std()
        print("Local Magnitude", ML_mean, "Variance", ML_deviation)
        label = "ML"
        self.MLs = MLs
        self.plot_histograms(ML, label)
        self.ML = ML_mean
        self.ML_std = ML_deviation

    def run_magnitudes(self):
        self.spectrum_Widget_Canvas.plot([], [], 1)
        self.ax2 = self.spectrum_Widget_Canvas.get_axe(1)
        self.ax2.cla()

        if self.local_magnitudeRB.isChecked():
            print("Calculating Local Magnitude")
            try:
                self.magnitude_local()
            except:
                pass

        if self.magnitudesRB.isChecked():
            try:
                if self.body_waveCB.isChecked():
                    print("Calculating Body-Wave Magnitude")
                    self.magnitude_body()
            except:
                pass
            try:
                if self.surface_waveCB.isChecked():
                    print("Calculating Surface-Wave Magnitude")
                    self.magnitude_surface()
            except:
                pass
            try:
                if self.moment_magnitudeCB.isChecked():
                    print("Calculating Moment Magnitude")
                    self.moment_magnitude()
            except:
                pass

            try:
                if self.coda_magnitudeCB.isChecked():
                    print("Coda Moment Magnitude")
                    self.magnitude_coda()
            except:
                pass

        self.print_magnitudes_results()

    def print_magnitudes_results(self):
        self.magnitudesText.setPlainText(" Magnitudes Estimation Results ")
        try:
            if self.Mw:
                self.magnitudesText.appendPlainText(
                    "Moment Magnitude: "
                    " Mw {Mw:.3f} "
                    " std {std:.3f} "
                    "Source Radious {source:.3f} "
                    "Stress Drop {stress:.3E} ".format(
                        Mw=self.Mw,
                        std=self.Mw_std,
                        source=self.source_radius / 1000,
                        stress=self.stress_drop))

        except:
            pass

        try:
            if self.Ms:
                self.magnitudesText.appendPlainText("Surface-Wave Magnitude: "
                                                    " Ms {Ms:.3f} "
                                                    " std {std:.3f} ".format(
                                                        Ms=self.Ms,
                                                        std=self.Ms_std))
        except:
            pass
        try:
            if self.Mb:
                self.magnitudesText.appendPlainText("Body-Wave Magnitude: "
                                                    " Mb {Mb:.3f} "
                                                    " std {std:.3f} ".format(
                                                        Mb=self.Mb,
                                                        std=self.Mb_std))
        except:
            pass
        try:
            if self.Mc:
                self.magnitudesText.appendPlainText("Coda Magnitude: "
                                                    " Mc {Mc:.3f} "
                                                    " std {std:.3f} ".format(
                                                        Mc=self.Mc,
                                                        std=self.Mc_std))
        except:
            pass
        try:
            if self.ML:
                self.magnitudesText.appendPlainText("Coda Magnitude: "
                                                    " ML {ML:.3f} "
                                                    " std {std:.3f} ".format(
                                                        ML=self.ML,
                                                        std=self.ML_std))
        except:
            pass

    def save_results(self):
        import pandas as pd
        path_output = os.path.join(ROOT_DIR, "earthquakeAnalisysis",
                                   "location_output", "loc",
                                   "magnitudes_output.mag")
        Magnitude_results = {
            'Magnitudes': [
                "Mw", "Mw_std", "Ms", "Ms_std", "Mb", "Mb_std", "Mc", "Mc_std",
                "ML", "ML_std"
            ],
            'results': [
                self.Mw, self.Mw_std, self.Ms, self.Ms_std, self.Mb,
                self.Mb_std, self.Mc, self.Mc_std, self.ML, self.ML_std
            ]
        }
        df = pd.DataFrame(Magnitude_results, columns=['Magnitudes', 'results'])
        print(df)
        df.to_csv(path_output, sep=' ', index=False)

    def plot_histograms(self, magnitudes, label):

        self.ax2.hist(magnitudes,
                      bins=4 * len(magnitudes),
                      alpha=0.5,
                      label=label)
        self.ax2.set_xlabel("Magnitude", size=12)
        self.ax2.set_ylabel("Count", size=12)
        self.ax2.legend(loc='upper right')

    def plot_comparison(self):
        import matplotlib.pyplot as plt
        from isp.Gui.Frames import MatplotlibFrame
        list_magnitudes = []
        labels = []
        if len(self.Magnitude_Ws) >= 0:
            list_magnitudes.append(self.Magnitude_Ws)
            labels.append("Mw")
        if len(self.Mss) >= 0:
            list_magnitudes.append(self.Mss)
            labels.append("Ms")
        if len(self.Mcs) >= 0:
            list_magnitudes.append(self.Mcs)
            labels.append("Mc")
        if len(self.MLs) >= 0:
            labels.append("ML")
            list_magnitudes.append(self.MLs)
        fig, ax1 = plt.subplots(figsize=(6, 6))
        self.mpf = MatplotlibFrame(fig)
        k = 0
        for magnitude in list_magnitudes:
            label = labels[k]
            x = np.arange(len(magnitude)) + 1
            ax1.scatter(x, magnitude, s=15, alpha=0.5, label=label)
            ax1.tick_params(direction='in', labelsize=10)
            ax1.legend(loc='upper right')
            plt.ylabel('Magnitudes', fontsize=10)
            plt.xlabel('Counts', fontsize=10)
            k = k + 1

        self.mpf.show()
Example #15
0
class EarthquakeLocationFrame(pw.QFrame, UiEarthquakeLocationFrame):
    def __init__(self, parent: pw.QWidget):
        super(EarthquakeLocationFrame, self).__init__(parent)

        self.setupUi(self)
        ParentWidget.set_parent(parent, self)
        self.__pick_output_path = PickerManager.get_default_output_path()
        self.__dataless_dir = None
        self.__nll_manager = None
        self.__first_polarity = None

        # Map
        self.cartopy_canvas = CartopyCanvas(self.widget_map)
        # Canvas for Earthquake Location Results
        self.residuals_canvas = MatplotlibCanvas(self.plotMatWidget_residuals)
        #self.residuals_canvas.figure.subplots_adjust(left = 0.03, bottom = 0.36, right=0.97, top=0.95, wspace=0.2,
        #                                         hspace=0.0)

        # Canvas for FOCMEC  Results
        self.focmec_canvas = FocCanvas(self.widget_focmec)
        self.grid_latitude_bind = BindPyqtObject(self.gridlatSB)
        self.grid_longitude_bind = BindPyqtObject(self.gridlonSB)
        self.grid_depth_bind = BindPyqtObject(self.griddepthSB)
        self.grid_xnode_bind = BindPyqtObject(self.xnodeSB)
        self.grid_ynode_bind = BindPyqtObject(self.ynodeSB)
        self.grid_znode_bind = BindPyqtObject(self.znodeSB)
        self.grid_dxsize_bind = BindPyqtObject(self.dxsizeSB)
        self.grid_dysize_bind = BindPyqtObject(self.dysizeSB)
        self.grid_dzsize_bind = BindPyqtObject(self.dzsizeSB)

        self.genvelBtn.clicked.connect(lambda: self.on_click_run_vel_to_grid())
        self.grdtimeBtn.clicked.connect(
            lambda: self.on_click_run_grid_to_time())
        self.runlocBtn.clicked.connect(lambda: self.on_click_run_loc())
        self.plotmapBtn.clicked.connect(lambda: self.on_click_plot_map())
        self.stationsBtn.clicked.connect(
            lambda: self.on_click_select_metadata_file())
        self.firstpolarityBtn.clicked.connect(self.first_polarity)
        self.plotpdfBtn.clicked.connect(self.plot_pdf)

    @property
    def nll_manager(self):
        if not self.__nll_manager:
            self.__nll_manager = NllManager(self.__pick_output_path,
                                            self.__dataless_dir)
        return self.__nll_manager

    @property
    def firstpolarity_manager(self):
        if not self.__first_polarity:
            self.__first_polarity = FirstPolarity()
        return self.__first_polarity

    def on_click_select_metadata_file(self):
        selected = pw.QFileDialog.getOpenFileName(
            self, "Select metadata/stations coordinates file")
        if isinstance(selected[0], str) and os.path.isfile(selected[0]):
            self.stationsPath.setText(selected[0])
            self.set_dataless_dir(self.stationsPath.text())

    def set_dataless_dir(self, dir_path):
        self.__dataless_dir = dir_path
        self.nll_manager.set_dataless_dir(dir_path)

    def set_pick_output_path(self, file_path):
        self.__pick_output_path = file_path
        self.nll_manager.set_observation_file(file_path)

    def info_message(self, msg, detailed_message=None):
        md = MessageDialog(self)
        md.set_info_message(msg, detailed_message)

    def subprocess_feedback(self, err_msg: str, set_default_complete=True):
        """
        This method is used as a subprocess feedback. It runs when a raise expect is detected.

        :param err_msg: The error message from the except.
        :param set_default_complete: If True it will set a completed successfully message. Otherwise nothing will
            be displayed.
        :return:
        """
        if err_msg:
            md = MessageDialog(self)
            if "Error code" in err_msg:
                md.set_error_message(
                    "Click in show details detail for more info.", err_msg)
            else:
                md.set_warning_message("Click in show details for more info.",
                                       err_msg)
        else:
            if set_default_complete:
                md = MessageDialog(self)
                md.set_info_message("Completed Successfully.")

    @parse_excepts(lambda self, msg: self.subprocess_feedback(msg))
    def on_click_run_vel_to_grid(self):
        self.nll_manager.vel_to_grid(
            self.grid_latitude_bind.value, self.grid_longitude_bind.value,
            self.grid_depth_bind.value, self.grid_xnode_bind.value,
            self.grid_ynode_bind.value, self.grid_znode_bind.value,
            self.grid_dxsize_bind.value, self.grid_dysize_bind.value,
            self.grid_dzsize_bind.value, self.comboBox_gridtype.currentText(),
            self.comboBox_wavetype.currentText(), self.modelCB.currentText())

    @parse_excepts(lambda self, msg: self.subprocess_feedback(msg))
    def on_click_run_grid_to_time(self):

        if self.distanceSB.value() > 0:
            limit = self.distanceSB.value()
        else:
            limit = np.sqrt(
                (self.grid_xnode_bind.value * self.grid_dxsize_bind.value)**2 +
                (self.grid_xnode_bind.value * self.grid_dxsize_bind.value)**2)

        self.nll_manager.grid_to_time(self.grid_latitude_bind.value,
                                      self.grid_longitude_bind.value,
                                      self.grid_depth_bind.value,
                                      self.comboBox_grid.currentText(),
                                      self.comboBox_angles.currentText(),
                                      self.comboBox_ttwave.currentText(),
                                      limit)

    @parse_excepts(lambda self, msg: self.subprocess_feedback(
        msg, set_default_complete=False))
    def on_click_run_loc(self):
        transform = self.transCB.currentText()
        std_out = self.nll_manager.run_nlloc(self.grid_latitude_bind.value,
                                             self.grid_longitude_bind.value,
                                             self.grid_depth_bind.value,
                                             transform)
        self.info_message("Location complete. Check details.", std_out)

    @parse_excepts(lambda self, msg: self.subprocess_feedback(msg))
    def on_click_plot_map(self):
        origin = self.nll_manager.get_NLL_info()
        scatter_x, scatter_y, scatter_z, pdf = self.nll_manager.get_NLL_scatter(
        )
        lat = origin.latitude
        lon = origin.longitude
        stations = self.nll_manager.stations_match()

        self.cartopy_canvas.plot_map(lon,
                                     lat,
                                     scatter_x,
                                     scatter_y,
                                     scatter_z,
                                     0,
                                     resolution='high',
                                     stations=stations)
        # Writing Location information
        self.add_earthquake_info(origin)
        xp, yp, xs, ys = self.nll_manager.ger_NLL_residuals()
        self.plot_residuals(xp, yp, xs, ys)

    def plot_pdf(self):
        scatter_x, scatter_y, scatter_z, pdf = self.nll_manager.get_NLL_scatter(
        )
        self.pdf = PDFmanger(scatter_x, scatter_y, scatter_z, pdf)
        self.pdf.plot_scatter()

    def plot_residuals(self, xp, yp, xs, ys):

        artist = self.residuals_canvas.plot(xp,
                                            yp,
                                            axes_index=0,
                                            linewidth=0.5)
        self.residuals_canvas.set_xlabel(0, "Station")
        self.residuals_canvas.set_ylabel(0, "P wave Res")
        self.residuals_canvas.set_yaxis_color(self.residuals_canvas.get_axe(0),
                                              artist.get_color(),
                                              is_left=True)
        self.residuals_canvas.plot(xs,
                                   ys,
                                   0,
                                   is_twinx=True,
                                   color="red",
                                   linewidth=0.5)
        self.residuals_canvas.set_ylabel_twinx(0, "S wave Res")
        self.residuals_canvas.plot(xp, yp, axes_index=0, linewidth=0.5)

    def first_polarity(self):
        import pandas as pd
        path_output = os.path.join(ROOT_DIR, "earthquakeAnalisysis",
                                   "location_output", "loc",
                                   "first_polarity.fp")
        self.firstpolarity_manager.create_input()
        self.firstpolarity_manager.run_focmec()
        Station, Az, Dip, Motion = self.firstpolarity_manager.get_dataframe()
        cat, Plane_A = self.firstpolarity_manager.extract_focmec_info()
        #print(cat[0].focal_mechanisms[0])
        strike_A = Plane_A.strike
        dip_A = Plane_A.dip
        rake_A = Plane_A.rake
        misfit_first_polarity = cat[0].focal_mechanisms[0].misfit
        azimuthal_gap = cat[0].focal_mechanisms[0].azimuthal_gap
        number_of_polarities = cat[0].focal_mechanisms[
            0].station_polarity_count

        first_polarity_results = {
            "First_Polarity": [
                "Strike", "Dip", "Rake", "misfit_first_polarity",
                "azimuthal_gap", "number_of_polarities"
            ],
            "results": [
                strike_A, dip_A, rake_A, misfit_first_polarity, azimuthal_gap,
                number_of_polarities
            ]
        }
        df = pd.DataFrame(first_polarity_results,
                          columns=["First_Polarity", "results"])
        df.to_csv(path_output, sep=' ', index=False)
        self.focmec_canvas.drawFocMec(strike_A, dip_A, rake_A, Station, Az,
                                      Dip, Motion, 0)
        self.add_first_polarity_info(first_polarity_results)

    def add_first_polarity_info(self, first_polarity_results):
        self.FirstPolarityInfoText.setPlainText("First Polarity Results")
        self.FirstPolarityInfoText.appendPlainText(
            "Strike: {Strike:.3f}".format(
                Strike=first_polarity_results["results"][0]))
        self.FirstPolarityInfoText.appendPlainText(
            "Dip: {Dip:.3f}".format(Dip=first_polarity_results["results"][1]))
        self.FirstPolarityInfoText.appendPlainText("Rake: {Rake:.3f}".format(
            Rake=first_polarity_results["results"][2]))
        self.FirstPolarityInfoText.appendPlainText(
            "Misfit: {Misfit:.3f}".format(
                Misfit=first_polarity_results["results"][3]))
        self.FirstPolarityInfoText.appendPlainText(
            "GAP: {GAP:.3f}".format(GAP=first_polarity_results["results"][4]))
        self.FirstPolarityInfoText.appendPlainText(
            "Number of polarities: {NP:.3f}".format(
                NP=first_polarity_results["results"][5]))

    def add_earthquake_info(self, origin: Origin):

        self.EarthquakeInfoText.setPlainText(
            "  Origin time and RMS:     {origin_time}     {standard_error:.3f}"
            .format(origin_time=origin.time,
                    standard_error=origin.quality.standard_error))
        self.EarthquakeInfoText.appendPlainText(
            "  Hypocenter Geographic Coordinates:     "
            "Latitude {lat:.3f} "
            "Longitude {long:.3f}     Depth {depth:.3f}     "
            "Uncertainty {unc:.3f}".format(
                lat=origin.latitude,
                long=origin.longitude,
                depth=origin.depth / 1000,
                unc=origin.depth_errors['uncertainty']))
        self.EarthquakeInfoText.appendPlainText(
            "  Horizontal Ellipse:     Max Horizontal Err {:.3f}     "
            "Min Horizontal Err {:.3f}     "
            "Azimuth {:.3f}".format(
                origin.origin_uncertainty.max_horizontal_uncertainty,
                origin.origin_uncertainty.min_horizontal_uncertainty,
                origin.origin_uncertainty.azimuth_max_horizontal_uncertainty))

        self.EarthquakeInfoText.appendPlainText(
            "  Quality Parameters:     Number of Phases {:.3f}     "
            "Azimuthal GAP {:.3f}     Minimum Distance {:.3f}     "
            "Maximum Distance {:.3f}".format(origin.quality.used_phase_count,
                                             origin.quality.azimuthal_gap,
                                             origin.quality.minimum_distance,
                                             origin.quality.maximum_distance))
Example #16
0
class Vespagram(pw.QFrame, UiVespagram):
    def __init__(self, st, inv, t1, t2):
        super(Vespagram, self).__init__()
        self.setupUi(self)
        """
        Vespagram, computed a fixed slowness or backazimuth

        :param params required to initialize the class:
            
        
        """

        self.st = st
        self.inv = inv
        self.t1 = t1
        self.t2 = t2
        self.canvas_vespagram = MatplotlibCanvas(self.widget_vespagram,
                                                 nrows=2)
        self.run_vespaBtn.clicked.connect(self.run_vespa)
        self.plotBtn.clicked.connect(self.plot_vespa)

    def closeEvent(self, ce):
        self.save_values()

    def __load__(self):
        self.load_values()

    #@AsycTime.run_async()
    def run_vespa(self):

        vespa = vespagram_util(self.st,
                               self.freq_min_DB.value(),
                               self.freq_max_DB.value(),
                               self.win_len_DB.value(),
                               self.slownessDB.value(),
                               self.backazimuthCB.value(),
                               self.inv,
                               self.t1,
                               self.t2,
                               self.overlapSB.value(),
                               selection=self.selectionCB.currentText(),
                               method="FK")

        self.x, self.y, self.log_vespa_spectrogram = vespa.vespa_deg()
        md = MessageDialog(self)
        md.set_info_message("Vespagram Estimated !!!")

    def plot_vespa(self):

        if self.selectionCB.currentText() == "Slowness":
            self.__plot_vespa_slow()
        else:
            self.__plot_vespa_az()

    def __plot_vespa_slow(self):
        base_line = self.base_lineDB.value()
        colour = self.colourCB.currentText()
        #vespagram = np.clip(self.log_vespa_spectrogram, a_min=base_line, a_max=0)
        vespagram = np.clip(self.log_vespa_spectrogram, a_min=0, a_max=1)
        self.canvas_vespagram.plot_contour(self.x,
                                           self.y,
                                           vespagram,
                                           axes_index=0,
                                           clabel="Rel. Power",
                                           cmap=plt.get_cmap(colour))
        self.canvas_vespagram.set_xlabel(0, "Time (s)")
        self.canvas_vespagram.set_ylabel(0, "Azimuth")

    def __plot_vespa_az(self):
        base_line = self.base_lineDB.value()
        colour = self.colourCB.currentText()
        #vespagram = np.clip(self.log_vespa_spectrogram, a_min=base_line, a_max=0)
        vespagram = np.clip(self.log_vespa_spectrogram, a_min=0, a_max=1)
        self.canvas_vespagram.plot_contour(self.x,
                                           self.y,
                                           vespagram,
                                           axes_index=1,
                                           clabel="Rel Power",
                                           cmap=plt.get_cmap(colour))
        self.canvas_vespagram.set_xlabel(1, "Time (s)")
        self.canvas_vespagram.set_ylabel(1, "Slowness (s/km)")
Example #17
0
class Earthquake3CFrame(pw.QFrame, UiEarthquake3CFrame):
    def __init__(self, parent: pw.QWidget):

        super(Earthquake3CFrame, self).__init__(parent)

        self.setupUi(self)
        ParentWidget.set_parent(parent, self)
        #Initialize parametrs for plot rotation
        self._z = {}
        self._r = {}
        self._t = {}
        self._st = {}
        self.inventory = {}
        #self.filter_3ca = FilterBox(self.toolQFrame, 1)  # add filter box component.
        self.parameters = ParametersSettings()

        # 3C_Component
        self.canvas = MatplotlibCanvas(self.plotMatWidget_3C)
        self.canvas.set_new_subplot(3, ncols=1)
        self.canvas_pol = MatplotlibCanvas(self.Widget_polarization)
        self.canvas.mpl_connect('key_press_event', self.key_pressed)
        # binds
        self.root_path_bind_3C = BindPyqtObject(self.rootPathForm_3C,
                                                self.onChange_root_path_3C)
        self.degreeSB_bind = BindPyqtObject(self.degreeSB)
        self.vertical_form_bind = BindPyqtObject(self.verticalQLineEdit)
        self.north_form_bind = BindPyqtObject(self.northQLineEdit)
        self.east_form_bind = BindPyqtObject(self.eastQLineEdit)

        # accept drops
        self.vertical_form_bind.accept_dragFile(
            drop_event_callback=self.drop_event)
        self.north_form_bind.accept_dragFile(
            drop_event_callback=self.drop_event)
        self.east_form_bind.accept_dragFile(
            drop_event_callback=self.drop_event)

        # Add file selector to the widget
        self.file_selector = FilesView(self.root_path_bind_3C.value,
                                       parent=self.fileSelectorWidget)
        self.file_selector.setDragEnabled(True)

        self.selectDirBtn_3C.clicked.connect(self.on_click_select_directory_3C)
        self.rotateplotBtn.clicked.connect(
            lambda: self.on_click_rotate(self.canvas))
        self.rot_macroBtn.clicked.connect(
            lambda: self.open_parameters_settings())
        self.polarizationBtn.clicked.connect(self.on_click_polarization)
        ###
        self.plotpolBtn.clicked.connect(self.plot_particle_motion)
        self.stationsBtn.clicked.connect(self.stationsInfo)
        self.save_rotatedBtn.clicked.connect(self.save_rotated)
        ###

    def open_parameters_settings(self):
        self.parameters.show()

    def info_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    @staticmethod
    def drop_event(event: pqg.QDropEvent, bind_object: BindPyqtObject):
        data = event.mimeData()
        url = data.urls()[0]
        bind_object.value = url.fileName()

    @property
    def north_component_file(self):
        return os.path.join(self.root_path_bind_3C.value,
                            self.north_form_bind.value)

    @property
    def vertical_component_file(self):
        return os.path.join(self.root_path_bind_3C.value,
                            self.vertical_form_bind.value)

    @property
    def east_component_file(self):
        return os.path.join(self.root_path_bind_3C.value,
                            self.east_form_bind.value)

    def onChange_root_path_3C(self, value):
        """
        Fired every time the root_path is changed

        :param value: The path of the new directory.

        :return:
        """
        self.file_selector.set_new_rootPath(value)

    # Function added for 3C Components
    def on_click_select_directory_3C(self):

        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', self.root_path_bind_3C.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', self.root_path_bind_3C.value,
                pw.QFileDialog.DontUseNativeDialog)

        if dir_path:
            self.root_path_bind_3C.value = dir_path

    def set_times(self, st):

        max_start = np.max([tr.stats.starttime for tr in st])
        min_end = np.min([tr.stats.endtime for tr in st])

        return min_end, max_start

    def on_click_rotate(self, canvas):

        time1 = convert_qdatetime_utcdatetime(self.dateTimeEdit_4)
        time2 = convert_qdatetime_utcdatetime(self.dateTimeEdit_5)
        angle = self.degreeSB.value()
        incidence_angle = self.incidenceSB.value()
        method = self.methodCB.currentText()
        parameters = self.parameters.getParameters()

        try:
            sd = PolarizationAnalyis(self.vertical_component_file,
                                     self.north_component_file,
                                     self.east_component_file)

            time, z, r, t, st = sd.rotate(self.inventory,
                                          time1,
                                          time2,
                                          angle,
                                          incidence_angle,
                                          method=method,
                                          parameters=parameters,
                                          trim=True)
            self._z = z
            self._r = r
            self._t = t
            self._st = st
            rotated_seismograms = [z, r, t]
            for index, data in enumerate(rotated_seismograms):
                self.canvas.plot(time,
                                 data,
                                 index,
                                 color="black",
                                 linewidth=0.5)
                info = "{}.{}.{}".format(self._st[index].stats.network,
                                         self._st[index].stats.station,
                                         self._st[index].stats.channel)
                ax = self.canvas.get_axe(0)
                ax.set_xlim(sd.t1.matplotlib_date, sd.t2.matplotlib_date)
                formatter = mdt.DateFormatter('%Y/%m/%d/%H:%M:%S')
                ax.xaxis.set_major_formatter(formatter)
                self.canvas.set_plot_label(index, info)

            canvas.set_xlabel(2, "Time (s)")

        except InvalidFile:
            self.info_message(
                "Invalid mseed files. Please, make sure to select all the three components (Z, N, E) "
                "for rotate.")
        except ValueError as error:
            self.info_message(str(error))

    def on_click_polarization(self):
        time1 = convert_qdatetime_utcdatetime(self.dateTimeEdit_4)
        time2 = convert_qdatetime_utcdatetime(self.dateTimeEdit_5)
        sd = PolarizationAnalyis(self.vertical_component_file,
                                 self.north_component_file,
                                 self.east_component_file)
        try:
            var = sd.polarize(time1, time2, self.doubleSpinBox_winlen.value(),
                              self.freq_minDB.value(), self.freq_maxDB.value())

            artist = self.canvas_pol.plot(
                var['time'],
                var[self.comboBox_yaxis.currentText()],
                0,
                clear_plot=True,
                linewidth=0.5)
            self.canvas_pol.set_xlabel(0, "Time [s]")
            self.canvas_pol.set_ylabel(0, self.comboBox_yaxis.currentText())
            self.canvas_pol.set_yaxis_color(self.canvas_pol.get_axe(0),
                                            artist.get_color(),
                                            is_left=True)
            self.canvas_pol.plot(var['time'],
                                 var[self.comboBox_polarity.currentText()],
                                 0,
                                 is_twinx=True,
                                 color="red",
                                 linewidth=0.5)
            self.canvas_pol.set_ylabel_twinx(
                0, self.comboBox_polarity.currentText())
        except InvalidFile:
            self.info_message(
                "Invalid mseed files. Please, make sure to select all the three components (Z, N, E) "
                "for polarization.")
        except ValueError as error:
            self.info_message(str(error))

    def plot_particle_motion(self):
        self._plot_polarization = PlotPolarization(self._z, self._r, self._t)
        self._plot_polarization.show()

    def stationsInfo(self):
        files = []
        try:
            if self.vertical_component_file and self.north_component_file and self.east_component_file:
                files = [
                    self.vertical_component_file, self.north_component_file,
                    self.east_component_file
                ]
        except:
            pass

        sd = []
        if len(files) == 3:
            for file in files:
                try:
                    st = SeismogramDataAdvanced(file)

                    station = [
                        st.stats.Network, st.stats.Station, st.stats.Location,
                        st.stats.Channel, st.stats.StartTime, st.stats.EndTime,
                        st.stats.Sampling_rate, st.stats.Npts
                    ]

                    sd.append(station)
                except:
                    pass

            self._stations_info = StationsInfo(sd)
            self._stations_info.show()

    def save_rotated(self):
        import os
        root_path = os.path.dirname(os.path.abspath(__file__))

        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', root_path)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', root_path,
                pw.QFileDialog.DontUseNativeDialog)
        if self._st:
            n = len(self._st)
            for j in range(n):
                tr = self._st[j]
                t1 = tr.stats.starttime
                id = tr.id + "." + "D" + "." + str(t1.year) + "." + str(
                    t1.julday)
                print(tr.id, "Writing data processed")
                path_output = os.path.join(dir_path, id)
                tr.write(path_output, format="MSEED")

    def key_pressed(self, event):

        if event.key == 'q':
            x1, y1 = event.xdata, event.ydata
            tt = UTCDateTime(mdt.num2date(x1))
            set_qdatetime(tt, self.dateTimeEdit_4)
            self.canvas.draw_arrow(x1,
                                   0,
                                   arrow_label="st",
                                   color="purple",
                                   linestyles='--',
                                   picker=False)
            self.canvas.draw_arrow(x1,
                                   1,
                                   arrow_label="st",
                                   color="purple",
                                   linestyles='--',
                                   picker=False)
            self.canvas.draw_arrow(x1,
                                   2,
                                   arrow_label="st",
                                   color="purple",
                                   linestyles='--',
                                   picker=False)

        if event.key == 'e':
            x1, y1 = event.xdata, event.ydata
            tt = UTCDateTime(mdt.num2date(x1))
            set_qdatetime(tt, self.dateTimeEdit_5)
            self.canvas.draw_arrow(x1,
                                   0,
                                   arrow_label="et",
                                   color="purple",
                                   linestyles='--',
                                   picker=False)
            self.canvas.draw_arrow(x1,
                                   1,
                                   arrow_label="st",
                                   color="purple",
                                   linestyles='--',
                                   picker=False)
            self.canvas.draw_arrow(x1,
                                   2,
                                   arrow_label="st",
                                   color="purple",
                                   linestyles='--',
                                   picker=False)
Example #18
0
    def __init__(self):
        super(RealTimeFrame, self).__init__()
        self.setupUi(self)
        self.setWindowIcon(pqg.QIcon(':\\icons\\map-icon.png'))
        self.widget_map = None
        self.settings_dialog = SettingsDialog(self)
        self.inventory = {}
        self.files = []
        self.events_times = []
        self.total_items = 0
        self.items_per_page = 1
        self.__dataless_manager = None
        self.__metadata_manager = None
        self.st = None
        self.client = None
        self.stations_available = []
        self.data_dict = {}
        self.dataless_not_found = set(
        )  # a set of mseed files that the dataless couldn't find.
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.canvas = MatplotlibCanvas(self.plotMatWidget,
                                       nrows=self.numTracesCB.value(),
                                       constrained_layout=False)
        self.canvas.figure.tight_layout()
        self.timer_outdated = pyc.QTimer()
        self.timer_outdated.setInterval(1000)  # 1 second
        self.timer_outdated.timeout.connect(self.outdated_stations)

        # Binding
        self.root_path_bind = BindPyqtObject(self.rootPathForm)
        self.dataless_path_bind = BindPyqtObject(self.datalessPathForm)

        # Bind

        self.selectDirBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind))

        #self.selectDatalessDirBtn.clicked.connect(lambda: self.on_click_select_directory(self.dataless_path_bind))

        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.selectDatalessDirBtn.clicked.connect(
            lambda: self.on_click_select_metadata_file(self.metadata_path_bind
                                                       ))

        self.actionSet_Parameters.triggered.connect(
            lambda: self.open_parameters_settings())
        self.mapBtn.clicked.connect(self.show_map)
        # self.__metadata_manager = MetadataManager(self.dataless_path_bind.value)
        self.actionSet_Parameters.triggered.connect(
            lambda: self.open_parameters_settings())
        self.actionArray_Anlysis.triggered.connect(self.open_array_analysis)
        self.actionMoment_Tensor_Inversion.triggered.connect(
            self.open_moment_tensor)
        self.actionTime_Frequency_Analysis.triggered.connect(
            self.time_frequency_analysis)
        self.actionReceiver_Functions.triggered.connect(
            self.open_receiver_functions)
        self.actionOpen_Settings.triggered.connect(
            lambda: self.settings_dialog.show())
        self.actionOpen_Help.triggered.connect(lambda: self.open_help())
        self.RetrieveBtn.clicked.connect(self.retrieve_data)
        self.stopBtn.clicked.connect(self.stop)
        # Parameters settings
        self.parameters = ParametersSettings()
        # Earth Model Viewer
        self.earthmodel = EarthModelViewer()
        # help Documentation
        self.help = HelpDoc()
Example #19
0
class RealTimeFrame(BaseFrame, UiRealTimeFrame):
    def __init__(self):
        super(RealTimeFrame, self).__init__()
        self.setupUi(self)
        self.setWindowIcon(pqg.QIcon(':\\icons\\map-icon.png'))
        self.widget_map = None
        self.settings_dialog = SettingsDialog(self)
        self.inventory = {}
        self.files = []
        self.events_times = []
        self.total_items = 0
        self.items_per_page = 1
        self.__dataless_manager = None
        self.__metadata_manager = None
        self.st = None
        self.client = None
        self.stations_available = []
        self.data_dict = {}
        self.dataless_not_found = set(
        )  # a set of mseed files that the dataless couldn't find.
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.canvas = MatplotlibCanvas(self.plotMatWidget,
                                       nrows=self.numTracesCB.value(),
                                       constrained_layout=False)
        self.canvas.figure.tight_layout()
        self.timer_outdated = pyc.QTimer()
        self.timer_outdated.setInterval(1000)  # 1 second
        self.timer_outdated.timeout.connect(self.outdated_stations)

        # Binding
        self.root_path_bind = BindPyqtObject(self.rootPathForm)
        self.dataless_path_bind = BindPyqtObject(self.datalessPathForm)

        # Bind

        self.selectDirBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind))

        #self.selectDatalessDirBtn.clicked.connect(lambda: self.on_click_select_directory(self.dataless_path_bind))

        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.selectDatalessDirBtn.clicked.connect(
            lambda: self.on_click_select_metadata_file(self.metadata_path_bind
                                                       ))

        self.actionSet_Parameters.triggered.connect(
            lambda: self.open_parameters_settings())
        self.mapBtn.clicked.connect(self.show_map)
        # self.__metadata_manager = MetadataManager(self.dataless_path_bind.value)
        self.actionSet_Parameters.triggered.connect(
            lambda: self.open_parameters_settings())
        self.actionArray_Anlysis.triggered.connect(self.open_array_analysis)
        self.actionMoment_Tensor_Inversion.triggered.connect(
            self.open_moment_tensor)
        self.actionTime_Frequency_Analysis.triggered.connect(
            self.time_frequency_analysis)
        self.actionReceiver_Functions.triggered.connect(
            self.open_receiver_functions)
        self.actionOpen_Settings.triggered.connect(
            lambda: self.settings_dialog.show())
        self.actionOpen_Help.triggered.connect(lambda: self.open_help())
        self.RetrieveBtn.clicked.connect(self.retrieve_data)
        self.stopBtn.clicked.connect(self.stop)
        # Parameters settings
        self.parameters = ParametersSettings()
        # Earth Model Viewer
        self.earthmodel = EarthModelViewer()
        # help Documentation
        self.help = HelpDoc()

        # shortcuts

    @property
    def dataless_manager(self):
        if not self.__dataless_manager:
            self.__dataless_manager = DatalessManager(
                self.dataless_path_bind.value)
        return self.__dataless_manager

    def message_dataless_not_found(self):
        if len(self.dataless_not_found) > 1:
            md = MessageDialog(self)
            md.set_info_message("Metadata not found.")
        else:
            for file in self.dataless_not_found:
                md = MessageDialog(self)
                md.set_info_message("Metadata for {} not found.".format(file))

        self.dataless_not_found.clear()

    def subprocess_feedback(self, err_msg: str, set_default_complete=True):
        """
        This method is used as a subprocess feedback. It runs when a raise expect is detected.

        :param err_msg: The error message from the except.
        :param set_default_complete: If True it will set a completed successfully message. Otherwise nothing will
            be displayed.
        :return:
        """
        if err_msg:
            md = MessageDialog(self)
            if "Error code" in err_msg:
                md.set_error_message(
                    "Click in show details detail for more info.", err_msg)
            else:
                md.set_warning_message("Click in show details for more info.",
                                       err_msg)
        else:
            if set_default_complete:
                md = MessageDialog(self)
                md.set_info_message("Loaded Metadata Successfully.")

    def open_parameters_settings(self):
        self.parameters.show()

    def onChange_metadata_path(self, value):

        md = MessageDialog(self)
        try:

            self.__metadata_manager = MetadataManager(value)
            self.inventory = self.__metadata_manager.get_inventory()
            print(self.inventory)
            md.set_info_message(
                "Loaded Metadata, please check your terminal for further details"
            )

        except:

            md.set_error_message(
                "Something went wrong. Please check your metada file is a correct one"
            )

    def on_click_select_directory(self, bind: BindPyqtObject):
        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value,
                pw.QFileDialog.DontUseNativeDialog)

        if dir_path:
            bind.value = dir_path

    def on_click_select_metadata_file(self, bind: BindPyqtObject):
        selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file")
        if isinstance(selected[0], str) and os.path.isfile(selected[0]):
            bind.value = selected[0]

    def handle_data(self, tr):
        # If tr is not valid, discard it
        if not tr:
            return

        s = [tr.stats.network, tr.stats.station, tr.stats.channel]
        key = ".".join(s)
        outdated_tr = None

        if key in self.data_dict.keys():
            tr.data = np.float64(tr.data)
            current_tr = self.data_dict[key]
            # If received trace is in the same day as current, append received to current
            if current_tr.stats.endtime.julday == tr.stats.endtime.julday:
                self.data_dict[key] = self.data_dict[key] + tr

            else:
                # TODO: maybe the trace should have all the info and the save file only saves current day
                # TODO: so that way data is not erased on day change
                # If received trace has a part within current day, add it to current trace and save as outdated and
                # trim the trace to contain only next day's data
                if current_tr.stats.endtime.julday == tr.stats.starttime.julday:
                    day_start = datetime.datetime.combine(
                        tr.stats.endtime.date, datetime.time())
                    last_day = day_start - datetime.timedelta(microseconds=1)
                    outdated_tr = current_tr + tr.slice(
                        tr.stats.starttime, UTCDateTime(last_day), False)
                    tr.trim(UTCDateTime(day_start), tr.stats.endtime)
                # Set new day's trace as current
                self.data_dict[key] = tr

        else:
            # insert New Key
            tr.data = np.float64(tr.data)
            self.data_dict[key] = tr

        self.plot_seismogram()

        if self.widget_map is not None:
            station_list = self.get_station_info(tr)
            self.widget_map.plot_set_stations(station_list)

        if self.saveDataCB.isChecked():
            if outdated_tr is not None:
                self.write_trace(outdated_tr)
            self.write_trace(tr)

    def outdated_stations(self):
        # this method is run every t seconds to check and plot which stations do not send data
        outdated_stations = []
        outdated_traces = []
        # Outdated stations' traces will be erased from current list
        for key in list(self.data_dict.keys()):
            if self.data_dict[key].stats.endtime + 60 < UTCDateTime.now():
                outdated_traces.append(self.data_dict[key])
                outdated_stations.append(
                    self.get_station_info(outdated_traces[-1]))
                del self.data_dict[key]

        if outdated_stations:
            self.widget_map.plot_unset_stations(outdated_stations)

        if self.saveDataCB.isChecked():
            for tr in outdated_traces:
                self.write_trace(tr)

    def seedlink_error(self, tr):

        print("seedlink_error")

    def terminate_data(self, tr):

        print("terminate_data")

    @AsycTime.run_async()
    def retrieve_data(self, e):

        self.client = create_client(self.serverAddressForm.text(),
                                    on_data=self.handle_data,
                                    on_seedlink_error=self.seedlink_error,
                                    on_terminate=self.terminate_data)

        pyc.QMetaObject.invokeMethod(self.timer_outdated, 'start')

        for net in self.netForm.text().split(","):
            for sta in self.stationForm.text().split(","):
                for chn in self.channelForm.text().split(","):
                    self.client.select_stream(net, sta, chn)

        # self.client.on_data()
        self.client.run()
        # self.client.get_info(level="ALL")

    def plot_seismogram(self):
        # TODO: y axis should be independent for each subplot

        now = UTCDateTime.now()
        start_time = now - self.timewindowSB.value() * 60
        end_time = now + 30
        self.canvas.set_new_subplot(nrows=self.numTracesCB.value(),
                                    ncols=1,
                                    update=False)
        self.canvas.set_xlabel(self.numTracesCB.value() - 1,
                               "Date",
                               update=False)
        index = 0
        parameters = self.parameters.getParameters()
        for key, tr in self.data_dict.items():
            # sd = SeismogramDataAdvanced(file_path=None, stream=Stream(traces=tr), realtime=True)
            sd = SeismogramDataAdvanced(file_path=None,
                                        stream=tr,
                                        realtime=True)
            tr = sd.get_waveform_advanced(parameters, self.inventory)

            t = tr.times("matplotlib")
            s = tr.data
            info = "{}.{}.{}".format(tr.stats.network, tr.stats.station,
                                     tr.stats.channel)
            self.canvas.plot_date(t,
                                  s,
                                  index,
                                  clear_plot=False,
                                  update=False,
                                  color="black",
                                  fmt='-',
                                  linewidth=0.5)
            self.canvas.set_plot_label(index, info)
            ax = self.canvas.get_axe(index)

            if index == self.numTracesCB.value() - 1:
                ax.set_xlim(mdt.num2date(start_time.matplotlib_date),
                            mdt.num2date(end_time.matplotlib_date))

            index = index + 1

            formatter = mdt.DateFormatter('%y/%m/%d/%H:%M:%S')
            ax.xaxis.set_major_formatter(formatter)
        self.canvas.draw()
        # pyc.QCoreApplication.instance().processEvents()

    def stop(self):
        # TODO: not working. Maybe subclassing is necessary
        self.client.close()
        pyc.QMetaObject.invokeMethod(self.timer_outdated, 'stop')

    def write_trace(self, tr):
        t1 = tr.stats.starttime
        file_name = tr.id + "." + "D" + "." + str(t1.year) + "." + str(
            t1.julday)
        path_output = os.path.join(self.rootPathForm.text(), file_name)
        if os.path.exists(path_output):
            temp = tempfile.mkstemp()
            tr.write(temp[1], format="MSEED")
            with open(path_output, 'ab') as current:
                with open(temp[1], 'rb') as temp_bin:
                    current.write(temp_bin.read())
            os.remove(temp[1])
        else:
            tr.write(path_output, format="MSEED")

    def show_map(self):
        if self.inventory:
            self.widget_map = MapRealTime(self.inventory)
            try:
                self.widget_map.show()
            except:
                pass

    def get_station_info(self, tr):
        coordinates = {}
        net_ids = []
        sta_ids = []
        latitude = []
        longitude = []
        net_ids.append(tr.stats.network)
        sta_ids.append(tr.stats.station)
        coords = self.inventory.get_coordinates(tr.id)
        latitude.append(coords['latitude'])
        longitude.append(coords['longitude'])
        net_content = [net_ids, sta_ids, latitude, longitude]
        coordinates[tr.stats.network] = net_content

        return coordinates

    # TODO: this should be generic to be invoked from other windows
    def open_array_analysis(self):
        self.controller().open_array_window()

    def open_moment_tensor(self):
        self.controller().open_momentTensor_window()

    def time_frequency_analysis(self):
        self.controller().open_seismogram_window()

    def open_receiver_functions(self):
        self.controller().open_receiverFunctions()

    def controller(self):
        from isp.Gui.controllers import Controller
        return Controller()
Example #20
0
class EGFFrame(pw.QWidget, UiEGFFrame):
    def __init__(self, parameters, settings):
        super(EGFFrame, self).__init__()
        self.setupUi(self)

        self.parameters = parameters
        self.settings_dialog = settings

        self.progressbar = pw.QProgressDialog(self)
        self.progressbar.setWindowTitle('Ambient Noise Tomography')
        self.progressbar.setLabelText(" Computing ")
        self.progressbar.setWindowIcon(pqg.QIcon(':\icons\map-icon.png'))
        self.progressbar.close()

        self.inventory = {}
        self.files = []
        self.total_items = 0
        self.items_per_page = 1
        self.__dataless_manager = None
        self.__metadata_manager = None
        self.st = None
        self.output = None
        self.root_path_bind = BindPyqtObject(self.rootPathForm,
                                             self.onChange_root_path)
        self.root_path_bind2 = BindPyqtObject(self.rootPathForm2,
                                              self.onChange_root_path)
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.updateBtn.clicked.connect(self.plot_egfs)
        self.output_bind = BindPyqtObject(self.outPathForm,
                                          self.onChange_root_path)
        self.pagination = Pagination(self.pagination_widget, self.total_items,
                                     self.items_per_page)
        self.pagination.set_total_items(0)

        self.canvas = MatplotlibCanvas(self.plotMatWidget,
                                       nrows=self.items_per_page,
                                       constrained_layout=False)
        self.canvas.set_xlabel(0, "Time (s)")
        self.canvas.figure.tight_layout()

        # Bind buttons

        self.readFilesBtn.clicked.connect(lambda: self.get_now_files())
        self.selectDirBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind))
        self.selectDirBtn2.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind2))
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.selectDatalessDirBtn.clicked.connect(
            lambda: self.on_click_select_file(self.metadata_path_bind))
        self.outputBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.output_bind))
        self.preprocessBtn.clicked.connect(self.run_preprocess)
        self.cross_stackBtn.clicked.connect(self.stack)
        self.mapBtn.clicked.connect(self.map)

    @pyc.Slot()
    def _increase_progress(self):
        self.progressbar.setValue(self.progressbar.value() + 1)

    def filter_error_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    def onChange_root_path(self, value):
        """
        Fired every time the root_path is changed
        :param value: The path of the new directory.
        :return:
        """
        # self.read_files(value)
        pass

    def on_click_select_file(self, bind: BindPyqtObject):
        selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file")
        if isinstance(selected[0], str) and os.path.isfile(selected[0]):
            bind.value = selected[0]

    @parse_excepts(lambda self, msg: self.subprocess_feedback(msg))
    @AsycTime.run_async()
    def onChange_metadata_path(self, value):

        try:
            self.__metadata_manager = MetadataManager(value)
            self.inventory = self.__metadata_manager.get_inventory()
            print(self.inventory)
        except:
            raise FileNotFoundError("The metadata is not valid")

    def subprocess_feedback(self, err_msg: str, set_default_complete=True):
        """
        This method is used as a subprocess feedback. It runs when a raise expect is detected.
        :param err_msg: The error message from the except.
        :param set_default_complete: If True it will set a completed successfully message. Otherwise nothing will
            be displayed.
        :return:
        """
        if err_msg:
            md = MessageDialog(self)
            if "Error code" in err_msg:
                md.set_error_message(
                    "Click in show details detail for more info.", err_msg)
            else:
                md.set_warning_message("Click in show details for more info.",
                                       err_msg)
        else:
            if set_default_complete:
                md = MessageDialog(self)
                md.set_info_message(
                    "Loaded Metadata, please check your terminal for further details"
                )

    def on_click_select_directory(self, bind: BindPyqtObject):
        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value,
                pw.QFileDialog.DontUseNativeDialog)
        if dir_path:
            bind.value = dir_path

    def read_files(self, dir_path):
        md = MessageDialog(self)
        md.hide()
        try:
            self.progressbar.reset()
            self.progressbar.setLabelText(" Reading Files ")
            self.progressbar.setRange(0, 0)
            with ThreadPoolExecutor(1) as executor:
                self.ant = noise_organize(dir_path, self.inventory)
                self.ant.send_message.connect(self.receive_messages)

                def read_files_callback():
                    data_map, size, channels = self.ant.create_dict()
                    print(channels)
                    pyc.QMetaObject.invokeMethod(self.progressbar, 'accept')
                    return data_map, size, channels

                f = executor.submit(read_files_callback)
                self.progressbar.exec()
                self.data_map, self.size, self.channels = f.result()
                f.cancel()

            # self.ant.test()
            md.set_info_message("Readed data files Successfully")
        except:
            md.set_error_message(
                "Something went wrong. Please check your data files are correct mseed files"
            )

        md.show()

    def run_preprocess(self):
        self.params = self.settings_dialog.getParameters()
        self.read_files(self.root_path_bind.value)
        self.process()

    ####################################################################################################################

    def process(self):
        #
        self.process_ant = process_ant(self.output_bind.value, self.params,
                                       self.inventory)
        list_raw = self.process_ant.get_all_values(self.data_map)
        self.process_ant.create_all_dict_matrix(list_raw, self.channels)

    def stack(self):
        stack = noisestack(self.output_bind.value)
        stack.run_cross_stack()
        stack.rotate_horizontals()

    @pyc.pyqtSlot(str)
    def receive_messages(self, message):
        self.listWidget.addItem(message)

    def get_files_at_page(self):
        n_0 = (self.pagination.current_page -
               1) * self.pagination.items_per_page
        n_f = n_0 + self.pagination.items_per_page
        return self.files[n_0:n_f]

    def get_file_at_index(self, index):
        files_at_page = self.get_files_at_page()
        return files_at_page[index]

    def onChange_items_per_page(self, items_per_page):
        self.items_per_page = items_per_page

    def filter_error_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    def set_pagination_files(self, files_path):
        self.files = files_path
        self.total_items = len(self.files)
        self.pagination.set_total_items(self.total_items)

    def get_files(self, dir_path):
        files_path = MseedUtil.get_tree_hd5_files(self, dir_path, robust=False)
        self.set_pagination_files(files_path)
        # print(files_path)
        pyc.QMetaObject.invokeMethod(self.progressbar, 'accept',
                                     qt.AutoConnection)

        return files_path

    def get_now_files(self):

        md = MessageDialog(self)
        md.hide()
        try:

            self.progressbar.reset()
            self.progressbar.setLabelText(" Reading Files ")
            self.progressbar.setRange(0, 0)
            with ThreadPoolExecutor(1) as executor:
                f = executor.submit(
                    lambda: self.get_files(self.root_path_bind2.value))
                self.progressbar.exec()
                self.files_path = f.result()
                f.cancel()

            # self.files_path = self.get_files(self.root_path_bind.value)

            md.set_info_message("Readed data files Successfully")

        except:

            md.set_error_message(
                "Something went wrong. Please check your data files are correct mseed files"
            )

        md.show()

    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 sort_by_distance_advance(self, file):

        geodetic = MseedUtil.get_geodetic(file)

        if geodetic[0] is not None:

            return geodetic[0]
        else:
            return 0.

    def sort_by_baz_advance(self, file):

        geodetic = MseedUtil.get_geodetic(file)

        if geodetic[1] is not None:

            return geodetic[0]
        else:
            return 0.

    def map(self):

        try:

            map_dict = {}
            sd = []

            for tr in self.st:

                station = tr.stats.station.split("_")[0]
                name = tr.stats.network + "." + station
                sd.append(name)
                map_dict[name] = [
                    tr.stats.mseed['coordinates'][0],
                    tr.stats.mseed['coordinates'][1]
                ]

            self.map_stations = StationsMap(map_dict)
            self.map_stations.plot_stations_map(latitude=0, longitude=0)

        except:
            md = MessageDialog(self)
            md.set_error_message(
                "couldn't plot stations map, please check your metadata and the trace headers"
            )
Example #21
0
class TimeFrequencyFrame(BaseFrame, UiTimeFrequencyFrame):
    def __init__(self):

        super(TimeFrequencyFrame, self).__init__()
        self.setupUi(self)
        self.__stations_dir = None
        self.__metadata_manager = None
        self.inventory = {}
        self._stations_info = {}
        self.tr1 = []
        self.tr2 = []
        self.canvas_plot1 = MatplotlibCanvas(self.widget_plot_up, nrows=2)
        # self.canvas_plot1.set_xlabel(1, "Time (s)")
        # self.canvas_plot1.set_ylabel(0, "Amplitude ")
        # self.canvas_plot1.set_ylabel(1, "Frequency (Hz)")
        self.canvas_plot2 = MatplotlibCanvas(self.widget_plot_down, nrows=2)
        # self.canvas_plot2.set_xlabel(1, "Time (s)")
        # self.canvas_plot2.set_ylabel(0, "Amplitude ")
        # self.canvas_plot2.set_ylabel(1, "Frequency (Hz)")
        # Binding
        self.canvas_plot1.mpl_connect('key_press_event', self.key_pressed)
        self.canvas_plot2.mpl_connect('key_press_event', self.key_pressed)
        self.root_path_bind = BindPyqtObject(self.rootPathForm,
                                             self.onChange_root_path)
        self.dataless_path_bind = BindPyqtObject(self.datalessPathForm)
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        # Add file selector to the widget
        self.file_selector = FilesView(
            self.root_path_bind.value,
            parent=self.fileSelectorWidget,
            on_change_file_callback=lambda file_path: self.onChange_file(
                file_path))
        # Binds
        self.selectDirBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind))
        self.datalessBtn.clicked.connect(
            lambda: self.on_click_select_file(self.dataless_path_bind))
        # Action Buttons
        self.actionSettings.triggered.connect(
            lambda: self.open_parameters_settings())
        self.actionOpen_Help.triggered.connect(lambda: self.open_help())
        self.actionOpen_Spectral_Analysis.triggered.connect(
            self.time_frequency_advance)
        self.plotBtn.clicked.connect(self.plot_seismogram)
        self.stationsBtn.clicked.connect(self.stations_info)

        # help Documentation
        self.help = HelpDoc()

        # Parameters settings
        self.parameters = ParametersSettings()

        # Time Frequency Advance
        #self.time_frequency_advance = TimeFrequencyAdvance()

    def filter_error_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    def message_dataless_not_found(self):
        if len(self.dataless_not_found) > 1:
            md = MessageDialog(self)
            md.set_info_message("Metadata not found.")
        else:
            for file in self.dataless_not_found:
                md = MessageDialog(self)
                md.set_info_message("Metadata for {} not found.".format(file))

        self.dataless_not_found.clear()

    def open_parameters_settings(self):
        self.parameters.show()

    def time_frequency_advance(self):
        self._time_frequency_advance = TimeFrequencyAdvance(self.tr1, self.tr2)
        self._time_frequency_advance.show()

    def validate_file(self):
        if not MseedUtil.is_valid_mseed(self.file_selector.file_path):
            msg = "The file {} is not a valid mseed. Please, choose a valid format". \
                format(self.file_selector.file_name)
            raise InvalidFile(msg)

    def onChange_root_path(self, value):
        """
        Fired every time the root_path is changed

        :param value: The path of the new directory.

        :return:
        """
        self.file_selector.set_new_rootPath(value)

    def onChange_file(self, file_path):
        # Called every time user select a different file
        pass

    def on_click_select_directory(self, bind: BindPyqtObject):
        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value,
                pw.QFileDialog.DontUseNativeDialog)
        if dir_path:
            bind.value = dir_path

    def on_click_select_file(self, bind: BindPyqtObject):
        selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file")
        if isinstance(selected[0], str) and os.path.isfile(selected[0]):
            bind.value = selected[0]

    def onChange_metadata_path(self, value):
        md = MessageDialog(self)
        try:
            self.__metadata_manager = MetadataManager(value)
            self.inventory = self.__metadata_manager.get_inventory()
            md.set_info_message(
                "Loaded Metadata, please check your terminal for further details"
            )
        except:
            md.set_error_message(
                "Something went wrong. Please check your metada file is a correct one"
            )

    @property
    def trace(self):
        return ObspyUtil.get_tracer_from_file(self.file_selector.file_path)

    def get_data(self):
        file = self.file_selector.file_path
        starttime = convert_qdatetime_utcdatetime(self.starttime_date)
        endtime = convert_qdatetime_utcdatetime(self.endtime_date)
        diff = endtime - starttime
        parameters = self.parameters.getParameters()
        sd = SeismogramDataAdvanced(file)

        if self.trimCB.isChecked() and diff >= 0:
            tr = sd.get_waveform_advanced(
                parameters,
                self.inventory,
                filter_error_callback=self.filter_error_message,
                start_time=starttime,
                end_time=endtime)
        else:
            tr = sd.get_waveform_advanced(
                parameters,
                self.inventory,
                filter_error_callback=self.filter_error_message)

        t = tr.times()
        return tr, t

    def get_time_window(self):

        t1 = convert_qdatetime_utcdatetime(self.starttime_date)
        t2 = convert_qdatetime_utcdatetime(self.endtime_date)

        return t1, t2

    def stations_info(self):
        obsfiles = MseedUtil.get_mseed_files(self.root_path_bind.value)
        obsfiles.sort()
        sd = []
        for file in obsfiles:
            st = SeismogramDataAdvanced(file)
            station = [
                st.stats.Network, st.stats.Station, st.stats.Location,
                st.stats.Channel, st.stats.StartTime, st.stats.EndTime,
                st.stats.Sampling_rate, st.stats.Npts
            ]
            sd.append(station)
        self._stations_info = StationsInfo(sd, check=False)
        self._stations_info.show()

    def plot_seismogram(self):
        selection = self.selectCB.currentText()

        if selection == "Seismogram 1":
            #self.validate_file()
            [self.tr1, t] = self.get_data()
            self.canvas_plot1.plot(t,
                                   self.tr1.data,
                                   0,
                                   clear_plot=True,
                                   color="black",
                                   linewidth=0.5)
            self.canvas_plot1.set_xlabel(1, "Time (s)")
            self.canvas_plot1.set_ylabel(0, "Amplitude ")
            self.canvas_plot1.set_ylabel(1, "Frequency (Hz)")
            info = "{}.{}.{}".format(self.tr1.stats.network,
                                     self.tr1.stats.station,
                                     self.tr1.stats.channel)
            self.canvas_plot1.set_plot_label(0, info)

            if self.time_frequencyChB.isChecked():
                self.time_frequency(self.tr1, selection)

        if selection == "Seismogram 2":
            #self.validate_file()
            [self.tr2, t] = self.get_data()
            self.canvas_plot2.plot(t,
                                   self.tr2.data,
                                   0,
                                   clear_plot=True,
                                   color="black",
                                   linewidth=0.5)
            self.canvas_plot2.set_xlabel(1, "Time (s)")
            self.canvas_plot2.set_ylabel(0, "Amplitude ")
            self.canvas_plot2.set_ylabel(1, "Frequency (Hz)")
            info = "{}.{}.{}".format(self.tr2.stats.network,
                                     self.tr2.stats.station,
                                     self.tr2.stats.channel)
            self.canvas_plot2.set_plot_label(0, info)

            if self.time_frequencyChB.isChecked():
                self.time_frequency(self.tr2, selection)

    @AsycTime.run_async()
    def time_frequency(self, tr, order):
        selection = self.time_frequencyCB.currentText()
        ts, te = self.get_time_window()
        diff = te - ts
        if selection == "Multitaper Spectrogram":

            win = int(self.mt_window_lengthDB.value() * tr.stats.sampling_rate)
            tbp = self.time_bandwidth_DB.value()
            ntapers = self.number_tapers_mtSB.value()
            f_min = self.freq_min_mtDB.value()
            f_max = self.freq_max_mtDB.value()
            mtspectrogram = MTspectrogram(self.file_selector.file_path, win,
                                          tbp, ntapers, f_min, f_max)

            if self.trimCB.isChecked() and diff >= 0:
                x, y, log_spectrogram = mtspectrogram.compute_spectrogram(
                    tr, start_time=ts, end_time=te)
            else:
                x, y, log_spectrogram = mtspectrogram.compute_spectrogram(tr)

            log_spectrogram = np.clip(log_spectrogram,
                                      a_min=self.minlevelCB.value(),
                                      a_max=0)
            min_log_spectrogram = self.minlevelCB.value()
            max_log_spectrogram = 0

            if order == "Seismogram 1":
                if self.typeCB.currentText() == 'contourf':

                    self.canvas_plot1.plot_contour(x,
                                                   y,
                                                   log_spectrogram,
                                                   axes_index=1,
                                                   clabel="Power [dB]",
                                                   cmap=plt.get_cmap("jet"),
                                                   vmin=min_log_spectrogram,
                                                   vmax=max_log_spectrogram)
                elif self.typeCB.currentText() == 'pcolormesh':

                    print("plotting pcolormesh")
                    self.canvas_plot1.pcolormesh(x,
                                                 y,
                                                 log_spectrogram,
                                                 axes_index=1,
                                                 clabel="Power [dB]",
                                                 cmap=plt.get_cmap("jet"),
                                                 vmin=min_log_spectrogram,
                                                 vmax=max_log_spectrogram)
                self.canvas_plot1.set_xlabel(1, "Time (s)")
                self.canvas_plot1.set_ylabel(0, "Amplitude ")
                self.canvas_plot1.set_ylabel(1, "Frequency (Hz)")

            elif order == "Seismogram 2":
                if self.typeCB.currentText() == 'contourf':

                    self.canvas_plot2.plot_contour(x,
                                                   y,
                                                   log_spectrogram,
                                                   axes_index=1,
                                                   clear_plot=True,
                                                   clabel="Power [dB]",
                                                   cmap=plt.get_cmap("jet"),
                                                   vmin=min_log_spectrogram,
                                                   vmax=max_log_spectrogram)
                elif self.typeCB.currentText() == 'pcolormesh':

                    self.canvas_plot2.pcolormesh(x,
                                                 y,
                                                 log_spectrogram,
                                                 axes_index=1,
                                                 clear_plot=True,
                                                 clabel="Power [dB]",
                                                 cmap=plt.get_cmap("jet"),
                                                 vmin=min_log_spectrogram,
                                                 vmax=max_log_spectrogram)

                self.canvas_plot2.set_xlabel(1, "Time (s)")
                self.canvas_plot2.set_ylabel(0, "Amplitude ")
                self.canvas_plot2.set_ylabel(1, "Frequency (Hz)")

        elif selection == "Wigner Spectrogram":

            win = int(self.mt_window_lengthDB.value() * tr.stats.sampling_rate)
            tbp = self.time_bandwidth_DB.value()
            ntapers = self.number_tapers_mtSB.value()
            f_min = self.freq_min_mtDB.value()
            f_max = self.freq_max_mtDB.value()
            wignerspec = WignerVille(self.file_selector.file_path, win, tbp,
                                     ntapers, f_min, f_max)

            if self.trimCB.isChecked() and diff >= 0:
                x, y, log_spectrogram = wignerspec.compute_wigner_spectrogram(
                    tr, start_time=ts, end_time=te)
            else:
                x, y, log_spectrogram = wignerspec.compute_wigner_spectrogram(
                    tr)

            if order == "Seismogram 1":
                if self.typeCB.currentText() == 'contourf':
                    self.canvas_plot1.plot_contour(x,
                                                   y,
                                                   log_spectrogram,
                                                   axes_index=1,
                                                   clear_plot=True,
                                                   clabel="Rel Power ",
                                                   cmap=plt.get_cmap("jet"))
                elif self.typeCB.currentText() == 'pcolormesh':
                    self.canvas_plot1.pcolormesh(x,
                                                 y,
                                                 log_spectrogram,
                                                 axes_index=1,
                                                 clear_plot=True,
                                                 clabel="Rel Power ",
                                                 cmap=plt.get_cmap("jet"))
                self.canvas_plot1.set_xlabel(1, "Time (s)")
                self.canvas_plot1.set_ylabel(0, "Amplitude ")
                self.canvas_plot1.set_ylabel(1, "Frequency (Hz)")

            elif order == "Seismogram 2":
                if self.typeCB.currentText() == 'contourf':
                    self.canvas_plot2.plot_contour(x,
                                                   y,
                                                   log_spectrogram,
                                                   axes_index=1,
                                                   clear_plot=True,
                                                   clabel="Power [dB]",
                                                   cmap=plt.get_cmap("jet"))
                elif self.typeCB.currentText() == 'pcolormesh':
                    self.canvas_plot2.pcolormesh(x,
                                                 y,
                                                 log_spectrogram,
                                                 axes_index=1,
                                                 clear_plot=True,
                                                 clabel="Power [dB]",
                                                 cmap=plt.get_cmap("jet"))
                self.canvas_plot2.set_xlabel(1, "Time (s)")
                self.canvas_plot2.set_ylabel(0, "Amplitude ")
                self.canvas_plot2.set_ylabel(1, "Frequency (Hz)")

        elif selection == "Continuous Wavelet Transform":

            fs = tr.stats.sampling_rate
            nf = self.atomsSB.value()
            f_min = self.freq_min_cwtDB.value()
            f_max = self.freq_max_cwtDB.value()
            wmin = self.wminSB.value()
            wmax = self.wminSB.value()
            #tt = int( self.wavelet_lenghtDB.value()*fs)
            npts = len(tr.data)
            t = np.linspace(0, tr.stats.delta * npts, npts)
            #cw = ConvolveWaveletScipy(self.file_selector.file_path)
            cw = ConvolveWaveletScipy(tr)
            wavelet = self.wavelet_typeCB.currentText()

            m = self.wavelets_param.value()
            if self.trimCB.isChecked() and diff >= 0:

                cw.setup_wavelet(ts,
                                 te,
                                 wmin=wmin,
                                 wmax=wmax,
                                 tt=int(fs / f_min),
                                 fmin=f_min,
                                 fmax=f_max,
                                 nf=nf,
                                 use_wavelet=wavelet,
                                 m=m,
                                 decimate=False)
            else:
                cw.setup_wavelet(wmin=wmin,
                                 wmax=wmax,
                                 tt=int(fs / f_min),
                                 fmin=f_min,
                                 fmax=f_max,
                                 nf=nf,
                                 use_wavelet=wavelet,
                                 m=m,
                                 decimate=False)

            scalogram2 = cw.scalogram_in_dbs()
            scalogram2 = np.clip(scalogram2,
                                 a_min=self.minlevelCB.value(),
                                 a_max=0)
            cf = cw.cf_lowpass()
            freq = np.logspace(np.log10(f_min), np.log10(f_max))
            k = wmin / (2 * np.pi * freq)
            delay = int(fs * np.mean(k))
            x, y = np.meshgrid(
                t,
                np.logspace(np.log10(f_min), np.log10(f_max),
                            scalogram2.shape[0]))
            c_f = wmin / 2 * math.pi
            f = np.linspace((f_min), (f_max), scalogram2.shape[0])
            pred = (math.sqrt(2) * c_f / f) - (math.sqrt(2) * c_f / f_max)

            pred_comp = t[len(t) - 1] - pred
            min_cwt = self.minlevelCB.value()
            max_cwt = 0

            norm = Normalize(vmin=min_cwt, vmax=max_cwt)

            tf = t[delay:len(t)]
            cf = cf[0:len(tf)]
            if order == "Seismogram 1":

                #self.canvas_plot1.plot(tf, cf, 0, clear_plot=True, is_twinx=True, color="red",
                #                       linewidth=0.5)
                if self.typeCB.currentText() == 'pcolormesh':
                    self.canvas_plot1.pcolormesh(x,
                                                 y,
                                                 scalogram2,
                                                 axes_index=1,
                                                 clear_plot=True,
                                                 clabel="Power [dB]",
                                                 cmap=plt.get_cmap("jet"),
                                                 vmin=min_cwt,
                                                 vmax=max_cwt)
                elif self.typeCB.currentText() == 'contourf':
                    self.canvas_plot1.plot_contour(x,
                                                   y,
                                                   scalogram2,
                                                   axes_index=1,
                                                   clear_plot=True,
                                                   clabel="Power [dB]",
                                                   cmap=plt.get_cmap("jet"),
                                                   vmin=min_cwt,
                                                   vmax=max_cwt)

                ax_cone = self.canvas_plot1.get_axe(1)
                ax_cone.fill_between(pred,
                                     f,
                                     0,
                                     color="black",
                                     edgecolor="red",
                                     alpha=0.3)
                ax_cone.fill_between(pred_comp,
                                     f,
                                     0,
                                     color="black",
                                     edgecolor="red",
                                     alpha=0.3)
                self.canvas_plot1.set_xlabel(1, "Time (s)")
                self.canvas_plot1.set_ylabel(0, "Amplitude ")
                self.canvas_plot1.set_ylabel(1, "Frequency (Hz)")

            if order == "Seismogram 2":

                #self.canvas_plot2.plot(tf, cf, 0, clear_plot=True, is_twinx=True, color="red",
                #                       linewidth=0.5)

                if self.typeCB.currentText() == 'pcolormesh':
                    self.canvas_plot2.pcolormesh(x,
                                                 y,
                                                 scalogram2,
                                                 axes_index=1,
                                                 clear_plot=True,
                                                 clabel="Power [dB]",
                                                 cmap=plt.get_cmap("jet"),
                                                 vmin=min_cwt,
                                                 vmax=max_cwt)
                elif self.typeCB.currentText() == 'contourf':
                    self.canvas_plot2.plot_contour(x,
                                                   y,
                                                   scalogram2,
                                                   axes_index=1,
                                                   clear_plot=True,
                                                   clabel="Power [dB]",
                                                   cmap=plt.get_cmap("jet"),
                                                   vmin=min_cwt,
                                                   vmax=max_cwt)

                ax_cone2 = self.canvas_plot2.get_axe(1)
                ax_cone2.fill_between(pred,
                                      f,
                                      0,
                                      color="black",
                                      edgecolor="red",
                                      alpha=0.3)
                ax_cone2.fill_between(pred_comp,
                                      f,
                                      0,
                                      color="black",
                                      edgecolor="red",
                                      alpha=0.3)
                self.canvas_plot2.set_xlabel(1, "Time (s)")
                self.canvas_plot2.set_ylabel(0, "Amplitude ")
                self.canvas_plot2.set_ylabel(1, "Frequency (Hz)")

        else:
            pass

    def key_pressed(self, event):
        selection = self.selectCB.currentText()

        if event.key == 'w':
            self.plot_seismogram()

        if event.key == 'q':
            if selection == "Seismogram 1":
                [tr, t] = self.get_data()
                x1, y1 = event.xdata, event.ydata
                tt = tr.stats.starttime + x1
                set_qdatetime(tt, self.starttime_date)
                self.canvas_plot1.draw_arrow(x1,
                                             0,
                                             arrow_label="st",
                                             color="purple",
                                             linestyles='--',
                                             picker=False)
            elif selection == "Seismogram 2":
                [tr, t] = self.get_data()
                x1, y1 = event.xdata, event.ydata
                tt = tr.stats.starttime + x1
                set_qdatetime(tt, self.starttime_date)
                self.canvas_plot2.draw_arrow(x1,
                                             0,
                                             arrow_label="st",
                                             color="purple",
                                             linestyles='--',
                                             picker=False)

        if event.key == 'e':

            if selection == "Seismogram 1":
                [tr, t] = self.get_data()
                x1, y1 = event.xdata, event.ydata
                tt = tr.stats.starttime + x1
                set_qdatetime(tt, self.endtime_date)
                self.canvas_plot1.draw_arrow(x1,
                                             0,
                                             arrow_label="et",
                                             color="purple",
                                             linestyles='--',
                                             picker=False)
            elif selection == "Seismogram 2":
                [tr, t] = self.get_data()
                x1, y1 = event.xdata, event.ydata
                tt = tr.stats.starttime + x1
                set_qdatetime(tt, self.endtime_date)
                self.canvas_plot2.draw_arrow(x1,
                                             0,
                                             arrow_label="et",
                                             color="purple",
                                             linestyles='--',
                                             picker=False)

    def open_help(self):
        self.help.show()
Example #22
0
class TimeFrequencyAdvance(pw.QFrame, UiTimeFrequencyWidget):
    def __init__(self, tr1, tr2):
        super(TimeFrequencyAdvance, self).__init__()
        self.setupUi(self)
        self.spectrum_Widget_Canvas = MatplotlibCanvas(self.spectrumWidget, nrows=2, ncols=2,
                                                      sharex=False, constrained_layout=True)

        self.spectrum_Widget_Canvas2 = MatplotlibCanvas(self.spectrumWidget2, nrows=1, ncols=1,
                                                      sharex=False, constrained_layout=True)

        self.coherence_Widget_Canvas = MatplotlibCanvas(self.coherenceWidget, nrows=2, ncols=1, sharex=False,
                                                       constrained_layout=True)
        self.cross_correlation_Widget_Canvas = MatplotlibCanvas(self.cross_correlationWidget, nrows = 3, ncols = 1)

        self.cross_spectrumWidget_Widget_Canvas = MatplotlibCanvas(self.cross_spectrumWidget,nrows = 2, ncols = 1,
                                sharex=True, constrained_layout=True)


        self.plot_spectrumBtn.clicked.connect(self.plot_spectrum)
        self.coherenceBtn.clicked.connect(self.coherence)
        self.cross_correlationsBtn.clicked.connect(self.plot_correlation)
        #self.Cross_spectrumBtn.clicked.connect(self.plot_cross_spectrogram)
        self.Cross_scalogramBtn.clicked.connect(self.plot_cross_scalogram)
        self.tr1 = tr1
        self.tr2 = tr2

    def plot_spectrum(self):
        if len(self.tr1) >0:
            [spec1, freq1, jackknife_errors] = spectrumelement(self.tr1.data, self.tr1.stats.delta, self.tr1.id)
            self.spectrum_Widget_Canvas.plot(freq1, spec1, 0)
            ax1 = self.spectrum_Widget_Canvas.get_axe(0)
            ax1.cla()
            ax1.loglog(freq1, spec1, '0.1', linewidth=0.5, color='steelblue', label=self.tr1.id)
            ax1.fill_between(freq1, jackknife_errors[:, 0], jackknife_errors[:, 1], facecolor="0.75",
                             alpha=0.5, edgecolor="0.5")
            ax1.set_ylim(spec1.min() / 10.0, spec1.max() * 100.0)
            ax1.set_xlim(freq1[1], freq1[len(freq1)-1])
            ax1.set_ylabel('Amplitude')
            ax1.set_xlabel('Frequency [Hz]')
            ax1.grid(True, which="both", ls="-", color='grey')
            ax1.legend()

            #plot the phase
            N = len(self.tr1.data)
            D = 2 ** math.ceil(math.log2(N))
            z = np.zeros(D - N)
            data = np.concatenate((self.tr1.data, z), axis=0)
            spectrum = np.fft.rfft(data, D)
            phase = np.angle(spectrum)
            ax3 = self.spectrum_Widget_Canvas.get_axe(2)
            ax3.semilogx(freq1, phase*180/math.pi, color = 'orangered', linewidth=0.5)
            ax3.set_xlim(freq1[1], freq1[len(freq1) - 1])
            ax3.grid(True, which="both", ls="-", color='grey')
            ax3.set_ylabel('Phase')
            ax3.set_xlabel('Frequency [Hz]')

        else:
            pass

        if len(self.tr2) > 0:
            [spec2, freq2, jackknife_errors] = spectrumelement(self.tr2.data, self.tr2.stats.delta, self.tr2.id)
            self.spectrum_Widget_Canvas.plot(freq2, spec2, 1)
            ax2 = self.spectrum_Widget_Canvas.get_axe(1)
            ax2.cla()
            ax2.loglog(freq2, spec2, '0.1', linewidth=0.5, color='steelblue', label=self.tr2.id)
            ax2.fill_between(freq2, jackknife_errors[:, 0], jackknife_errors[:, 1], facecolor="0.75",
                             alpha=0.5, edgecolor="0.5")
            ax2.set_ylim(spec2.min() / 10.0, spec2.max() * 100.0)
            ax2.set_xlim(freq2[1], freq2[len(freq2) - 1])
            ax2.set_ylabel('Amplitude')
            ax2.set_xlabel('Frequency [Hz]')
            ax2.grid(True, which="both", ls="-", color='grey')
            ax2.legend()

            # plot the phase
            N = len(self.tr2.data)
            D = 2 ** math.ceil(math.log2(N))
            z = np.zeros(D - N)
            data = np.concatenate((self.tr2.data, z), axis=0)
            spectrum = np.fft.rfft(data, D)
            phase = np.angle(spectrum)
            ax4 = self.spectrum_Widget_Canvas.get_axe(3)
            ax4.semilogx(freq2, phase * 180 / math.pi, color = 'orangered', linewidth=0.5)
            ax4.set_xlim(freq2[1], freq2[len(freq2) - 1])
            ax4.grid(True, which="both", ls="-", color='grey')
            ax4.set_ylabel('Phase')
            ax4.set_xlabel('Frequency [Hz]')
        else:
            pass

        # Power

        try:
            self.spectrum_Widget_Canvas2.plot(freq1, spec1, 0)
            ax5 = self.spectrum_Widget_Canvas2.get_axe(0)
            ax5.cla()
            spec1=spec1**2
            spec2=spec2**2
            ax5.loglog(freq1, spec1, '0.1', linewidth=0.5, color='steelblue', label=self.tr1.id)
            ax5.loglog(freq2, spec2, '0.1', linewidth=0.5, color='orangered', label=self.tr2.id)
            ax5.set_ylabel('Amplitude')
            ax5.set_xlabel('Frequency [Hz]')
            ax5.grid(True, which="both", ls="-", color='grey')
            ax5.legend()

        except:
            raise("Some data is missing")




    def coherence(self):
        if len(self.tr1) > 0 and len(self.tr2) > 0:
            sampling_rates = []
            fs1=self.tr1.stats.sampling_rate
            fs2=self.tr2.stats.sampling_rate
            sampling_rates.append(fs1)
            sampling_rates.append(fs2)
            max_sampling_rates = np.max(sampling_rates)
            overlap = self.cohe_overlapSB.value()
            time_window = self.time_window_coheSB.value()
            nfft = time_window*max_sampling_rates
            if fs1 != fs2:
                self.tr1.resample(max_sampling_rates)
                self.tr1.resample(max_sampling_rates)

            # Plot Amplitude
            [A,f, phase] = cohe(self.tr1.data, self.tr2.data, max_sampling_rates, nfft, overlap)

            self.coherence_Widget_Canvas.plot(f, A, 0)

            ax1 = self.coherence_Widget_Canvas.get_axe(0)
            ax1.cla()
            ax1.loglog(f, A, '0.1', linewidth=0.5, color='steelblue', label="Amplitude Coherence "+
                                                                            self.tr1.id+" "+ self.tr2.id)

            ax1.set_ylim(A.min() / 10.0, A.max() * 100.0)
            ax1.set_xlim(f[1], f[len(f) - 1])
            ax1.set_ylabel('Magnitude Coherence')
            ax1.set_xlabel('Frequency [Hz]')
            ax1.grid(True, which="both", ls="-", color='grey')
            ax1.legend()

            # Plot Phase
            ax2 = self.coherence_Widget_Canvas.get_axe(1)
            ax2.cla()
            ax2.semilogx(f, phase * 180 / math.pi, color='orangered', linewidth=0.5, label="Phase Coherence "+
                                                                            self.tr1.id+" "+ self.tr2.id)
            ax2.set_xlim(f[1], f[len(f) - 1])
            ax2.set_ylabel('Phase')
            ax2.set_xlabel('Frequency [Hz]')
            ax2.grid(True, which="both", ls="-", color='grey')
            ax2.legend()

    def plot_correlation(self):

        if len(self.tr1) > 0 and len(self.tr2) > 0:
            sampling_rates = []
            fs1=self.tr1.stats.sampling_rate
            fs2=self.tr2.stats.sampling_rate
            sampling_rates.append(fs1)
            sampling_rates.append(fs2)
            max_sampling_rates = np.max(sampling_rates)

            if fs1 != fs2:
                self.tr1.resample(max_sampling_rates)
                self.tr2.resample(max_sampling_rates)

            cc1 = correlate_maxlag(self.tr1.data, self.tr1.data, maxlag = max([len(self.tr1.data),len(self.tr2.data)]))
            cc2 = correlate_maxlag(self.tr2.data, self.tr2.data, maxlag = max([len(self.tr1.data),len(self.tr2.data)]))
            cc3 = correlate_maxlag(self.tr1.data, self.tr2.data, maxlag = max([len(self.tr1.data),len(self.tr2.data)]))
            N1 = len(cc1)
            N2 = len(cc2)
            N3 = len(cc3)
            self.cross_correlation_Widget_Canvas.plot(get_lags(cc1)/max_sampling_rates, cc1, 0,
                                                      clear_plot=True, linewidth=0.5,color='black')
            self.cross_correlation_Widget_Canvas.plot(get_lags(cc2)/max_sampling_rates, cc2, 1,
                                                      clear_plot=True, linewidth=0.5, color = 'black')
            self.cross_correlation_Widget_Canvas.plot(get_lags(cc3)/max_sampling_rates, cc3, 2,
                                                      clear_plot=True, linewidth=0.5, color = 'red')

    def plot_cross_spectrogram(self):
        if len(self.tr1) > 0 and len(self.tr2) > 0:
            csp = cross_spectrogram(self.tr1, self.tr2, win=self.time_windowSB.value(),
                                    tbp=self.time_bandwidthSB.value(), ntapers = self.num_tapersSB.value())

            [coherence_cross, freq, t] = csp.compute_coherence_crosspectrogram()
            f_min = 0
            f_max = 0.5*(1/max(freq))
            f_max=50
            x, y = np.meshgrid(t, np.linspace(f_min, f_max, coherence_cross.shape[0]))

            self.cross_spectrumWidget_Widget_Canvas.plot_contour(x, y, coherence_cross, axes_index=0,
                     clabel="Coherence", cmap=plt.get_cmap("jet"), vmin=0,vmax=1)
            self.cross_spectrumWidget_Widget_Canvas.set_xlabel(0, "Time (s)")
            self.cross_spectrumWidget_Widget_Canvas.set_ylabel(0, "Frequency (Hz)")


    def plot_cross_scalogram(self):

        base_line = self.base_lineDB.value()
        colour = self.colourCB.currentText()

        if len(self.tr1) > 0 and len(self.tr2) > 0:
            #
            fs1 = self.tr1.stats.sampling_rate
            fs2 = self.tr2.stats.sampling_rate
            fs = max(fs1, fs2)
            if fs1 < fs:
                self.tr1.resample(fs)
            elif fs2 < fs:
                self.tr2.resample(fs)
            all_traces = [self.tr1, self.tr2]
            st = Stream(traces=all_traces)
            maxstart = np.max([tr.stats.starttime for tr in st])
            minend = np.min([tr.stats.endtime for tr in st])
            st.trim(maxstart, minend)
            tr1 = st[0]
            tr2 = st[1]
            tr1.detrend(type='demean')
            tr1.taper(max_percentage=0.05)
            tr2.detrend(type='demean')
            tr2.taper(max_percentage=0.05)

            npts =len(tr1.data)
            t = np.linspace(0,  npts/fs, npts)
            f_max = fs/2
            nf = 40
            wmin=wmax=self.num_cyclesSB.value()
            f_min = self.freq_min_waveletSB.value()
            tt = int(fs / f_min)
            [ba, nConv, frex, half_wave] = ccwt_ba_fast(npts, fs, f_min, f_max, wmin, wmax, tt, nf)

            cf, sc, scalogram1 = cwt_fast(tr1.data, ba, nConv, frex, half_wave, fs)

            cf, sc, scalogram2 = cwt_fast(tr2.data, ba, nConv, frex, half_wave, fs)

            crossCFS = scalogram1 * np.conj(scalogram2)

            cross_scalogram = np.abs(crossCFS)**2
            cross_scalogram = 10*np.log(cross_scalogram/np.max(cross_scalogram))
            cross_scalogram = np.clip(cross_scalogram, a_min=base_line, a_max=0)
            min_cwt = base_line
            max_cwt = 0


            x, y = np.meshgrid(t, np.logspace(np.log10(f_min), np.log10(f_max), cross_scalogram.shape[0]))
            c_f = wmin / 2 * math.pi
            f = np.linspace((f_min), (f_max), cross_scalogram.shape[0])
            pred = (math.sqrt(2) * c_f / f) - (math.sqrt(2) * c_f / f_max)

            pred_comp = t[len(t) - 1] - pred


            #Plot Seismograms

            self.cross_spectrumWidget_Widget_Canvas.plot(tr1.times(), self.tr1.data, 0, color="black",
                    linewidth=0.5,alpha = 0.75)

            self.cross_spectrumWidget_Widget_Canvas.plot(tr2.times(), tr2.data, 0, clear_plot=False, is_twinx=True,
                                                         color="orangered", linewidth=0.5, alpha=0.75)
            info = tr1.id + " " + tr2.id
            self.cross_spectrumWidget_Widget_Canvas.set_plot_label(0, info)
            self.cross_spectrumWidget_Widget_Canvas.set_ylabel(0, "Amplitude")
            #info = "{}.{}.{}".format(tr1.stats.network, tr1.stats.station, tr1.stats.channel)
            #self.cross_spectrumWidget_Widget_Canvas.set_plot_label(0, info)
            #info = "{}.{}.{}".format(tr2.stats.network, tr2.stats.station, tr1.stats.channel)
            #self.cross_spectrumWidget_Widget_Canvas.set_plot_label(0, info)


            # Plot Cross Scalogram
            self.cross_spectrumWidget_Widget_Canvas.plot_contour(x, y, cross_scalogram, axes_index=1, clabel="Cross Power [dB]",
                                           cmap=plt.get_cmap(colour))
            # Plot Cone
            ax_cone = self.cross_spectrumWidget_Widget_Canvas.get_axe(1)
            ax_cone.fill_between(pred, f, 0, color="black", edgecolor="red", alpha=0.3)
            ax_cone.fill_between(pred_comp, f, 0, color="black", edgecolor="red", alpha=0.3)
            self.cross_spectrumWidget_Widget_Canvas.set_xlabel(1, "Time (s)")
            self.cross_spectrumWidget_Widget_Canvas.set_ylabel(1, "Frequency (Hz)")
Example #23
0
class PlotPolarization(pw.QFrame, UiPlotPolarization ):
    def __init__(self, z, r, t):
        super(PlotPolarization, self).__init__()
        self.setupUi(self)
        self._z = z-np.mean(z)
        self._r = r-np.mean(r)
        self._t = t-np.mean(t)
        all_traces = [self._z, self._r, self._t]
        self.st = Stream(traces=all_traces)
        self._r_max = max(r)
        self._t_max = max(t)
        self._z_max=max(z)
        self.max_value=max([max(abs(z)), max(abs(t)), max(abs(r))])
        self.canvas = MatplotlibCanvas(self.plotMatWidget_polarization)
        self.canvas2D = MatplotlibCanvas(self.plotMatWidget_polarization2, nrows=2, ncols=2, constrained_layout=True)
        self.canvas.figure.gca(projection='3d')
        self.plotBtn.clicked.connect(lambda: self.plot_particle())


    def plot_particle(self):
        azimuth, incidence, rect, plan = flinn(self.st)

        self.canvas.plot_projection(self._r,self._t,self._z, axes_index=0)
        self.canvas.set_xlabel(0, "Radial")
        self.canvas.set_ylabel(0, "Transversal")
        #self.canvas.set_zlabel(0, "Vertical")

        self.canvas2D.plot(self._r, self._z, 0, clear_plot=True, linewidth=0.5)
        self.canvas2D.set_xlabel(0, "Radial")
        self.canvas2D.set_ylabel(0, "Vertical")
        ax1 = self.canvas2D.get_axe(0)
        ax1.set_xlim([-self.max_value,self.max_value])
        ax1.set_ylim([-self.max_value, self.max_value])

        self.canvas2D.plot(self._t, self._z, 1, clear_plot=True, linewidth=0.5)
        self.canvas2D.set_xlabel(1, "Transversal")
        self.canvas2D.set_ylabel(1, "Vertical")
        ax2 = self.canvas2D.get_axe(1)
        ax2.set_xlim([-self.max_value, self.max_value])
        ax2.set_ylim([-self.max_value, self.max_value])

        self.canvas2D.plot(self._r, self._t, 2, clear_plot=True, linewidth=0.5)
        self.canvas2D.set_xlabel(2, "Radial")
        self.canvas2D.set_ylabel(2, "Transversal")
        ax3 = self.canvas2D.get_axe(2)
        ax3.set_xlim([-self.max_value, self.max_value])
        ax3.set_ylim([-self.max_value, self.max_value])

        self.polarizationText.setPlainText("  Azimuth:     {azimuth:.3f} ".format(azimuth=azimuth))
        self.polarizationText.appendPlainText("  Incidence Angle:     {incidence:.3f} ".format(incidence=incidence))
        self.polarizationText.appendPlainText("  Rectilinearity:     {rect:.3f} ".format(rect=rect))
        self.polarizationText.appendPlainText("  Planarity:     {plan:.3f} ".format(plan=plan))
Example #24
0
class ArrayAnalysisFrame(BaseFrame, UiArrayAnalysisFrame):
    def __init__(self):
        super(ArrayAnalysisFrame, self).__init__()
        self.setupUi(self)
        self.__stations_dir = None
        self.stream_frame = None
        self.__metadata_manager = None
        self.inventory = {}
        self._stations_info = {}
        self._stations_coords = {}
        self.stack = None
        self.canvas = MatplotlibCanvas(self.responseMatWidget)
        self.canvas_fk = MatplotlibCanvas(self.widget_fk, nrows=4)
        self.canvas_slow_map = MatplotlibCanvas(self.widget_slow_map)
        self.canvas_fk.on_double_click(self.on_click_matplotlib)
        self.canvas_stack = MatplotlibCanvas(self.widget_stack)
        self.cartopy_canvas = CartopyCanvas(self.widget_map)
        self.canvas.set_new_subplot(1, ncols=1)

        #Binding
        self.root_pathFK_bind = BindPyqtObject(self.rootPathFormFK)
        self.root_pathBP_bind = BindPyqtObject(self.rootPathFormBP)
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.metadata_path_bindBP = BindPyqtObject(self.datalessPathFormBP,
                                                   self.onChange_metadata_path)
        self.output_path_bindBP = BindPyqtObject(self.outputPathFormBP,
                                                 self.onChange_metadata_path)
        self.fmin_bind = BindPyqtObject(self.fminSB)
        self.fmax_bind = BindPyqtObject(self.fmaxSB)
        self.grid_bind = BindPyqtObject(self.gridSB)
        self.smax_bind = BindPyqtObject(self.smaxSB)

        # On select
        self.canvas_fk.register_on_select(self.on_select,
                                          rectprops=dict(alpha=0.2,
                                                         facecolor='red'))
        self.fminFK_bind = BindPyqtObject(self.fminFKSB)
        self.fmaxFK_bind = BindPyqtObject(self.fmaxFKSB)
        self.overlap_bind = BindPyqtObject(self.overlapSB)
        self.timewindow_bind = BindPyqtObject(self.timewindowSB)
        self.smaxFK_bind = BindPyqtObject(self.slowFKSB)
        self.slow_grid_bind = BindPyqtObject(self.gridFKSB)

        # Bind buttons
        self.selectDirBtnFK.clicked.connect(
            lambda: self.on_click_select_directory(self.root_pathFK_bind))
        self.datalessBtn.clicked.connect(
            lambda: self.on_click_select_metadata_file(self.metadata_path_bind
                                                       ))

        # Bind buttons BackProjection
        self.selectDirBtnBP.clicked.connect(
            lambda: self.on_click_select_directory(self.root_pathBP_bind))
        self.datalessBtnBP.clicked.connect(
            lambda: self.on_click_select_metadata_file(self.
                                                       metadata_path_bindBP))
        self.outputBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.output_path_bindBP))

        #Action Buttons
        self.arfBtn.clicked.connect(lambda: self.arf())
        self.runFKBtn.clicked.connect(lambda: self.FK_plot())
        self.plotBtn.clicked.connect(lambda: self.plot_seismograms())
        self.plotBtnBP.clicked.connect(lambda: self.plot_seismograms(FK=False))
        self.actionSettings.triggered.connect(
            lambda: self.open_parameters_settings())
        self.actionProcessed_Seimograms.triggered.connect(self.write)
        self.actionStacked_Seismograms.triggered.connect(self.write_stack)
        self.stationsBtn.clicked.connect(lambda: self.stationsInfo())
        self.stationsBtnBP.clicked.connect(lambda: self.stationsInfo(FK=False))
        self.mapBtn.clicked.connect(self.stations_map)
        self.actionCreate_Stations_File.triggered.connect(
            self.stations_coordinates)
        self.actionLoad_Stations_File.triggered.connect(self.load_path)
        self.actionRunVespagram.triggered.connect(self.open_vespagram)
        self.shortcut_open = pw.QShortcut(pqg.QKeySequence('Ctrl+O'), self)
        self.shortcut_open.activated.connect(self.open_solutions)
        self.create_gridBtn.clicked.connect(self.create_grid)
        self.actionOpen_Help.triggered.connect(lambda: self.open_help())
        self.load_videoBtn.clicked.connect(self.loadvideoBP)

        # help Documentation
        self.help = HelpDoc()

        # Parameters settings
        self.__parameters = ParametersSettings()

        # Stations Coordinates
        self.__stations_coords = StationsCoords()

        # picks
        self.picks = {
            'Time': [],
            'Phase': [],
            'BackAzimuth': [],
            'Slowness': [],
            'Power': []
        }

        # video
        self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.player.setVideoOutput(self.backprojection_widget)
        self.player.stateChanged.connect(self.mediaStateChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.durationChanged.connect(self.durationChanged)
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play_bp)
        self.positionSlider.sliderMoved.connect(self.setPosition)

    def mediaStateChanged(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPlay))

    def positionChanged(self, position):
        self.positionSlider.setValue(position)

    def durationChanged(self, duration):
        self.positionSlider.setRange(0, duration)

    def setPosition(self, position):
        self.player.setPosition(position)

    def open_parameters_settings(self):
        self.__parameters.show()

    def stations_coordinates(self):
        self.__stations_coords.show()

    def open_vespagram(self):
        if self.st and self.inventory and self.t1 and self.t2:
            self.__vespagram = Vespagram(self.st, self.inventory, self.t1,
                                         self.t2)
            self.__vespagram.show()

    def on_click_select_directory(self, bind: BindPyqtObject):
        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', bind.value,
                pw.QFileDialog.DontUseNativeDialog)
        if dir_path:
            bind.value = dir_path

    def onChange_metadata_path(self, value):

        md = MessageDialog(self)
        try:

            self.__metadata_manager = MetadataManager(value)
            self.inventory = self.__metadata_manager.get_inventory()
            print(self.inventory)
            md.set_info_message(
                "Loaded Metadata, please check your terminal for further details"
            )

        except:

            md.set_error_message(
                "Something went wrong. Please check your metada file is a correct one"
            )

    def on_click_select_metadata_file(self, bind: BindPyqtObject):
        selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file")
        if isinstance(selected[0], str) and os.path.isfile(selected[0]):
            bind.value = selected[0]

    def load_path(self):
        selected_file = pw.QFileDialog.getOpenFileName(
            self, "Select Stations Coordinates file")
        self.path_file = selected_file[0]
        df = pd.read_csv(self.path_file, delim_whitespace=True)
        n = len(df)
        self.coords = np.zeros([n, 3])
        for i in range(n):
            #coords[i]=data[i]
            self.coords[i] = np.array(
                [df['Lon'][i], df['Lat'][i], df['Depth'][i]])

    def arf(self):
        try:
            if self.coords.all():

                wavenumber = array_analysis.array()
                arf = wavenumber.arf(self.coords, self.fmin_bind.value,
                                     self.fmax_bind.value,
                                     self.smax_bind.value,
                                     self.grid_bind.value)

                slim = self.smax_bind.value
                x = y = np.linspace(-1 * slim, slim, len(arf))
                self.canvas.plot_contour(x,
                                         y,
                                         arf,
                                         axes_index=0,
                                         clabel="Power [dB]",
                                         cmap=plt.get_cmap("jet"))
                self.canvas.set_xlabel(0, "Sx (s/km)")
                self.canvas.set_ylabel(0, "Sy (s/km)")
        except:
            md = MessageDialog(self)
            md.set_error_message(
                "Couldn't compute ARF, please check if you have loaded stations coords"
            )

    def stations_map(self):
        coords = {}

        if self.path_file:
            df = pd.read_csv(self.path_file, delim_whitespace=True)
            n = len(df)
            self.coords = np.zeros([n, 3])
            for i in range(n):
                coords[df['Name'][i]] = [
                    df['Lat'][i],
                    df['Lon'][i],
                ]
        #try:
            self.cartopy_canvas.plot_map(df['Lat'][0],
                                         df['Lon'][0],
                                         0,
                                         0,
                                         0,
                                         0,
                                         resolution="low",
                                         stations=coords)
        #except:
        #    pass

    def FK_plot(self):
        self.canvas_stack.set_new_subplot(nrows=1, ncols=1)
        starttime = convert_qdatetime_utcdatetime(self.starttime_date)
        endtime = convert_qdatetime_utcdatetime(self.endtime_date)
        selection = self.inventory.select(station=self.stationLE.text(),
                                          channel=self.channelLE.text())
        if self.trimCB.isChecked():
            wavenumber = array_analysis.array()
            relpower, abspower, AZ, Slowness, T = wavenumber.FK(
                self.st, selection, starttime, endtime, self.fminFK_bind.value,
                self.fmaxFK_bind.value, self.smaxFK_bind.value,
                self.slow_grid_bind.value, self.timewindow_bind.value,
                self.overlap_bind.value)
            self.canvas_fk.scatter3d(T,
                                     relpower,
                                     relpower,
                                     axes_index=0,
                                     clabel="Power [dB]")
            self.canvas_fk.scatter3d(T,
                                     abspower,
                                     relpower,
                                     axes_index=1,
                                     clabel="Power [dB]")
            self.canvas_fk.scatter3d(T,
                                     AZ,
                                     relpower,
                                     axes_index=2,
                                     clabel="Power [dB]")
            self.canvas_fk.scatter3d(T,
                                     Slowness,
                                     relpower,
                                     axes_index=3,
                                     clabel="Power [dB]")
            self.canvas_fk.set_ylabel(0, " Rel Power ")
            self.canvas_fk.set_ylabel(1, " Absolute Power ")
            self.canvas_fk.set_ylabel(2, " Back Azimuth ")
            self.canvas_fk.set_ylabel(3, " Slowness [s/km] ")
            self.canvas_fk.set_xlabel(3, " Time [s] ")
            ax = self.canvas_fk.get_axe(3)
            formatter = mdt.DateFormatter('%H:%M:%S')
            ax.xaxis.set_major_formatter(formatter)
            ax.xaxis.set_tick_params(rotation=30)
        else:
            md = MessageDialog(self)
            md.set_info_message("Please select dates and then check Trim box")

    def on_click_matplotlib(self, event, canvas):
        output_path = os.path.join(ROOT_DIR, 'arrayanalysis', 'dataframe.csv')

        if isinstance(canvas, MatplotlibCanvas):
            st = self.st.copy()
            wavenumber = array_analysis.array()
            selection = self.inventory.select(station=self.stationLE.text(),
                                              channel=self.channelLE.text())
            x1, y1 = event.xdata, event.ydata
            DT = x1
            Z, Sxpow, Sypow, coord = wavenumber.FKCoherence(
                st, selection, DT, self.fminFK_bind.value,
                self.fmaxFK_bind.value, self.smaxFK_bind.value,
                self.timewindow_bind.value, self.slow_grid_bind.value,
                self.methodSB.currentText())

            backacimuth = wavenumber.azimuth2mathangle(
                np.arctan2(Sypow, Sxpow) * 180 / np.pi)
            slowness = np.abs(Sxpow, Sypow)
            if self.methodSB.currentText() == "FK":
                clabel = "Power"
            elif self.methodSB.currentText() == "MTP.COHERENCE":
                clabel = "Magnitude Coherence"

            Sx = np.arange(-1 * self.smaxFK_bind.value, self.smaxFK_bind.value,
                           self.slow_grid_bind.value)[np.newaxis]
            nx = len(Sx[0])
            x = y = np.linspace(-1 * self.smaxFK_bind.value,
                                self.smaxFK_bind.value, nx)
            X, Y = np.meshgrid(x, y)
            self.canvas_slow_map.plot_contour(X,
                                              Y,
                                              Z,
                                              axes_index=0,
                                              clabel=clabel,
                                              cmap=plt.get_cmap("jet"))
            self.canvas_slow_map.set_xlabel(0, "Sx [s/km]")
            self.canvas_slow_map.set_ylabel(0, "Sy [s/km]")

            # Save in a dataframe the pick value
            x1 = wavenumber.gregorian2date(x1)

            self.picks['Time'].append(x1.isoformat())
            self.picks['Phase'].append(self.phaseCB.currentText())
            self.picks['BackAzimuth'].append(backacimuth[0])
            self.picks['Slowness'].append(slowness[0])
            self.picks['Power'].append(np.max(Z))
            df = pd.DataFrame(self.picks)
            df.to_csv(output_path, index=False, header=True)

            # Call Stack and Plot###
            #stream_stack, time = wavenumber.stack_stream(self.root_pathFK_bind.value, Sxpow, Sypow, coord)

            if st:
                st2 = self.st.copy()
                # Align for the maximum power and give the data of the traces
                stream_stack, self.time, self.stats = wavenumber.stack_stream(
                    st2, Sxpow, Sypow, coord)
                # stack the traces
                self.stack = wavenumber.stack(
                    stream_stack, stack_type=self.stackCB.currentText())
                self.canvas_stack.plot(self.time,
                                       self.stack,
                                       axes_index=0,
                                       linewidth=0.75)
                self.canvas_stack.set_xlabel(0, " Time [s] ")
                self.canvas_stack.set_ylabel(0, "Stack Amplitude")

    def filter_error_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    def plot_seismograms(self, FK=True):

        if FK:
            starttime = convert_qdatetime_utcdatetime(self.starttime_date)
            endtime = convert_qdatetime_utcdatetime(self.endtime_date)
        else:
            starttime = convert_qdatetime_utcdatetime(self.starttime_date_BP)
            endtime = convert_qdatetime_utcdatetime(self.endtime_date_BP)

        diff = endtime - starttime

        if FK:
            file_path = self.root_pathFK_bind.value
        else:
            file_path = self.root_pathBP_bind.value

        obsfiles = []

        for dirpath, _, filenames in os.walk(file_path):
            for f in filenames:
                if f != ".DS_Store":
                    obsfiles.append(os.path.abspath(os.path.join(dirpath, f)))

        obsfiles.sort()
        parameters = self.__parameters.getParameters()
        all_traces = []
        trace_number = 0

        for file in obsfiles:
            sd = SeismogramDataAdvanced(file)

            if FK:
                if self.trimCB.isChecked() and diff >= 0:
                    tr = sd.get_waveform_advanced(
                        parameters,
                        self.inventory,
                        filter_error_callback=self.filter_error_message,
                        start_time=starttime,
                        end_time=endtime,
                        trace_number=trace_number)
                else:
                    tr = sd.get_waveform_advanced(
                        parameters,
                        self.inventory,
                        filter_error_callback=self.filter_error_message,
                        trace_number=trace_number)
            else:
                if self.trimCB_BP.isChecked() and diff >= 0:
                    tr = sd.get_waveform_advanced(
                        parameters,
                        self.inventory,
                        filter_error_callback=self.filter_error_message,
                        start_time=starttime,
                        end_time=endtime,
                        trace_number=trace_number)
                else:
                    tr = sd.get_waveform_advanced(
                        parameters,
                        self.inventory,
                        filter_error_callback=self.filter_error_message,
                        trace_number=trace_number)

            all_traces.append(tr)
            trace_number = trace_number + 1

        self.st = Stream(traces=all_traces)

        if FK:
            if self.selectCB.isChecked():
                self.st = self.st.select(station=self.stationLE.text(),
                                         channel=self.channelLE.text())

        else:
            if self.selectCB_BP.isChecked():
                self.st = self.st.select(network=self.stationLE_BP.text(),
                                         station=self.stationLE_BP.text(),
                                         channel=self.channelLE_BP.text())

        self.stream_frame = MatplotlibFrame(self.st, type='normal')
        self.stream_frame.show()

    def stationsInfo(self, FK=True):
        if FK:
            obsfiles = MseedUtil.get_mseed_files(self.root_pathFK_bind.value)
        else:
            obsfiles = MseedUtil.get_mseed_files(self.root_pathBP_bind.value)
        obsfiles.sort()
        sd = []
        for file in obsfiles:
            st = SeismogramDataAdvanced(file)
            station = [
                st.stats.Network, st.stats.Station, st.stats.Location,
                st.stats.Channel, st.stats.StartTime, st.stats.EndTime,
                st.stats.Sampling_rate, st.stats.Npts
            ]
            sd.append(station)
        self._stations_info = StationsInfo(sd, check=True)
        self._stations_info.show()

    def write(self):
        root_path = os.path.dirname(os.path.abspath(__file__))
        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', root_path)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', root_path,
                pw.QFileDialog.DontUseNativeDialog)
        if dir_path:
            n = len(self.st)
            try:
                if len(n) > 0:
                    for j in range(n):
                        tr = self.st[j]
                        t1 = tr.stats.starttime
                        id = tr.id + "." + "D" + "." + str(
                            t1.year) + "." + str(t1.julday)
                        print(tr.id, "Writing data processed")
                        path_output = os.path.join(dir_path, id)
                        tr.write(path_output, format="MSEED")
                else:
                    md = MessageDialog(self)
                    md.set_info_message("Nothing to write")
            except:
                pass

    def write_stack(self):
        if self.stack is not None and len(self.stack) > 0:
            root_path = os.path.dirname(os.path.abspath(__file__))
            if "darwin" == platform:
                dir_path = pw.QFileDialog.getExistingDirectory(
                    self, 'Select Directory', root_path)
            else:
                dir_path = pw.QFileDialog.getExistingDirectory(
                    self, 'Select Directory', root_path,
                    pw.QFileDialog.DontUseNativeDialog)
            if dir_path:
                tr = Trace(data=self.stack, header=self.stats)
                file = os.path.join(dir_path, tr.id)
                tr.write(file, format="MSEED")
        else:
            md = MessageDialog(self)
            md.set_info_message("Nothing to write")

    def __to_UTC(self, DT):

        # Convert start from Greogorian to actual date
        Time = DT
        Time = Time - int(Time)
        d = date.fromordinal(int(DT))
        date1 = d.isoformat()
        H = (Time * 24)
        H1 = int(H)  # Horas
        minutes = (H - int(H)) * 60
        minutes1 = int(minutes)
        seconds = (minutes - int(minutes)) * 60
        H1 = str(H1).zfill(2)
        minutes1 = str(minutes1).zfill(2)
        seconds = "%.2f" % seconds
        seconds = str(seconds).zfill(2)
        DATE = date1 + "T" + str(H1) + minutes1 + seconds

        t1 = UTCDateTime(DATE)
        return t1

    def on_select(self, ax_index, xmin, xmax):
        self.t1 = self.__to_UTC(xmin)
        self.t2 = self.__to_UTC(xmax)

    def open_solutions(self):
        output_path = os.path.join(ROOT_DIR, 'arrayanalysis', 'dataframe.csv')
        try:
            command = "{} {}".format('open', output_path)
            exc_cmd(command, cwd=ROOT_DIR)
        except:
            md = MessageDialog(self)
            md.set_error_message("Coundn't open solutions file")

    ### New part back-projection

    def create_grid(self):
        area_coords = [
            self.minLonBP, self.maxLonBP, self.minLatBP, self.maxLatBP
        ]
        bp = back_proj_organize(self, self.rootPathFormBP,
                                self.datalessPathFormBP, area_coords,
                                self.sxSB.value, self.sxSB.value,
                                self.depthSB.value)

        mapping = bp.create_dict()

        try:
            self.path_file = os.path.join(self.output_path_bindBP.value,
                                          "mapping.pkl")
            file_to_store = open(self.path_file, "wb")
            pickle.dump(mapping, file_to_store)
            md = MessageDialog(self)
            md.set_info_message("BackProjection grid created succesfully!!!")

        except:
            md = MessageDialog(self)
            md.set_error_message("Coundn't create a BackProjection grid")

    def run_bp(self):

        try:
            if os.path.exists(self.path_file):
                with open(self.path_file, 'rb') as handle:
                    mapping = pickle.load(handle)
        except:
            md = MessageDialog(self)
            md.set_error_message(
                "Please you need try to previously create a BackProjection grid"
            )

        power = backproj.run_back(self.st,
                                  mapping,
                                  self.time_winBP.value,
                                  self.stepBP.value,
                                  window=self.slide_winBP.value,
                                  multichannel=self.mcccCB.isChecked(),
                                  stack_process=self.methodBP.currentText())

        #plot_cum(power, mapping['area_coords'], self.cum_sumBP.value, self.st)
        plot_bp(power,
                mapping['area_coords'],
                self.cum_sumBP.value,
                self.st,
                output=self.output_path_bindBP.value)

        fname = os.path.join(self.output_path_bindBP.value, "power.pkl")

        file_to_store = open(fname, "wb")
        pickle.dump(power, file_to_store)

    def loadvideoBP(self):
        self.path_video, _ = pw.QFileDialog.getOpenFileName(
            self, "Choose your BackProjection", ".",
            "Video Files (*.mp4 *.flv *.ts *.mts *.avi)")
        if self.path_video != '':

            self.player.setVideoOutput(self.backprojection_widget)
            self.player.setMedia(
                QMediaContent(pyc.QUrl.fromLocalFile(self.path_video)))
            md = MessageDialog(self)
            md.set_info_message(
                "Video containing BackProjection succesfully loaded")
        else:
            md = MessageDialog(self)
            md.set_error_message(
                "Video containing BackProjection couldn't be loaded")

    def play_bp(self):

        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
        else:
            self.player.play()

    def open_help(self):
        self.help.show()
Example #25
0
    def __init__(self):
        super(ArrayAnalysisFrame, self).__init__()
        self.setupUi(self)
        self.__stations_dir = None
        self.stream_frame = None
        self.__metadata_manager = None
        self.inventory = {}
        self._stations_info = {}
        self._stations_coords = {}
        self.stack = None
        self.canvas = MatplotlibCanvas(self.responseMatWidget)
        self.canvas_fk = MatplotlibCanvas(self.widget_fk, nrows=4)
        self.canvas_slow_map = MatplotlibCanvas(self.widget_slow_map)
        self.canvas_fk.on_double_click(self.on_click_matplotlib)
        self.canvas_stack = MatplotlibCanvas(self.widget_stack)
        self.cartopy_canvas = CartopyCanvas(self.widget_map)
        self.canvas.set_new_subplot(1, ncols=1)

        #Binding
        self.root_pathFK_bind = BindPyqtObject(self.rootPathFormFK)
        self.root_pathBP_bind = BindPyqtObject(self.rootPathFormBP)
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.metadata_path_bindBP = BindPyqtObject(self.datalessPathFormBP,
                                                   self.onChange_metadata_path)
        self.output_path_bindBP = BindPyqtObject(self.outputPathFormBP,
                                                 self.onChange_metadata_path)
        self.fmin_bind = BindPyqtObject(self.fminSB)
        self.fmax_bind = BindPyqtObject(self.fmaxSB)
        self.grid_bind = BindPyqtObject(self.gridSB)
        self.smax_bind = BindPyqtObject(self.smaxSB)

        # On select
        self.canvas_fk.register_on_select(self.on_select,
                                          rectprops=dict(alpha=0.2,
                                                         facecolor='red'))
        self.fminFK_bind = BindPyqtObject(self.fminFKSB)
        self.fmaxFK_bind = BindPyqtObject(self.fmaxFKSB)
        self.overlap_bind = BindPyqtObject(self.overlapSB)
        self.timewindow_bind = BindPyqtObject(self.timewindowSB)
        self.smaxFK_bind = BindPyqtObject(self.slowFKSB)
        self.slow_grid_bind = BindPyqtObject(self.gridFKSB)

        # Bind buttons
        self.selectDirBtnFK.clicked.connect(
            lambda: self.on_click_select_directory(self.root_pathFK_bind))
        self.datalessBtn.clicked.connect(
            lambda: self.on_click_select_metadata_file(self.metadata_path_bind
                                                       ))

        # Bind buttons BackProjection
        self.selectDirBtnBP.clicked.connect(
            lambda: self.on_click_select_directory(self.root_pathBP_bind))
        self.datalessBtnBP.clicked.connect(
            lambda: self.on_click_select_metadata_file(self.
                                                       metadata_path_bindBP))
        self.outputBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.output_path_bindBP))

        #Action Buttons
        self.arfBtn.clicked.connect(lambda: self.arf())
        self.runFKBtn.clicked.connect(lambda: self.FK_plot())
        self.plotBtn.clicked.connect(lambda: self.plot_seismograms())
        self.plotBtnBP.clicked.connect(lambda: self.plot_seismograms(FK=False))
        self.actionSettings.triggered.connect(
            lambda: self.open_parameters_settings())
        self.actionProcessed_Seimograms.triggered.connect(self.write)
        self.actionStacked_Seismograms.triggered.connect(self.write_stack)
        self.stationsBtn.clicked.connect(lambda: self.stationsInfo())
        self.stationsBtnBP.clicked.connect(lambda: self.stationsInfo(FK=False))
        self.mapBtn.clicked.connect(self.stations_map)
        self.actionCreate_Stations_File.triggered.connect(
            self.stations_coordinates)
        self.actionLoad_Stations_File.triggered.connect(self.load_path)
        self.actionRunVespagram.triggered.connect(self.open_vespagram)
        self.shortcut_open = pw.QShortcut(pqg.QKeySequence('Ctrl+O'), self)
        self.shortcut_open.activated.connect(self.open_solutions)
        self.create_gridBtn.clicked.connect(self.create_grid)
        self.actionOpen_Help.triggered.connect(lambda: self.open_help())
        self.load_videoBtn.clicked.connect(self.loadvideoBP)

        # help Documentation
        self.help = HelpDoc()

        # Parameters settings
        self.__parameters = ParametersSettings()

        # Stations Coordinates
        self.__stations_coords = StationsCoords()

        # picks
        self.picks = {
            'Time': [],
            'Phase': [],
            'BackAzimuth': [],
            'Slowness': [],
            'Power': []
        }

        # video
        self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.player.setVideoOutput(self.backprojection_widget)
        self.player.stateChanged.connect(self.mediaStateChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.durationChanged.connect(self.durationChanged)
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play_bp)
        self.positionSlider.sliderMoved.connect(self.setPosition)
class TimeAnalysisWidget(pw.QFrame, UiTimeAnalysisWidget):
    def __init__(self, parent, current_index=-1, parent_name=None):

        super(TimeAnalysisWidget, self).__init__()
        self.setupUi(self)
        ParentWidget.set_parent(parent, self, current_index)

        if parent_name:  # add parent name if given. Helps to make difference between the same widget
            self.parent_name = parent_name

        # embed matplotlib to qt widget
        self.canvas = MatplotlibCanvas(self.plotMatWidget, nrows=2)
        self.canvas.set_xlabel(1, "Time (s)")
        self.canvas.on_double_click(self.on_double_click_matplotlib)

        self.time_selector = TimeSelectorBox(self.PlotToolsWidget, 0)
        self.filter = FilterBox(self.PlotToolsWidget, 1)
        self.spectrum_box = SpectrumBox(self.PlotToolsWidget, 3)
        self.station_info = StationInfoBox(self.PlotToolsWidget, 4)

        # bind buttons
        self.plotSeismogramBtn.clicked.connect(
            lambda: self.on_click_plot_seismogram(self.canvas))
        self.plotArrivalsBtn.clicked.connect(
            lambda: self.on_click_plot_arrivals(self.canvas))
        self.spectrum_box.register_plot_mtp(
            lambda: self.on_click_mtp(self.canvas))
        self.spectrum_box.register_plot_cwt(
            lambda: self.on_click_cwt(self.canvas))

        self.__file_selector = None
        self.__event_info = None
        self.is_envelop_checked = False

    def register_file_selector(self, file_selector: FilesView):
        self.__file_selector = file_selector

    def set_event_info(self, event_into: EventInfoBox):
        self.__event_info = event_into

    @property
    def file_selector(self) -> FilesView:
        return self.__file_selector

    @property
    def event_info(self) -> EventInfoBox:
        return self.__event_info

    @property
    def tracer_stats(self):
        return ObspyUtil.get_stats(self.file_selector.file_path)

    @property
    def stream(self):
        return read(self.file_selector.file_path)

    @property
    def trace(self):
        return ObspyUtil.get_tracer_from_file(self.file_selector.file_path)

    def validate_file(self):
        if not MseedUtil.is_valid_mseed(self.file_selector.file_path):
            msg = "The file {} is not a valid mseed. Please, choose a valid format".\
                format(self.file_selector.file_name)
            md = MessageDialog(self)
            md.set_info_message(msg)
            raise InvalidFile(msg)

    def filter_error_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    def get_data(self):

        filter_value = self.filter.filter_value

        f_min = self.filter.min_freq
        f_max = self.filter.max_freq

        t1 = self.time_selector.start_time
        t2 = self.time_selector.end_time

        sd = SeismogramData.from_tracer(self.trace)
        return sd.get_waveform(filter_error_callback=self.filter_error_message,
                               filter_value=filter_value,
                               f_min=f_min,
                               f_max=f_max,
                               start_time=t1,
                               end_time=t2)

    def get_time_window(self):
        t1 = self.time_selector.start_time
        t2 = self.time_selector.end_time

        return t1, t2

    def plot_seismogram(self, canvas):
        tr = self.get_data()
        t = tr.times()
        s1 = tr.data
        canvas.plot(t, s1, 0, color="black", linewidth=0.5)

        if self.is_envelop_checked:
            analytic_sygnal = hilbert(s1)
            envelope = np.abs(analytic_sygnal)
            canvas.plot(t,
                        envelope,
                        0,
                        clear_plot=False,
                        linewidth=0.5,
                        color='sandybrown')

    def plot_mt_spectrogram(self, canvas: MatplotlibCanvas):
        win = int(self.spectrum_box.win_bind.value *
                  self.tracer_stats.Sampling_rate)
        tbp = self.spectrum_box.tw_bind.value
        ntapers = self.spectrum_box.ntapers_bind.value
        f_min = self.filter.min_freq
        f_max = self.filter.max_freq
        ts, te = self.get_time_window()

        mtspectrogram = MTspectrogram(self.file_selector.file_path, win, tbp,
                                      ntapers, f_min, f_max)
        x, y, log_spectrogram = mtspectrogram.compute_spectrogram(
            start_time=ts, end_time=te, trace_filter=self.filter.filter_value)
        canvas.plot_contour(x,
                            y,
                            log_spectrogram,
                            axes_index=1,
                            clabel="Power [dB]",
                            cmap=plt.get_cmap("jet"))
        canvas.set_xlabel(1, "Time (s)")

    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 on_click_plot_seismogram(self, canvas):
        try:
            self.validate_file()
            self.update_station_info()
            self.plot_seismogram(canvas)
        except InvalidFile:
            pass

    def on_click_mtp(self, canvas):
        try:
            self.validate_file()
            self.update_station_info()
            self.plot_mt_spectrogram(canvas)
        except InvalidFile:
            pass

    def on_click_cwt(self, canvas):
        try:
            self.validate_file()
            self.update_station_info()
            self.plot_cwt_spectrogram(canvas)
        except InvalidFile:
            pass

    def on_double_click_matplotlib(self, event, canvas):
        pass

    def on_click_plot_arrivals(self, canvas):
        self.update_station_info()
        self.plot_arrivals(canvas)

    def update_station_info(self):
        self.station_info.set_basic_info(self.tracer_stats)

    def plot_arrivals(self, canvas):
        self.event_info.set_canvas(canvas)
        station_stats = StationsStats(self.tracer_stats.Station,
                                      self.station_info.latitude,
                                      self.station_info.longitude, 0.)
        self.event_info.plot_arrivals(0, self.time_selector.start_time,
                                      station_stats)
Example #27
0
class FrequencyTimeFrame(pw.QWidget, UiFrequencyTime):
    def __init__(self):
        super(FrequencyTimeFrame, self).__init__()
        self.setupUi(self)
        self.solutions = []
        self.periods_now = []
        self.colors = ["white", "green", "black"]
        self._stations_info = {}
        self.parameters = ParametersSettings()
        # Binds
        self.root_path_bind = BindPyqtObject(self.rootPathForm_2, self.onChange_root_path)
        self.canvas_plot1 = MatplotlibCanvas(self.widget_plot_up, ncols=2, sharey  = True)
        top = 0.900
        bottom = 0.180
        left = 0.045
        right = 0.720
        wspace = 0.135
        self.canvas_plot1.figure.subplots_adjust(left=left, bottom=bottom, right=right, top=top, wspace=wspace, hspace=0.0)

        ax = self.canvas_plot1.get_axe(0)
        left,width = 0.2, 0.55
        bottom, height = 0.180, 0.72
        spacing = 0.02
        coords_ax = [left+width+spacing, bottom, 0.2, height]
        self.fig = ax.get_figure()
        #self.ax_seism1 = self.fig.add_axes(coords_ax, sharey = ax)
        self.ax_seism1 = self.fig.add_axes(coords_ax)
        self.ax_seism1.yaxis.tick_right()


        # Add file selector to the widget
        self.file_selector = FilesView(self.root_path_bind.value, parent=self.fileSelectorWidget_2,
                                       on_change_file_callback=lambda file_path: self.onChange_file(file_path))

        # Binds
        self.selectDirBtn_2.clicked.connect(lambda: self.on_click_select_directory(self.root_path_bind))

        # action
        self.plotBtn.clicked.connect(self.plot_seismogram)
        self.plot2Btn.clicked.connect(self.run_phase_vel)
        self.stationsBtn.clicked.connect(self.stations_info)
        self.macroBtn.clicked.connect(lambda: self.open_parameters_settings())
        # clicks
        self.canvas_plot1.on_double_click(self.on_click_matplotlib)
        self.canvas_plot1.mpl_connect('key_press_event', self.key_pressed)

    def open_parameters_settings(self):
        self.parameters.show()

    def filter_error_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    def onChange_root_path(self, value):
        """
        Fired every time the root_path is changed

        :param value: The path of the new directory.

        :return:
        """
        self.file_selector.set_new_rootPath(value)


    def onChange_file(self, file_path):
        # Called every time user select a different file
        pass

    def on_click_select_directory(self, bind: BindPyqtObject):
        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', bind.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', bind.value,
                                                           pw.QFileDialog.DontUseNativeDialog)
        if dir_path:
            bind.value = dir_path

    def on_click_select_file(self, bind: BindPyqtObject):
        selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file")
        if isinstance(selected[0], str) and os.path.isfile(selected[0]):
            bind.value = selected[0]

    def find_indices(self, lst, condition):

        return [i for i, elem in enumerate(lst) if condition(elem)]

    def find_nearest(self, a, a0):
        "Element in nd array `a` closest to the scalar value `a0`"
        idx = np.abs(a - a0).argmin()
        return a.flat[idx], idx

    def stations_info(self):
        sd = []
        st = read(self.file_selector.file_path)
        tr = st[0]
        sd.append([tr.stats.network, tr.stats.station, tr.stats.location, tr.stats.channel, tr.stats.starttime,
                       tr.stats.endtime, tr.stats.sampling_rate, tr.stats.npts])

        self._stations_info = StationsInfo(sd, check= False)
        self._stations_info.show()



    @property
    def trace(self):
        return ObspyUtil.get_tracer_from_file(self.file_selector.file_path)

    def get_data(self):
        parameters = self.parameters.getParameters()
        file = self.file_selector.file_path
        try:

            sd = SeismogramDataAdvanced(file_path = file)
            tr = sd.get_waveform_advanced(parameters, {}, filter_error_callback=self.filter_error_message)
            #tr = st[0]
            t = tr.times()

            return tr, t
        except:
            return []

    def convert_2_vel(self, tr):

        geodetic = tr.stats.mseed['geodetic']
        dist = geodetic[0]

        return dist


    #@AsycTime.run_async()
    def plot_seismogram(self):

        [tr1, t] = self.get_data()
        tr = tr1.copy()
        fs = tr1.stats.sampling_rate
        selection = self.time_frequencyCB.currentText()
        # take into acount causality

        if self.causalCB.currentText() == "Causal":
            starttime = tr.stats.starttime
            endtime = tr.stats.starttime+int(len(tr.data) / (2*fs))
            tr.trim(starttime=starttime,endtime=endtime)
            data = np.flip(tr.data)
            tr.data = data

        else:
            starttime = tr.stats.starttime +int(len(tr.data) / (2*fs))
            endtime =  tr.stats.endtime
            tr.trim(starttime=starttime, endtime=endtime)


        if selection == "Continuous Wavelet Transform":

            nf = self.atomsSB.value()
            f_min = 1 / self.period_max_cwtDB.value()
            f_max = 1/  self.period_min_cwtDB.value()
            wmin = self.wminSB.value()
            wmax = self.wminSB.value()
            npts = len(tr.data)
            t = np.linspace(0, tr.stats.delta * npts, npts)
            cw = ConvolveWaveletScipy(tr)
            wavelet=self.wavelet_typeCB.currentText()

            m = self.wavelets_param.value()

            cw.setup_wavelet(wmin=wmin, wmax=wmax, tt=int(fs/f_min), fmin=f_min, fmax=f_max, nf=nf,
                                 use_wavelet = wavelet, m = m, decimate=False)

            scalogram2 = cw.scalogram_in_dbs()
            phase, inst_freq, ins_freq_hz = cw.phase() # phase in radians
            inst_freq = ins_freq_hz
            #delay = cw.get_time_delay()
            x, y = np.meshgrid(t, np.logspace(np.log10(f_min), np.log10(f_max), scalogram2.shape[0]))
            #x = x + delay
            # chop cero division
            dist = self.convert_2_vel(tr)
            vel = (dist / (x[:, 1:] * 1000))
            min_time_idx = fs * (dist / (self.max_velDB.value() * 1000))
            min_time_idx = int(min_time_idx)
            max_time_idx = fs * (dist / (self.min_velDB.value() * 1000))
            max_time_idx = int(max_time_idx)
            period = 1 / y[:, 1:]
            scalogram2 = scalogram2[:, 1:]

            if self.ftCB.isChecked():
                min_vel, idx_min_vel = self.find_nearest(vel[0, :], self.min_velDB.value())
                max_vel, idx_max_vel = self.find_nearest(vel[0, :], self.max_velDB.value())
                self.min_vel = min_vel
                self.max_vel = max_vel
                vel = vel[:, idx_max_vel:idx_min_vel]
                period = period[:, idx_max_vel:idx_min_vel]
                scalogram2 = scalogram2[:, idx_max_vel:idx_min_vel]
                phase = phase[:, idx_max_vel:idx_min_vel]
                inst_freq = inst_freq[:, idx_max_vel:idx_min_vel]


            scalogram2 = np.clip(scalogram2, a_min=self.minlevelCB.value(), a_max=0)
            min_cwt= self.minlevelCB.value()
            max_cwt = 0

            #scalogram2 = scalogram2+0.01

            # flips
            scalogram2 = scalogram2.T
            scalogram2 = np.fliplr(scalogram2)
            scalogram2 = np.flipud(scalogram2)
            self.scalogram2 = scalogram2

            phase = phase.T
            phase = np.fliplr(phase)
            phase = np.flipud(phase)
            self.phase = phase

            inst_freq = inst_freq.T
            inst_freq = np.fliplr(inst_freq)
            inst_freq = np.flipud(inst_freq)
            self.inst_freq = inst_freq

            vel = vel.T
            vel = np.flipud(vel)
            self.vel = vel

            period = period.T
            period = np.fliplr(period)

            # extract ridge

            ridge = np.max(scalogram2, axis = 0)

            distance = self.dist_ridgDB.value()*vel.shape[0]/(max_vel-min_vel)
            height = (self.minlevelCB.value(),0)
            ridges, peaks, group_vel = self.find_ridges(scalogram2, vel, height, distance, self.numridgeSB.value())

            #print(ridges)
            #ridge_vel = []
            # for j in range(len(ridge)):
             #   value, idx = self.find_nearest(scalogram2[:,j],ridge[j])
             #    ridge_vel.append(vel[idx,j])

            self.t = dist/(1000*vel)
            self.dist = dist/1000
            # phase_vel = self.phase_vel(scalogram2, ridge, phase, inst_freq, t, dist/1000, n)
            # phase_vel = np.flipud(phase_vel)

            # Plot
            self.ax_seism1.cla()
            self.ax_seism1.plot(tr.data, tr.times() / tr.stats.sampling_rate, linewidth=0.5)
            self.ax_seism1.plot(tr.data[min_time_idx:max_time_idx],
                                tr.times()[min_time_idx:max_time_idx] / tr.stats.sampling_rate,
                                color='red', linewidth=0.5)

            self.ax_seism1.set_xlabel("Amplitude")
            self.ax_seism1.set_ylabel("Time (s)")
            self.canvas_plot1.clear()
            self.canvas_plot1.plot_contour(period, vel, scalogram2, axes_index=1, levels = 100, clabel="Power [dB]",
                        cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt, antialiased=True, xscale = "log")

            self.canvas_plot1.set_xlabel(1, "Period (s)")
            self.canvas_plot1.set_ylabel(1, "Group Velocity (km/s)")

            # Plot ridges

            for k in range(self.numridgeSB.value()):
                self.canvas_plot1.plot(period[0,:], group_vel[k], axes_index=1, marker=".", color = self.colors[k],
                                       clear_plot=False)

            self.group_vel = group_vel
            self.periods = period[0,:]

        if selection == "Hilbert-Multiband":

            f_min = 1 / self.period_max_mtDB.value()
            f_max = 1/  self.period_min_mtDB.value()

            npts = len(tr.data)
            t = np.linspace(0, tr.stats.delta * npts, npts)
            hg = hilbert_gauss(tr, f_min, f_max, self.freq_resDB.value())
            scalogram2, phase, inst_freq, inst_freq_hz, f = hg.compute_filter_bank()
            inst_freq = inst_freq_hz
            scalogram2 = hg.envelope_db()

            x, y = np.meshgrid(t, f[0:-1])

            # chop cero division
            dist = self.convert_2_vel(tr)
            vel = (dist / (x[:, 1:] * 1000))
            min_time_idx = fs * (dist / (self.max_velDB.value() * 1000))
            min_time_idx = int(min_time_idx)
            max_time_idx = fs * (dist / (self.min_velDB.value() * 1000))
            max_time_idx = int(max_time_idx)
            period = 1 / y[:, 1:]
            scalogram2 = scalogram2[:, 1:]

            if self.ftCB.isChecked():
                min_vel, idx_min_vel = self.find_nearest(vel[0, :], self.min_velDB.value())
                max_vel, idx_max_vel = self.find_nearest(vel[0, :], self.max_velDB.value())
                self.min_vel = min_vel
                self.max_vel = max_vel
                vel = vel[:, idx_max_vel:idx_min_vel]
                period = period[:, idx_max_vel:idx_min_vel]
                scalogram2 = scalogram2[:, idx_max_vel:idx_min_vel]
                phase = phase[:, idx_max_vel:idx_min_vel]
                inst_freq = inst_freq[:, idx_max_vel:idx_min_vel]

            scalogram2 = np.clip(scalogram2, a_min=self.minlevelCB.value(), a_max=0)
            min_cwt = self.minlevelCB.value()
            max_cwt = 0

            # flips
            scalogram2 = scalogram2.T
            scalogram2 = np.fliplr(scalogram2)
            scalogram2 = np.flipud(scalogram2)
            self.scalogram2 = scalogram2

            phase = phase.T
            phase = np.fliplr(phase)
            phase = np.flipud(phase)
            self.phase = phase

            inst_freq = inst_freq.T
            inst_freq = np.fliplr(inst_freq)
            inst_freq = np.flipud(inst_freq)
            self.inst_freq = inst_freq

            vel = vel.T
            vel = np.flipud(vel)
            self.vel = vel

            period = period.T
            period = np.fliplr(period)

            # extract ridge

            ridge = np.max(scalogram2, axis=0)

            distance = self.dist_ridgDB.value() * vel.shape[0] / (max_vel - min_vel)
            height = (self.minlevelCB.value(), 0)
            ridges, peaks, group_vel = self.find_ridges(scalogram2, vel, height, distance, self.numridgeSB.value())

            # print(ridges)
            # ridge_vel = []
            # for j in range(len(ridge)):
            #   value, idx = self.find_nearest(scalogram2[:,j],ridge[j])
            #    ridge_vel.append(vel[idx,j])

            self.t = dist / (1000 * vel)
            self.dist = dist / 1000
            # phase_vel = self.phase_vel(scalogram2, ridge, phase, inst_freq, t, dist/1000, n)
            # phase_vel = np.flipud(phase_vel)

            # Plot
            self.ax_seism1.cla()
            self.ax_seism1.plot(tr.data, tr.times() / tr.stats.sampling_rate, linewidth=0.5)
            self.ax_seism1.plot(tr.data[min_time_idx:max_time_idx],
                                tr.times()[min_time_idx:max_time_idx] / tr.stats.sampling_rate,
                                color='red', linewidth=0.5)

            self.ax_seism1.set_xlabel("Amplitude")
            self.ax_seism1.set_ylabel("Time (s)")
            self.canvas_plot1.clear()
            self.canvas_plot1.plot_contour(period, vel, scalogram2, axes_index=1, levels=100, clabel="Power [dB]",
                                           cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt, antialiased=True,
                                           xscale="log")

            self.canvas_plot1.set_xlabel(1, "Period (s)")
            self.canvas_plot1.set_ylabel(1, "Group Velocity (km/s)")

            # Plot ridges

            for k in range(self.numridgeSB.value()):
                self.canvas_plot1.plot(period[0, :], group_vel[k], axes_index=1, marker=".", color=self.colors[k],
                                       clear_plot=False)

            self.group_vel = group_vel
            self.periods = period[0, :]




    def run_phase_vel(self):

        phase_vel_array = self.phase_vel2()
        phase_vel__array = np.flipud(phase_vel_array)
        test = np.arange(-5, 5, 1)
    # Plot phase vel

        ax2 = self.canvas_plot1.get_axe(0)
        ax2.cla()
        for k in range(len(test)):
            ax2.semilogx(self.periods_now, phase_vel_array[k,:], linewidth = 0.0, marker=".")
            #self.canvas_plot1.plot_contour(self.periods_now, phase_vel_array[k,:],np.ones([1, len(self.periods_now)]),
            #                                0, "scatter", show_colorbar=False, marker = '.', xscale="log")

            #self.canvas_plot1.plot(self.periods_now, phase_vel_array[k,:], axes_index=0, marker=".", clear_plot=False,
            #                       xscale="log")

        if self.ftCB.isChecked():
          ax2.set_xlim(self.period_min_cwtDB.value(), self.period_max_cwtDB.value())
          ax2.set_ylim(self.min_vel, self.max_vel)
    #
        self.canvas_plot1.set_xlabel(0, "Period (s)")
        self.canvas_plot1.set_ylabel(0, "Phase Velocity (km/s)")

    def phase_vel2(self):
        landa = -1*np.pi/4
        phase_vel_array = np.zeros([len(np.arange(-5, 5, 1)), len(self.solutions)])
        for k in np.arange(-5, 5, 1):
            for j in range(len(self.solutions)):
                value_period, idx_period = self.find_nearest(self.periods, self.periods_now[j])
                value_group_vel, idx_group_vel = self.find_nearest(self.vel[:,0], self.solutions[j])
                to = self.t[idx_group_vel , 0]
                phase_test = self.phase[idx_group_vel, idx_period]
                inst_freq_test = self.inst_freq[idx_group_vel, idx_period]
                phase_vel_num = self.dist * inst_freq_test
                phase_vel_den = phase_test+inst_freq_test*to-(np.pi/4)-k*2*np.pi+landa
                phase_vel_array[k, j] = phase_vel_num / phase_vel_den

        return phase_vel_array

    def phase_vel(self, scalogram2, ridge, phase, inst_freq, t, dist, n):

        # extract phase_vel info

        phase_vel_array = np.zeros([n, len(ridge)])
        for k in np.arange(-5, 5, 1):
            for j in range(len(ridge)):
                value, idx = self.find_nearest(scalogram2[:, j], ridge[j])
                to = t[idx, j]
                phase_test = phase[idx, j]
                inst_freq_test = inst_freq[idx, j]
                phase_vel_num = dist * inst_freq_test
                phase_vel_den = phase_test+inst_freq_test*to-(np.pi/4)-k*2*np.pi
                phase_vel_array[k, j] = phase_vel_num / phase_vel_den

        return phase_vel_array

    def find_ridges(self, scalogram2, vel, height, distance, num_ridges):

        distance = int(distance)
        dim = scalogram2.shape[1]
        ridges = np.zeros([num_ridges, dim])
        peak = np.zeros([num_ridges, dim])
        group_vel = np.zeros([num_ridges, dim])

        for j in range(dim):

            peaks, properties = find_peaks(scalogram2[:,j], height = height, threshold=-5, distance = distance)

            for k in range(num_ridges):

                try:
                    if len(peaks)>0:
                        ridges[k, j] = peaks[k]

                        peak[k, j] =  properties['peak_heights'][k]
                        group_vel[k,j] =vel[int(peaks[k]),0]
                    else:
                        ridges[k, j] = "NaN"
                        peak[k, j] = "NaN"
                        group_vel[k, j] = "NaN"

                except:

                    ridges[k, j] = "NaN"
                    peak[k, j] = "NaN"
                    group_vel[k, j] = "NaN"


        return ridges, peak, group_vel


    def on_click_matplotlib(self, event, canvas):
        if isinstance(canvas, MatplotlibCanvas):

            x1_value, y1_value = event.xdata, event.ydata

            period, pick_vel,_ = self.find_pos(x1_value, y1_value)
            self.solutions.append(pick_vel)
            self.periods_now.append(period)
            self.canvas_plot1.plot(period, pick_vel, color = "purple", axes_index = 1, clear_plot = False, marker = "." )

    def find_pos(self, x1, y1):

        value_period, idx_periods = self.find_nearest(self.periods, x1)
        dim = self.group_vel.shape[0]
        rms = []

        for k in range(dim):
            group_vel_test = self.group_vel[k, :][idx_periods]
            err = abs(group_vel_test - y1)
            if err>0:
                rms.append(err)
            else:
                err=100
                rms.append(err)

        rms = np.array(rms)
        idx = np.argmin(rms)

        return value_period, self.group_vel[idx, idx_periods], idx

    def key_pressed(self, event):

        if event.key == 'r':
            x1_value, y1_value = event.xdata, event.ydata
            print(x1_value, y1_value)
            period, pick_vel,idx = self.find_pos(x1_value, y1_value)
            # check if is in solutions
            if period in self.periods_now and pick_vel in self.solutions:
                self.periods_now.remove(period)
                self.solutions.remove(pick_vel)
                self.canvas_plot1.plot(period, pick_vel, color=self.colors[idx], axes_index=1, clear_plot=False, marker=".")


    # if selection == "Multitaper Spectrogram":
    #
    #     win = int(self.mt_window_lengthDB.value() * tr.stats.sampling_rate)
    #     win_half = int(win / (2 * fs))
    #     tbp = self.time_bandwidth_DB.value()
    #     ntapers = self.number_tapers_mtSB.value()
    #     f_min = 1 / self.period_max_mtDB.value()
    #     f_max = 1 / self.period_min_mtDB.value()
    #     mtspectrogram = MTspectrogram(self.file_selector.file_path, win, tbp, ntapers, f_min, f_max)
    #     x, y, log_spectrogram = mtspectrogram.compute_spectrogram(tr)
    #     # x in seconds, y in freqs
    #     x = x + win_half
    #     # chop cero division
    #     dist = self.convert_2_vel(tr)
    #     vel = (dist / (x[:, 1:] * 1000))
    #     min_time_idx = fs * (dist / (self.max_velDB.value() * 1000))
    #     min_time_idx = int(min_time_idx)
    #     max_time_idx = fs * (dist / (self.min_velDB.value() * 1000))
    #     max_time_idx = int(max_time_idx)
    #     period = 1 / y[:, 1:]
    #     log_spectrogram = log_spectrogram[:, 1:]
    #
    #     if self.ftCB.isChecked():
    #         min_vel, idx_min_vel = self.find_nearest(vel[0, :], self.min_velDB.value())
    #         max_vel, idx_max_vel = self.find_nearest(vel[0, :], self.max_velDB.value())
    #         vel = vel[:, idx_max_vel:idx_min_vel]
    #         period = period[:, idx_max_vel:idx_min_vel]
    #         log_spectrogram = log_spectrogram[:, idx_max_vel:idx_min_vel]
    #
    #     log_spectrogram = np.clip(log_spectrogram, a_min=self.minlevelCB.value(), a_max=0.05)
    #     min_log_spectrogram = self.minlevelCB.value()
    #     max_log_spectrogram = 0.05
    #     log_spectrogram = log_spectrogram + 0.05
    #
    #     # flips
    #     log_spectrogram = log_spectrogram.T
    #     log_spectrogram = np.fliplr(log_spectrogram)
    #     log_spectrogram = np.flipud(log_spectrogram)
    #
    #     vel = vel.T
    #     vel = np.flipud(vel)
    #
    #     period = period.T
    #     period = np.fliplr(period)
    #
    #     # Plot
    #     self.ax_seism1.cla()
    #     self.ax_seism1.plot(tr.data, tr.times() / tr.stats.sampling_rate, linewidth=0.5)
    #     self.ax_seism1.plot(tr.data[min_time_idx:max_time_idx],
    #                         tr.times()[min_time_idx:max_time_idx] / tr.stats.sampling_rate,
    #                         color='red', linewidth=0.5)
    #
    #     self.ax_seism1.set_xlabel("Amplitude")
    #     self.ax_seism1.set_ylabel("Time (s)")
    #     self.canvas_plot1.clear()
    #     self.canvas_plot1.plot_contour(period, vel, log_spectrogram, axes_index=0, clabel="Power [dB]",
    #                                    cmap=plt.get_cmap("jet"), vmin=min_log_spectrogram, vmax=max_log_spectrogram,
    #                                    antialiased=True, xscale="log")
    #
    #     # ax = self.canvas_plot1.get_axe(0)
    #     # ax.clabel(cs, levels = levels, fmt = '%2.1', colors = 'k', fontsize = 12)
    #     self.canvas_plot1.set_xlabel(0, "Period (s)")
    #     self.canvas_plot1.set_ylabel(0, "Group Velocity (m/s)")
Example #28
0
class SyntheticsAnalisysFrame(pw.QMainWindow, UiSyntheticsAnalisysFrame):

    def __init__(self, parent: pw.QWidget = None):

        super(SyntheticsAnalisysFrame, self).__init__(parent)

        self.setupUi(self)
        ParentWidget.set_parent(parent, self)
        self.setWindowTitle('Synthetics Analysis Frame')
        self.setWindowIcon(pqg.QIcon(':\icons\pen-icon.png'))

        #Initialize parametrs for plot rotation
        self._z = {}
        self._r = {}
        self._t = {}
        self._st = {}
        self.inventory = {}
        parameters = {}

        self._generator = SyntheticsGeneratorDialog(self)

        # 3C_Component
        self.focmec_canvas = FocCanvas(self.widget_fp)
        self.canvas = MatplotlibCanvas(self.plotMatWidget_3C)
        self.canvas.set_new_subplot(3, ncols=1)

        # Map
        self.cartopy_canvas = CartopyCanvas(self.map_widget)

        # binds
        self.root_path_bind_3C = BindPyqtObject(self.rootPathForm_3C, self.onChange_root_path_3C)
        self.vertical_form_bind = BindPyqtObject(self.verticalQLineEdit)
        self.north_form_bind = BindPyqtObject(self.northQLineEdit)
        self.east_form_bind = BindPyqtObject(self.eastQLineEdit)
        self.generation_params_bind = BindPyqtObject(self.paramsPathLineEdit)

        # accept drops
        self.vertical_form_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.north_form_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.east_form_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.generation_params_bind.accept_dragFile(drop_event_callback=self.drop_event)
        self.paramsPathLineEdit.textChanged.connect(self._generationParamsChanged)

        # Add file selector to the widget
        self.file_selector = FilesView(self.root_path_bind_3C.value, parent=self.fileSelectorWidget)
        self.file_selector.setDragEnabled(True)

        self.selectDirBtn_3C.clicked.connect(self.on_click_select_directory_3C)
        self.plotBtn.clicked.connect(self.on_click_rotate)
        ###
        self.stationsBtn.clicked.connect(self.stationsInfo)
        ###

        self.actionGenerate_synthetics.triggered.connect(lambda : self._generator.show())

    def info_message(self, msg):
        md = MessageDialog(self)
        md.set_info_message(msg)

    def _generationParamsChanged(self):
        with open(self.generation_params_file, 'rb') as f:
            self.params = pickle.load(f)
            depth_est =self.params['sourcedepthinmeters']
            depth_est =(float(depth_est))/1000
           #self.paramsTextEdit.setPlainText(str(params))
            self.paramsTextEdit.setPlainText("Earth Model: {model}".format(model=self.params['model']))
            self.paramsTextEdit.appendPlainText("Event Coords: {lat} {lon} {depth}".format(
                lat=self.params['sourcelatitude'],lon=self.params['sourcelongitude'],
                              depth=str(depth_est)))
            self.paramsTextEdit.appendPlainText("Time: {time}".format(time=self.params['origintime']))
            self.paramsTextEdit.appendPlainText("Units: {units}".format(units=self.params['units']))

            if 'sourcedoublecouple' in self.params:
                self.paramsTextEdit.appendPlainText("Source: {source}".format(source= self.params['sourcedoublecouple']))
            if 'sourcemomenttensor' in self.params:
                self.paramsTextEdit.appendPlainText("Source: {source}".format(source= self.params['sourcemomenttensor']))


    @staticmethod
    def drop_event(event: pqg.QDropEvent, bind_object: BindPyqtObject):
        data = event.mimeData()
        url = data.urls()[0]
        bind_object.value = url.fileName()

    @property
    def north_component_file(self):
        return os.path.join(self.root_path_bind_3C.value, self.north_form_bind.value)

    @property
    def vertical_component_file(self):
        return os.path.join(self.root_path_bind_3C.value, self.vertical_form_bind.value)

    @property
    def east_component_file(self):
        return os.path.join(self.root_path_bind_3C.value, self.east_form_bind.value)

    @property
    def generation_params_file(self):
        return os.path.join(self.root_path_bind_3C.value, self.generation_params_bind.value)

    def onChange_root_path_3C(self, value):
        """
        Fired every time the root_path is changed

        :param value: The path of the new directory.

        :return:
        """
        self.file_selector.set_new_rootPath(value)

    # Function added for 3C Components
    def on_click_select_directory_3C(self):

        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', self.root_path_bind_3C.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', self.root_path_bind_3C.value,
                                                           pw.QFileDialog.DontUseNativeDialog)

        if dir_path:
            self.root_path_bind_3C.value = dir_path

    def on_click_rotate(self, canvas):
        time1 = convert_qdatetime_utcdatetime(self.dateTimeEdit_4)
        time2 = convert_qdatetime_utcdatetime(self.dateTimeEdit_5)

        try:
            sd = SeismogramData(self.vertical_component_file)
            z = sd.get_waveform()
            sd = SeismogramData(self.north_component_file)
            n = sd.get_waveform()
            sd = SeismogramData(self.east_component_file)
            e = sd.get_waveform()
            seismograms = [z, n, e]
            time = z.times("matplotlib")
            self._st = Stream(traces=seismograms)
            for index, data in enumerate(seismograms):
                self.canvas.plot(time, data, index, color="black", linewidth=0.5)
                info = "{}.{}.{}".format(self._st[index].stats.network, self._st[index].stats.station,
                                         self._st[index].stats.channel)
                ax = self.canvas.get_axe(0)
                ax.set_xlim(time1.matplotlib_date, time2.matplotlib_date)
                formatter = mdt.DateFormatter('%Y/%m/%d/%H:%M:%S')
                ax.xaxis.set_major_formatter(formatter)
                self.canvas.set_plot_label(index, info)

            self.canvas.set_xlabel(2, "Time (s)")

            if 'sourcedoublecouple' in self.params:
                self.focmec_canvas.drawSynthFocMec(0, first_polarity = self.params['sourcedoublecouple'], mti = [])
            if 'sourcemomenttensor' in self.params:
                self.focmec_canvas.drawSynthFocMec(0, first_polarity= [], mti=self.params['sourcemomenttensor'])

        except InvalidFile:
            self.info_message("Invalid mseed files. Please, make sure you have generated correctly the synthetics")

        self.__map_coords()


    def stationsInfo(self):
        files = []
        try:
            if self.vertical_component_file and self.north_component_file and self.east_component_file:
                files = [self.vertical_component_file, self.north_component_file, self.east_component_file]
        except:
            pass

        sd = []
        if len(files)==3:
            for file in files:
                try:
                    st = SeismogramDataAdvanced(file)

                    station = [st.stats.Network,st.stats.Station,st.stats.Location,st.stats.Channel,st.stats.StartTime,
                           st.stats.EndTime, st.stats.Sampling_rate, st.stats.Npts]

                    sd.append(station)
                except:
                    pass

            self._stations_info = StationsInfo(sd)
            self._stations_info.show()

    def __map_coords(self):
        map_dict = {}
        sd = []
        with open(self.generation_params_file, 'rb') as f:
            params = pickle.load(f)

        n = len(params["bulk"])
        for j in range(n):

            for key in params["bulk"][j]:
                if key == "latitude":
                   lat = params["bulk"][j][key]

                elif key == "longitude":
                    lon = params["bulk"][j][key]

                #elif key == "networkcode":
                #    net = params["bulk"][j][key]

                elif key == "stationcode":
                    sta = params["bulk"][j][key]

                    sd.append(sta)
                    map_dict[sta] = [lon, lat]


        self.cartopy_canvas.plot_map(params['sourcelongitude'], params['sourcelatitude'], 0, 0, 0, 0,
                                     resolution='low', stations=map_dict)