Пример #1
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()
Пример #2
0
class TimeFrequencyFrame(BaseFrame, UiTimeFrequencyFrame):
    def __init__(self, ):
        super(TimeFrequencyFrame, self).__init__()
        self.setupUi(self)

        self.dayplot_frame = None

        # Bind buttons
        self.selectDirBtn.clicked.connect(self.on_click_select_directory)
        self.dayPlotBtn.clicked.connect(self.on_click_dayplot)

        # Bind qt objects
        self.root_path_bind = BindPyqtObject(self.rootPathForm,
                                             self.onChange_root_path)

        self.event_info = EventInfoBox(self.mainToolsWidget, None)
        self.event_info.set_buttons_visibility(False)

        # 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))

        self.time_analysis_widget = TimeAnalysisWidget(
            self.canvasWidget, parent_name="time_analysis_0")
        self.time_analysis_widget2 = TimeAnalysisWidget(
            self.canvasWidget, parent_name="time_analysis_1")

        self.time_analysis_windows = [
            self.time_analysis_widget, self.time_analysis_widget2
        ]
        for taw in self.time_analysis_windows:
            taw.register_file_selector(self.file_selector)
            taw.set_event_info(self.event_info)

        self.actionPlotEnvelope.toggled.connect(self.on_envelop_toggle)

    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_envelop_toggle(self, checked: bool):
        for taw in self.time_analysis_windows:
            taw.is_envelop_checked = checked

    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 on_click_select_directory(self):
        if "darwin" == platform:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', self.root_path_bind.value)
        else:
            dir_path = pw.QFileDialog.getExistingDirectory(
                self, 'Select Directory', self.root_path_bind.value,
                pw.QFileDialog.DontUseNativeDialog)

        if dir_path:
            self.root_path_bind.value = dir_path

    def plot_day_view(self):
        st = read(self.file_selector.file_path)
        self.dayplot_frame = MatplotlibFrame(st, type='dayplot')
        self.dayplot_frame.show()

    def on_click_dayplot(self):
        try:
            self.validate_file()
            self.plot_day_view()
        except InvalidFile as e:
            md = MessageDialog(self)
            md.set_info_message(e.message)
Пример #3
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()
Пример #4
0
class MTIFrame(BaseFrame, UiMomentTensor):
    def __init__(self):
        super(MTIFrame, self).__init__()
        self.setupUi(self)

        #super(MTIFrame, self).__init__()
        self.setupUi(self)
        self.__stations_dir = None
        self.__metadata_manager = None
        self.inventory = {}
        self._stations_info = {}
        self.stream = None
        # Binding
        self.root_path_bind = BindPyqtObject(self.rootPathForm)
        #self.dataless_path_bind = BindPyqtObject(self.datalessPathForm)
        self.metadata_path_bind = BindPyqtObject(self.datalessPathForm,
                                                 self.onChange_metadata_path)
        self.earth_path_bind = BindPyqtObject(self.earth_modelPathForm)

        # Binds
        self.selectDirBtn.clicked.connect(
            lambda: self.on_click_select_directory(self.root_path_bind))
        self.datalessBtn.clicked.connect(
            lambda: self.on_click_select_metadata_file(self.metadata_path_bind
                                                       ))
        self.earthmodelBtn.clicked.connect(
            lambda: self.on_click_select_file(self.earth_path_bind))

        # Action Buttons
        self.actionSettings.triggered.connect(
            lambda: self.open_parameters_settings())
        self.plotBtn.clicked.connect(self.plot_seismograms)
        self.actionSettings.triggered.connect(
            lambda: self.open_parameters_settings())
        self.actionWrite.triggered.connect(self.write)
        self.actionEarth_Model.triggered.connect(
            lambda: self.open_earth_model())
        self.actionFrom_File.triggered.connect(
            lambda: self.load_event_from_isolapath())
        self.actionOpen_Help.triggered.connect(lambda: self.open_help())
        self.stationsBtn.clicked.connect(self.stationsInfo)
        self.run_inversionBtn.clicked.connect(lambda: self.run_inversion())
        self.stations_mapBtn.clicked.connect(lambda: self.plot_map_stations())
        self.plot_solutionBtn.clicked.connect(lambda: self.plot_solution())
        #self.earthmodelBtn.clicked.connect(self.read_earth_model)
        # Parameters settings
        self.parameters = ParametersSettings()
        self.earth_model = CrustalModelParametersFrame()
        # help Documentation

        self.help = HelpDoc()

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

    def open_earth_model(self):
        self.earth_model.show()

    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))

    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 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):
        file_path = pw.QFileDialog.getOpenFileName(self, 'Select Directory',
                                                   bind.value)
        file_path = file_path[0]

        if file_path:
            bind.value = file_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 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 read_earth_model(self):
    #     model = self.earth_model.getParametersWithFormat()
    #     print(model)

    def plot_seismograms(self):
        parameters = self.get_inversion_parameters()
        lat = float(parameters['latitude'])
        lon = float(parameters['longitude'])
        starttime = convert_qdatetime_utcdatetime(self.starttime_date)
        endtime = convert_qdatetime_utcdatetime(self.endtime_date)
        diff = endtime - starttime

        parameters = self.parameters.getParameters()
        all_traces = []
        obsfiles = MseedUtil.get_mseed_files(self.root_path_bind.value)
        obsfiles.sort()

        for file in obsfiles:
            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)

            all_traces.append(tr)

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

        if self.st:
            min_dist = self.min_distCB.value()
            max_dist = self.max_distCB.value()
            mt = MTIManager(self.st, self.inventory, lat, lon, min_dist,
                            max_dist)
            [self.stream, self.deltas,
             self.stations_isola_path] = mt.get_stations_index()

    def stationsInfo(self):

        file_path = self.root_path_bind.value
        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=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 not dir_path:
            return

        n = len(self.st)
        for j in range(n):
            tr = self.st[j]
            print(tr.id, "Writing data processed")
            path_output = os.path.join(dir_path, tr.id)
            tr.write(path_output, format="MSEED")

    ##In progress##
    def load_event_from_isolapath(self):
        root_path = os.path.dirname(os.path.abspath(__file__))
        file_path = pw.QFileDialog.getOpenFileName(self, 'Select Directory',
                                                   root_path)
        file = file_path[0]
        frame = pd.read_csv(file, sep='\s+', header=None)
        time = frame.iloc[3][0]
        year = time[0:4]
        mm = time[4:6]
        dd = time[6:8]
        hour = frame.iloc[4][0]
        minute = frame.iloc[5][0]
        sec = frame.iloc[6][0]
        sec = float(sec)
        dec = sec - int(sec)
        dec = int(sec)

        time = UTCDateTime(int(year), int(mm), int(dd), int(hour), int(minute),
                           int(sec), dec)
        event = {
            'lat': frame.iloc[0][0],
            'lon': frame.iloc[0][1],
            'depth': frame.iloc[1][0],
            'mag': frame.iloc[2][0],
            'time': time,
            'istitution': frame.iloc[7][0]
        }

        return event

    @AsycTime.run_async()
    def run_inversion(self):
        parameters = self.get_inversion_parameters()
        try:
            stations_map = self._stations_info.get_stations_map()
        except:
            md = MessageDialog(self)
            md.set_info_message("Press Stations info and check your selection")

        if len(self.stream) and len(stations_map) > 0:

            isola = ISOLA(self.stream,
                          self.deltas,
                          location_unc=parameters['location_unc'],
                          depth_unc=parameters['depth_unc'],
                          time_unc=parameters['time_unc'],
                          deviatoric=parameters['deviatoric'],
                          threads=8,
                          circle_shape=parameters['circle_shape'],
                          use_precalculated_Green=parameters['GFs'])
            #
            isola.set_event_info(parameters['latitude'],
                                 parameters['longitude'], parameters['depth'],
                                 parameters['magnitude'],
                                 parameters['origin_time'])
            #
            print(isola.event)
            #
            #
            if self.stations_isola_path:
                isola.read_network_coordinates(self.stations_isola_path)
                isola.set_use_components(stations_map)
                #print(isola.stations)
                isola.read_crust(self.earth_path_bind.value)

                isola.set_parameters(parameters['freq_max'],
                                     parameters['freq_min'])
                self.infoTx.setPlainText("Calculated GFs")
                if not isola.calculate_or_verify_Green():
                    exit()
                self.infoTx.appendPlainText("Filtered and trim")
                isola.trim_filter_data()
                try:

                    if parameters['covariance']:
                        self.infoTx.appendPlainText(
                            "Calculating Covariance Matrix")
                        isola.covariance_matrix(crosscovariance=True,
                                                save_non_inverted=True,
                                                save_covariance_function=True)
                except:
                    md = MessageDialog(self)
                    md.set_error_message(
                        "No Possible calculate covariance matrix, "
                        "please try increasing the noise time window")
            #
                self.infoTx.appendPlainText("decimate and shift")
                isola.decimate_shift()
                self.infoTx.appendPlainText("Run inversion")
                isola.run_inversion()
                self.infoTx.appendPlainText("Finished Inversion")
                isola.find_best_grid_point()
                isola.print_solution()
                isola.print_fault_planes()
                self.infoTx.appendPlainText("Plotting Solutions")
                if len(isola.grid) > len(isola.depths):
                    isola.plot_maps()
                    self.infoTx.appendPlainText("plot_maps")
                if len(isola.depths) > 1:
                    isola.plot_slices()
                    self.infoTx.appendPlainText("plot_slices")
                if len(isola.grid) > len(isola.depths) and len(
                        isola.depths) > 1:
                    isola.plot_maps_sum()
                    self.infoTx.appendPlainText("plot_maps_sum")

                try:

                    isola.plot_MT()
                    self.infoTx.appendPlainText("plot_MT")
                    isola.plot_uncertainty(n=400)
                    self.infoTx.appendPlainText("plot_uncertainty")
                    #plot_MT_uncertainty_centroid()
                    isola.plot_seismo('seismo.png')
                    isola.plot_seismo('seismo_sharey.png', sharey=True)
                    self.infoTx.appendPlainText("plot_seismo")

                    if self.covarianceCB.isChecked():
                        isola.plot_seismo('plot_seismo.png', cholesky=True)
                        self.infoTx.appendPlainText("plot_seismo_cova")
                        isola.plot_noise()
                        self.infoTx.appendPlainText("plot_noise")
                        isola.plot_spectra()
                        self.infoTx.appendPlainText("plot_spectra")

                    isola.plot_stations()
                    self.infoTx.appendPlainText("plot_stations")

                except:
                    print("Couldn't Plot")

                try:
                    if self.covarianceCB.isChecked():
                        isola.plot_covariance_matrix(colorbar=True)
                    #isola.plot_3D()
                except:
                    pass

                try:
                    isola.html_log(
                        h1='ISP Moment Tensor inversion',
                        plot_MT='centroid.png',
                        plot_uncertainty='uncertainty.png',
                        plot_stations='stations.png',
                        plot_seismo_cova='seismo_cova.png',
                        plot_seismo_sharey='seismo_sharey.png',
                        plot_spectra='spectra.png',
                        plot_noise='noise.png',
                        plot_covariance_matrix='covariance_matrix.png',
                        plot_maps='map.png',
                        plot_slices='slice.png',
                        plot_maps_sum='map_sum.png')
                except:
                    self.infoTx.appendPlainText("Couldn't load url")
                try:
                    isola.html_log(h1='ISP Moment Tensor inversion',
                                   plot_MT='centroid.png',
                                   plot_uncertainty='uncertainty.png',
                                   plot_stations='stations.png',
                                   plot_seismo_sharey='seismo_sharey.png',
                                   plot_maps='map.png',
                                   plot_slices='slice.png')
                except:
                    self.infoTx.appendPlainText("Couldn't load url")

                self.infoTx.appendPlainText(
                    "Moment Tensor Inversion Successfully done !!!, please plot last solution"
                )
            else:
                pass

    def plot_solution(self):

        path = os.path.join(ROOT_DIR, 'mti/output/index.html')
        url = pyc.QUrl.fromLocalFile(path)
        self.widget.load(url)

    def get_inversion_parameters(self):
        parameters = {
            'latitude': self.latDB.value(),
            'longitude': self.lonDB.value(),
            'depth': self.depthDB.value(),
            'origin_time': convert_qdatetime_utcdatetime(self.origin_time),
            'location_unc': self.location_uncDB.value(),
            'time_unc': self.timeDB.value(),
            'magnitude': self.magnitudeDB.value(),
            'depth_unc': self.depth_uncDB.value(),
            'freq_min': self.freq_min_DB.value(),
            'freq_max': self.freq_max_DB.value(),
            'deviatoric': self.deviatoricCB.isChecked(),
            'circle_shape': self.circle_shapeCB.isChecked(),
            'GFs': self.gfCB.isChecked(),
            'covariance': self.covarianceCB.isChecked()
        }
        return parameters

    def plot_map_stations(self):
        md = MessageDialog(self)
        md.hide()
        try:
            stations = []
            obsfiles = MseedUtil.get_mseed_files(self.root_path_bind.value)
            obsfiles.sort()
            try:
                if len(self.stream) > 0:
                    stations = ObspyUtil.get_stations_from_stream(self.stream)
            except:
                pass

            map_dict = {}
            sd = []

            for file in obsfiles:
                if len(stations) == 0:
                    st = SeismogramDataAdvanced(file)

                    name = st.stats.Network + "." + st.stats.Station

                    sd.append(name)

                    st_coordinates = self.__metadata_manager.extract_coordinates(
                        self.inventory, file)

                    map_dict[name] = [
                        st_coordinates.Latitude, st_coordinates.Longitude
                    ]
                else:
                    st = SeismogramDataAdvanced(file)
                    if st.stats.Station in stations:
                        name = st.stats.Network + "." + st.stats.Station

                        sd.append(name)

                        st_coordinates = self.__metadata_manager.extract_coordinates(
                            self.inventory, file)

                        map_dict[name] = [
                            st_coordinates.Latitude, st_coordinates.Longitude
                        ]
                    else:
                        pass

            self.map_stations = StationsMap(map_dict)
            self.map_stations.plot_stations_map(latitude=self.latDB.value(),
                                                longitude=self.lonDB.value())

            md.set_info_message("Station Map OK !!! ")
        except:
            md.set_error_message(
                " Please check you have process and plot seismograms and opened stations info,"
                "Please additionally check that your metada fits with your mseed files"
            )

        md.show()

    def open_help(self):
        self.help.show()
Пример #5
0
class PDFmanger:
    def __init__(self, scatter_x, scatter_y, scatter_z, pdf):
        """
        Plot stations map fro dictionary (key = stations name, coordinates)

        :param
        """
        self.x = scatter_x
        self.y = scatter_y
        self.z = scatter_z
        self.pdf = pdf

    def plot_scatter(self):

        from isp.Gui.Frames import MatplotlibFrame
        print("Plotting PDF")
        pdf = np.array(self.pdf) / np.max(self.pdf)

        left, width = 0.06, 0.65
        bottom, height = 0.1, 0.65
        spacing = 0.02
        rect_scatter = [left, bottom, width, height]
        rect_scatterlon = [left, bottom + height + spacing, width, 0.2]
        rect_scatterlat = [left + width + spacing, bottom, 0.2, height]

        fig = plt.figure(figsize=(10, 8))
        self.mpf = MatplotlibFrame(fig)
        ax_scatter = plt.axes(rect_scatter)
        ax_scatter.tick_params(direction='in',
                               top=True,
                               right=True,
                               labelsize=10)
        plt.scatter(self.x,
                    self.y,
                    s=10,
                    c=pdf,
                    alpha=0.5,
                    marker=".",
                    cmap=plt.cm.jet)
        plt.xlabel("Longitude", fontsize=10)
        plt.ylabel("Latitude", fontsize=10)
        ax_scatx = plt.axes(rect_scatterlon)
        ax_scatx.tick_params(direction='in', labelbottom=False, labelsize=10)
        plt.scatter(self.x,
                    self.z,
                    s=10,
                    c=pdf,
                    alpha=0.5,
                    marker=".",
                    cmap=plt.cm.jet)
        plt.ylabel("Depth (km)", fontsize=10)
        plt.gca().invert_yaxis()
        ax_scatx = plt.axes(rect_scatterlat)
        ax_scatx.tick_params(direction='in', labelleft=False, labelsize=10)
        ax_scaty = plt.axes(rect_scatterlat)
        ax_scaty.tick_params(direction='in')
        ax_scaty.tick_params(which='major', labelsize=10)
        plt.scatter(self.z,
                    self.y,
                    s=10,
                    c=pdf,
                    alpha=0.5,
                    marker=".",
                    cmap=plt.cm.jet)
        ax_scaty = plt.axes(rect_scatterlat)
        ax_scaty.tick_params(direction='in', labelsize=10)
        plt.xlabel("Depth (km)", fontsize=10)
        cax = plt.axes([0.95, 0.1, 0.02, 0.8])
        plt.colorbar(cax=cax)
        self.mpf.show()
Пример #6
0
progname = os.path.basename(sys.argv[0])
progversion = "0.1"

qApp = QtWidgets.QApplication(sys.argv)


def on_select(ax_index, xmin, xmax):
    mpf.canvas.plot(xmax, 2, ax_index, clear_plot=False, marker="o")
    mpf.canvas.draw()


def on_click(event, canvas):
    print(event, canvas)


def on_dlb_click(event, canvas):
    print(event, canvas)


mpf = MatplotlibFrame(None)
mpf.canvas.set_new_subplot(2, 1)
mpf.canvas.on_double_click(on_dlb_click)
mpf.canvas.register_on_select(on_select)
mpf.canvas.plot([1, 2, 3], [1, 2, 3], 0)
mpf.canvas.plot([1, 2, 3], [1, 2, 3], 1)

mpf.setWindowTitle("%s" % progname)
mpf.show()
sys.exit(qApp.exec_())
Пример #7
0
class StationsMap:

    def __init__(self, stations_dict):
        """
        Plot stations map fro dictionary (key = stations name, coordinates)

        :param
        """
        self.__stations_dict = stations_dict



    def plot_stations_map(self, **kwargs):
        from matplotlib.transforms import offset_copy
        import cartopy.crs as ccrs
        from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
        from owslib.wms import WebMapService
        from matplotlib.patheffects import Stroke
        import cartopy.feature as cfeature
        import shapely.geometry as sgeom
        from matplotlib import pyplot as plt
        from isp import ROOT_DIR
        import os
        os.environ["CARTOPY_USER_BACKGROUNDS"] = os.path.join(ROOT_DIR, "maps")
        # MAP_SERVICE_URL = 'https://gis.ngdc.noaa.gov/arcgis/services/gebco08_hillshade/MapServer/WMSServer'
        MAP_SERVICE_URL = 'https://www.gebco.net/data_and_products/gebco_web_services/2020/mapserv?'
        # MAP_SERVICE_URL = 'https://gis.ngdc.noaa.gov/arcgis/services/etopo1/MapServer/WMSServer'

        geodetic = ccrs.Geodetic(globe=ccrs.Globe(datum='WGS84'))
        #layer = 'GEBCO_08 Hillshade'
        layer ='GEBCO_2020_Grid'
        #layer = 'shaded_relief'

        epi_lat = kwargs.pop('latitude')
        epi_lon = kwargs.pop('longitude')

        name_stations = []
        lat = []
        lon = []
        for name, coords in self.__stations_dict.items():
            name_stations.append(name)
            lat.append(float(coords[0]))
            lon.append(float(coords[1]))

        #
        proj = ccrs.PlateCarree()
        fig, ax = plt.subplots(1, 1, subplot_kw=dict(projection=proj), figsize=(16, 12))
        self.mpf = MatplotlibFrame(fig)

        xmin = min(lon)-4
        xmax = max(lon)+4
        ymin = min(lat)-4
        ymax = max(lat)+4
        extent = [xmin, xmax, ymin, ymax]
        ax.set_extent(extent, crs=ccrs.PlateCarree())

        try:

            wms = WebMapService(MAP_SERVICE_URL)
            ax.add_wms(wms, layer)

        except:

            ax.background_img(name='ne_shaded', resolution="high")


        #geodetic_transform = ccrs.Geodetic()._as_mpl_transform(ax)
        geodetic_transform = ccrs.PlateCarree()._as_mpl_transform(ax)
        text_transform = offset_copy(geodetic_transform, units='dots', x=-25)
        ax.scatter(lon, lat, s=12, marker="^", color='red', alpha=0.7, transform=ccrs.PlateCarree())
        ax.plot(epi_lon, epi_lat, color='black', marker='*', markersize=8)
        N=len(name_stations)
        for n in range(N):
            lon1=lon[n]
            lat1 = lat[n]
            name = name_stations[n]

            ax.text(lon1, lat1, name, verticalalignment='center', horizontalalignment='right', transform=text_transform,
                bbox=dict(facecolor='sandybrown', alpha=0.5, boxstyle='round'))

        # Create an inset GeoAxes showing the Global location
        #sub_ax = self.mpf.canvas.figure.add_axes([0.70, 0.75, 0.28, 0.28],
        #                      projection=ccrs.PlateCarree())
        sub_ax = self.mpf.canvas.figure.add_axes([0.70, 0.73, 0.28, 0.28], projection=ccrs.PlateCarree())
        sub_ax.set_extent([-179.9, 180, -89.9, 90], geodetic)

        # Make a nice border around the inset axes.
        effect = Stroke(linewidth=4, foreground='wheat', alpha=0.5)
        sub_ax.outline_patch.set_path_effects([effect])

        # Add the land, coastlines and the extent .
        sub_ax.add_feature(cfeature.LAND)
        sub_ax.coastlines()
        extent_box = sgeom.box(extent[0], extent[2], extent[1], extent[3])
        sub_ax.add_geometries([extent_box], ccrs.PlateCarree(), facecolor='none',
                              edgecolor='blue', linewidth=1.0)

        gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                          linewidth=0.2, color='gray', alpha=0.2, linestyle='-')

        gl.top_labels = False
        gl.left_labels = False
        gl.xlines = False
        gl.ylines = False

        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER

        #plt.savefig("/Users/robertocabieces/Documents/ISPshare/isp/mti/output/stations.png", bbox_inches='tight')
        self.mpf.show()
Пример #8
0
class PlotToolsManager:

    def __init__(self, id):
        """
        Manage Plot signal analysis in Earthquake Frame.

        :param obs_file_path: The file path of pick observations.
        """
        self.__id = id


    def plot_spectrum(self, freq, spec, jackknife_errors):
        import matplotlib.pyplot as plt
        from isp.Gui.Frames import MatplotlibFrame
        fig, ax1 = plt.subplots(figsize=(6, 6))
        self.mpf = MatplotlibFrame(fig)
        ax1.loglog(freq, spec, linewidth=1.0, color='steelblue', label=self.__id)
        ax1.frequencies = freq
        ax1.spectrum = spec
        ax1.fill_between(freq, jackknife_errors[:, 0], jackknife_errors[:, 1], facecolor="0.75",
                         alpha=0.5, edgecolor="0.5")
        ax1.set_ylim(spec.min() / 10.0, spec.max() * 100.0)
        plt.ylabel('Amplitude')
        plt.xlabel('Frequency [Hz]')
        plt.grid(True, which="both", ls="-", color='grey')
        plt.legend()
        self.mpf.show()

    def plot_spectrum_all(self, all_items):
        import matplotlib.pyplot as plt
        from isp.Gui.Frames import MatplotlibFrame
        fig, ax1 = plt.subplots(figsize=(6, 6))
        self.mpf = MatplotlibFrame(fig)

        for key, seismogram in all_items:
            data = seismogram[2]
            delta = 1 / seismogram[0][6]
            sta = seismogram[0][1]
            [spec, freq, jackknife_errors] = spectrumelement(data, delta, sta)
            info = "{}.{}.{}".format(seismogram[0][0], seismogram[0][1], seismogram[0][3])
            ax1.loglog(freq, spec, linewidth=1.0, alpha = 0.5, label=info)
            ax1.frequencies = freq
            ax1.spectrum = spec
            ax1.set_ylim(spec.min() / 10.0, spec.max() * 100.0)
            # ax1.set_xlim(freq[0], 1/(2*delta))
            plt.ylabel('Amplitude')
            plt.xlabel('Frequency [Hz]')
            plt.grid(True, which="both", ls="-", color='grey')
            plt.legend()
        self.mpf.show()





    def find_nearest(self,array, value):
        idx, val = min(enumerate(array), key=lambda x: abs(x[1] - value))
        return idx, val

    # def __compute_spectrogram(self, tr):
    #      npts = len(tr)
    #      t = np.linspace(0, (tr.stats.delta * npts), npts - self.win)
    #      mt_spectrum = self.MTspectrum(tr.data, self.win, tr.stats.delta, self.tbp, self.ntapers, self.f_min, self.f_max)
    #      log_spectrogram = 10. * np.log(mt_spectrum / np.max(mt_spectrum))
    #      x, y = np.meshgrid(t, np.linspace(self.f_min, self.f_max, log_spectrogram.shape[0]))
    #      return x, y, log_spectrogram

    def MTspectrum_plot(self, data, win, dt, tbp, ntapers, linf, lsup):

        if (win % 2) == 0:
            nfft = win / 2 + 1
        else:
            nfft = (win + 1) / 2

        lim = len(data) - win
        S = np.zeros([int(nfft), int(lim)])
        data2 = np.zeros(2 ** math.ceil(math.log2(win)))

        for n in range(lim):
            data1 = data[n:win + n]
            data1 = data1 - np.mean(data1)
            data2[0:win] = data1
            spec, freq = mtspec(data2, delta=dt, time_bandwidth=tbp, number_of_tapers=ntapers)
            spec = spec[0:int(nfft)]
            S[:, n] = spec

        value1, freq1 = self.find_nearest(freq, linf)
        value2, freq2 = self.find_nearest(freq, lsup)
        S = S[value1:value2]

        return S

    def compute_spectrogram_plot(self, data, win, delta, tbp, ntapers, f_min, f_max, t):

      npts = len(data)
      x = np.linspace(0, (delta * npts), npts - win)
      t = t[0:len(x)]
      mt_spectrum = self.MTspectrum_plot(data, win, delta, tbp, ntapers, f_min, f_max)
      log_spectrogram = 10. * np.log(mt_spectrum / np.max(mt_spectrum))
      x, y = np.meshgrid(t, np.linspace(f_min, f_max, log_spectrogram.shape[0]))
      return x, y, log_spectrogram