Ejemplo n.º 1
0
    def _check_input(values_dict):
        """Perform checks on inputs.

        Specifically:

        1. Ensure all components are `TimeSeries` objects.
        2. Ensure all components have equal `dt`.
        3. Ensure all components have same `nsamples`, if not trim.

        Parameters
        ----------
        values_dict : dict
            Key is human-readable component name {'ns', 'ew', 'vt'}.
            Value is corresponding `TimeSeries` object.

        Returns
        -------
        Tuple
            Containing checked components as tuple of the form
            `(ns, ew, vt)`.

        """
        ns = values_dict["ns"]
        try:
            ns = TimeSeries.from_timeseries(ns)
        except AttributeError as e:
            msg = f"'ns' must be a `TimeSeries`, not {type(ns)}."
            raise TypeError(msg) from e
        values_dict["ns"] = ns

        dt = ns.dt
        nsamples = ns.nsamples
        for key, value in values_dict.items():
            if key == "ns":
                continue

            if isinstance(value, TimeSeries):
                values_dict[key] = TimeSeries.from_timeseries(value)
            else:
                msg = f"`{key}`` must be a `TimeSeries`, not {type(value)}."
                raise TypeError(msg)

            if value.dt != dt:
                msg = "All components must have equal `dt`."
                raise ValueError(msg)

            if value.nsamples != nsamples:
                txt = "".join(
                    [f"{_k}={_v.nsamples} " for _k, _v in values_dict.items()])
                msg = f"Components are different length: {txt}"
                raise ValueError(msg)

        return (values_dict["ns"], values_dict["ew"], values_dict["vt"])
Ejemplo n.º 2
0
    def from_dict(cls, dictionary):
        """Create `Sensor3c` object from dictionary representation.

        Parameters
        ---------
        dictionary : dict
            Must contain keys "ns", "ew", and "vt", and may also contain
            the optional key "meta". "ns", "ew", and "vt" must be
            dictionary representations of `TimeSeries` objects, see
            `SigProPy <https://sigpropy.readthedocs.io/en/latest/?badge=latest>`_
            documentation for details.

        Returns
        -------
        Sensor3c
            Instantiated `Sensor3c` object.

        """
        if dictionary.get("meta") is None:
            dictionary["meta"] = None

        comps = []
        for comp in ["ns", "ew", "vt"]:
            comps.append(TimeSeries.from_dict(dictionary[comp]))

        return cls(*comps, dictionary["meta"])
Ejemplo n.º 3
0
    def reload_file(self):
        logging.info("begin - reload_file()")
        # Reset state
        self.applied_filter = False
        self.applied_taper = False
        self.fseries = False

        # Load File and Update Plot to Reflect This
        if self.fname.endswith(".miniseed"):
            traces = obspy.read(self.fname)
            self.tseries = TimeSeries.from_trace(traces[0])
        else:
            df = pd.read_csv(self.fname, names=["time", "amp"])
            self.tseries = TimeSeries(df.amp.to_numpy(),
                                      df.time[1] - df.time[0])

        self.update_tseries_plot()
        self.update_fseries_plot()
Ejemplo n.º 4
0
    def from_mseed(cls, fname):
        """Initialize a 3-component sensor (Sensor3c) object from a
        .miniseed file.

        Parameters
        ----------
        fname : str
            Name of miniseed file, full path may be used if desired.
            The file should contain three traces with the
            appropriate channel names. Refer to the `SEED` Manual
            `here <https://www.fdsn.org/seed_manual/SEEDManual_V2.4.pdf>`_.
            for specifics.

        Returns
        -------
        Sensor3c
            Initialized 3-component sensor object.

        """
        traces = obspy.read(fname)

        if len(traces) != 3:
            msg = f"miniseed file {fname} has {len(traces)} traces, but should have 3."
            raise ValueError(msg)

        found_ew, found_ns, found_vt = False, False, False
        for trace in traces:
            if trace.meta.channel.endswith("E") and not found_ew:
                ew = TimeSeries.from_trace(trace)
                found_ew = True
            elif trace.meta.channel.endswith("N") and not found_ns:
                ns = TimeSeries.from_trace(trace)
                found_ns = True
            elif trace.meta.channel.endswith("Z") and not found_vt:
                vt = TimeSeries.from_trace(trace)
                found_vt = True
            else:
                msg = f"Missing, duplicate, or incorrectly named components. See documentation."
                raise ValueError(msg)

        meta = {"File Name": fname}
        return cls(ns, ew, vt, meta)
Ejemplo n.º 5
0
    def _combine_horizontal_td(self, method, horizontals, azimuth):
        az_rad = math.radians(azimuth)
        ns = horizontals["ns"]
        ew = horizontals["ew"]

        if method in ["azimuth", "single-azimuth"]:
            horizontal = ns.amp*math.cos(az_rad) + ew.amp*math.sin(az_rad)
        else:
            msg = f"method={method} has not been implemented."
            raise NotImplementedError(msg)

        if isinstance(ns, WindowedTimeSeries):
            return WindowedTimeSeries(horizontal, ns.dt)
        elif isinstance(ns, TimeSeries):
            return TimeSeries(horizontal, ns.dt)
        else:
            raise NotImplementedError
Ejemplo n.º 6
0
    def _combine_horizontal_td(self, method, azimuth):
        """Combine horizontal components in the time domain.

        azimuth : float, optional
            Azimuth (clockwise positive) from North (i.e., 0 degrees).

        Returns
        -------
        TimeSeries
            Representing the combined horizontal components.

        """
        az_rad = math.radians(azimuth)

        if method in ["azimuth", "single-azimuth"]:
            horizontal = self.ns._amp * \
                math.cos(az_rad) + self.ew._amp*math.sin(az_rad)
        else:
            msg = f"method={method} has not been implemented."
            raise NotImplementedError(msg)

        return TimeSeries(horizontal, self.ns.dt)
Ejemplo n.º 7
0
    def from_saf(cls, fname):
        """Create `Sensor3c` object from a SAF ASCII file.

        Parameters
        ---------
        fname : str
            Name of the SESAME ASCII (SAF) file.

        Returns
        -------
        Sensor3c
            Instantiated `Sensor3c` object.

        """

        meta = {}
        meta["File Name"] = fname
        # This is the default value if a project name is not provided.
        meta["project_name"] = PROJECT_NAME
        meta["evt_x"] = EVT_X
        meta["evt_y"] = EVT_Y
        meta["evt_z"] = EVT_Z        

        with open(fname) as fsaf:
            # Look for some parameters in the header and
            # for the line where data start.
            for num, line in enumerate(fsaf, 1):
                spl = line.split(sep=SAF_SEP)
                # Remove all white spaces
                spl = [s.replace(" ", "") for s in spl]
                if "####----" in line:
                    # Data should start from here
                    data_start = num
                    break
                if spl:
                    # List is not empty
#                    print(spl)
                    if spl[0] == "SAMP_FREQ":
                        # Collect the sampling frequency
                        # CHECK HERE IF THE SAMPLING FREQUENCY IS OK!
                        samp_freq = float(spl[1])
                    elif spl[0] == "PROJECT_NAME":
                        try:
                            # Collect the name of the project
                            project_name = spl[1]
                        except IndexError:
                            # No name provided for the project
                            project_name = "None"
                        meta["project_name"] = project_name
                    elif spl[0] == "START_TIME":
 #                       print(spl[1])
                        YYYY = int(spl[1][:4])
                        MM = int(spl[1][4:6])
                        DD = int(spl[1][6:8])
                        hh = int(spl[1][8:10])
                        mm = int(spl[1][10:12])
                        ss = int(spl[1][12:14])
  #                      print(YYYY, MM, DD)
                        starttime = obspy.UTCDateTime(YYYY, MM, DD, hh, mm, ss)
                        meta["starttime"] = (spl[1][:4]+"/"+spl[1][4:6]+"/"+spl[1][6:8]+" "
                                             +spl[1][8:10]+":"+spl[1][10:12]+":"+spl[1][12:14])
                    elif spl[0] == "EVT_X":
                        meta["evt_x"] = float(spl[1])
                    elif spl[0] == "EVT_Y":
                        meta["evt_y"] = float(spl[1])
                    elif spl[0] == "EVT_Z":
                        meta["evt_z"] = float(spl[1])
                        
                                                      

                        
        # Read the dataset unsing pandas 
        data = pd.read_csv(fname, sep=r"\s+", skiprows=data_start, header=None, float_precision="round_trip")
        data.rename(columns={0: "vt",1: "ns", 2:"ew"}, inplace=True)

        trace_ew = obspy.Trace()
        trace_ew.data = data["ew"].to_numpy()
        trace_ew.stats.sampling_rate = samp_freq
        trace_ew.stats.starttime = starttime        
        
        ew = TimeSeries.from_trace(trace_ew)
        
        trace_ns = obspy.Trace()
        trace_ns.data = data["ns"].to_numpy()
        trace_ns.stats.sampling_rate = samp_freq
        trace_ns.stats.starttime = starttime                
        ns = TimeSeries.from_trace(trace_ns)
        
        trace_vt = obspy.Trace()
        trace_vt.data = data["vt"].to_numpy()
        trace_vt.stats.sampling_rate = samp_freq
        trace_vt.stats.starttime = starttime                        
        vt = TimeSeries.from_trace(trace_vt)


        
        return cls(ns, ew, vt, meta)    
Ejemplo n.º 8
0
    def from_mseed(cls, fname=None, fnames_1c=None):
        """Create 3-component sensor (Sensor3c) object from .mseed file.

        Parameters
        ----------
        fname : str, optional
            Name of miniseed file, full path may be used if desired.
            The file should contain three traces with the
            appropriate channel names. Refer to the `SEED` Manual
            `here <https://www.fdsn.org/seed_manual/SEEDManual_V2.4.pdf>`_.
            for specifics, default is `None`.
        fnames_1c : dict, optional
            Some data acquisition systems supply three separate miniSEED
            files rather than a single combined file. To use those types
            of files, simply specify the three files in a `dict` of
            the form `{'e':'east.mseed', 'n':'north.mseed',
            'z':'vertical.mseed'}`, default is `None`.

        Returns
        -------
        Sensor3c
            Initialized 3-component sensor object.

        Raises
        ------
        ValueError
            If both `fname` and `fname_verbose` are `None`.

        """
        if fnames_1c is None and fname is None:
            msg = "`fnames_1c` and `fname` cannot both be `None`."
            raise ValueError(msg)
        if fnames_1c is not None:
            trace_list = []
            for key in ["e", "n", "z"]:
                stream = obspy.read(fnames_1c[key], format="MSEED")
                if len(stream) > 1:
                    msg = f"File {fnames_1c[key]} contained {len(stream)}"
                    msg += "traces, rather than 1 as was expected."
                    raise IndexError(msg)
                trace = stream[0]
                if trace.meta.channel[-1] != key.capitalize():
                    msg = "Component indicated in the header of "
                    msg += f"{fnames_1c[key]} is {trace.meta.channel[-1]} "
                    msg += f"which does not match the key {key} specified. "
                    msg += "Ignore this warning only if you know "
                    msg += "your digitizer's header is incorrect."
                    warnings.warn(msg)
                    trace.meta.channel = trace.meta.channel[:-1] + \
                        key.capitalize()
                trace_list.append(trace)
            traces = obspy.Stream(trace_list)
        else:
            traces = obspy.read(fname, format="MSEED")

        if len(traces) != 3:
            msg = f"miniseed file {fname} has {len(traces)} traces, but should have 3."
            raise ValueError(msg)

        found_ew, found_ns, found_vt = False, False, False
        for trace in traces:
            if trace.meta.channel.endswith("E") and not found_ew:
                ew = TimeSeries.from_trace(trace)
                found_ew = True
            elif trace.meta.channel.endswith("N") and not found_ns:
                ns = TimeSeries.from_trace(trace)
                found_ns = True
            elif trace.meta.channel.endswith("Z") and not found_vt:
                vt = TimeSeries.from_trace(trace)
                found_vt = True
            else:
                msg = "Missing, duplicate, or incorrectly named components. See documentation."
                raise ValueError(msg)

        meta = {"File Name": fname}
        return cls(ns, ew, vt, meta)