Skip to content
Snippets Groups Projects
StreamConverter.py 8.32 KiB
Newer Older
  • Learn to ignore specific revisions
  • """Convert streams from one coordinate system to another.
    
    We use three coordinate systems.
    Geo: Based on Geographic North.  X, Y, Z, F
         X is north, Y is east, Z is down
    Obs: Based on the observatories orientaion. H, E, Z, F, d0
    Mag: Based on Magnetic North. H, D, Z, F
    """
    
    Yash Shah's avatar
    Yash Shah committed
    from __future__ import absolute_import
    
    Yash Shah's avatar
    Yash Shah committed
    from . import ChannelConverter
    
        """Convert a stream to geographic coordinate system.
    
        Parameters
        ----------
        stream : obspy.core.Stream
            stream containing observatory components H, D, Z, and F.
    
        Returns
        -------
        obspy.core.Stream
            new stream object containing geographic components X, Y, Z, and F.
        """
    
        h = mag.select(channel="H")[0]
        d = mag.select(channel="D")[0]
        z = mag.select(channel="Z")
        f = mag.select(channel="F")
    
        mag_h = h.data
        mag_d = d.data
        (geo_x, geo_y) = ChannelConverter.get_geo_from_mag(mag_h, mag_d)
    
        return (
            obspy.core.Stream(
                (__get_trace("X", h.stats, geo_x), __get_trace("Y", d.stats, geo_y))
            )
            + z
            + f
        )
    
    
    
    def get_geo_from_obs(obs):
        """Convert a stream to geographic coordinate system.
    
        Parameters
        ----------
        stream : obspy.core.Stream
            stream containing observatory components H, D or E, Z, and F.
    
        Returns
        -------
        obspy.core.Stream
            new stream object containing geographic components X, Y, Z, and F.
        """
        return get_geo_from_mag(get_mag_from_obs(obs))
    
    
    
    def get_deltaf_from_geo(geo):
        """Get deltaf given geographic coordinate values
    
        Parameters
        ----------
        obs: obspy.core.Stream
            stream containing the observatory components H, D or E, Z, and F.
    
        Returns
        -------
        obspy.core.Stream
            stream object containing delta f values
        """
    
        x = geo.select(channel="X")[0]
        y = geo.select(channel="Y")[0]
        z = geo.select(channel="Z")[0]
        fs = geo.select(channel="F")[0]
    
        fv = ChannelConverter.get_computed_f_using_squares(x, y, z)
        G = ChannelConverter.get_deltaf(fv, fs)
    
        return obspy.core.Stream((__get_trace("G", x.stats, G),))
    
    
    
    def get_deltaf_from_obs(obs):
        """Get deltaf given observatory coordinate values
    
        Parameters
        ----------
        obs: obspy.core.Stream
            stream containing the observatory components H, D or E, Z, and F.
    
        Returns
        -------
        obspy.core.Stream
            stream object containing delta f values
        """
    
        h = obs.select(channel="H")[0]
        z = obs.select(channel="Z")[0]
        fs = obs.select(channel="F")[0]
    
        e = __get_obs_e_from_obs(obs)
        fv = ChannelConverter.get_computed_f_using_squares(h, e, z)
        G = ChannelConverter.get_deltaf(fv, fs)
    
        return obspy.core.Stream((__get_trace("G", h.stats, G),))
    
    Hal Simpson's avatar
    Hal Simpson committed
        """Convert a stream to magnetic coordinate system.
    
        Parameters
        ----------
        geo: obspy.core.Stream
            stream containing observatory components X, Y, Z, and F.
    
        Returns
        -------
        obspy.core.Stream
            new stream object containing magnetic components H, D, Z, and F.
        """
    
        x = geo.select(channel="X")[0]
        y = geo.select(channel="Y")[0]
        z = geo.select(channel="Z")
        f = geo.select(channel="F")
    
        geo_x = x.data
        geo_y = y.data
        (mag_h, mag_d) = ChannelConverter.get_mag_from_geo(geo_x, geo_y)
    
        return (
            obspy.core.Stream(
                (__get_trace("H", x.stats, mag_h), __get_trace("D", y.stats, mag_d))
            )
            + z
            + f
        )
    
    
    
    def get_mag_from_obs(obs):
        """Convert a stream to magnetic coordinate system.
    
        Parameters
        ----------
        obs : obspy.core.Stream
            stream containing observatory components H, D or E, Z, and F.
    
        Returns
        -------
        obspy.core.Stream
            new stream object containing magnetic components H, D, Z, and F.
        """
    
        h = obs.select(channel="H")[0]
    
        z = obs.select(channel="Z")
        f = obs.select(channel="F")
    
        d0 = ChannelConverter.get_radians_from_minutes(
    
            numpy.float64(e.stats.declination_base) / 10
        )
    
        (mag_h, mag_d) = ChannelConverter.get_mag_from_obs(obs_h, obs_e, d0)
    
        return (
            obspy.core.Stream(
                (__get_trace("H", h.stats, mag_h), __get_trace("D", e.stats, mag_d))
            )
            + z
            + f
        )
    
    def get_obs_from_geo(geo, include_d=False):
    
        """Convert a stream to observatory coordinate system.
    
    
        Parameters
        ----------
        stream : obspy.core.Stream
            stream containing geographic components X, Y, Z, and F.
    
        include_d : boolean
            whether to also include the observatory D component.
    
    
        Returns
        -------
        obspy.core.Stream
            new stream object containing observatory components H, D, E, Z, and F.
        """
    
        return get_obs_from_mag(get_mag_from_geo(geo), include_d)
    
    def get_obs_from_mag(mag, include_d=False):
    
        """Convert a stream to magnetic observatory coordinate system.
    
        Parameters
        ----------
        stream: obspy.core.Stream
            stream containing magnetic components H, D, Z, and F.
    
        include_d: boolean
            whether to also include the observatory D component
    
        Returns
        -------
        obspy.core.Stream
            new stream object containing observatory components H, D, E, Z, and F
        """
    
        h = mag.select(channel="H")[0]
        d = mag.select(channel="D")[0]
        z = mag.select(channel="Z")
        f = mag.select(channel="F")
    
        mag_h = h.data
        mag_d = d.data
        d0 = ChannelConverter.get_radians_from_minutes(
    
            numpy.float64(d.stats.declination_base) / 10
        )
    
        (obs_h, obs_e) = ChannelConverter.get_obs_from_mag(mag_h, mag_d, d0)
    
        traces = (__get_trace("H", h.stats, obs_h), __get_trace("E", d.stats, obs_e))
    
        if include_d:
            obs_d = ChannelConverter.get_obs_d_from_obs(obs_h, obs_e)
    
            traces = traces + (__get_trace("D", d.stats, obs_d),)
    
        return obspy.core.Stream(traces) + z + f
    
    
    
    def get_obs_from_obs(obs, include_e=False, include_d=False):
        """Fill in the observatory parameters as requested
    
        Parameters
        ----------
        stream: obspy.core.Stream
    
            stream containing the observatory components H, D or E, Z, and F.
    
        include_e: boolean
            whether to include the e component
        include_d: boolean
            whether to include the d component
    
        Returns
        -------
        obspy.core.Stream
            new stream object containing observatory components H, D, E, Z, and F
        """
    
        h = obs.select(channel="H")[0]
        z = obs.select(channel="Z")
        f = obs.select(channel="F")
        traces = (h,)
    
        if include_d:
            d = __get_obs_d_from_obs(obs)
    
            traces = traces + (d,)
    
            traces = traces + (e,)
    
        return obspy.core.Stream(traces) + z + f
    
    
    
    def __get_trace(channel, stats, data):
        """Utility to create a new trace object.
    
        Parameters
        ----------
        channel : str
            channel name.
        stats : obspy.core.Stats
            channel metadata to clone.
        data : numpy.array
            channel data.
    
        Returns
        -------
        obspy.core.Trace
            trace containing data and metadata.
        """
        stats = obspy.core.Stats(stats)
        stats.channel = channel
        return obspy.core.Trace(data, stats)
    
    
    def __get_obs_d_from_obs(obs):
        """Get trace containing observatory D component.
    
        Returns D if found, otherwise computes D from H, E, D0.
    
        Parameters
        ----------
        obs : obspy.core.Stream
            observatory components (D) or (H, E).
    
        Returns
        -------
        obspy.core.Trace
            observatory component D.
        """
        try:
    
            d = obs.select(channel="D")[0]
    
        except IndexError:
    
            h = obs.select(channel="H")[0]
            e = obs.select(channel="E")[0]
            d = __get_trace(
                "D", e.stats, ChannelConverter.get_obs_d_from_obs(h.data, e.data)
            )
    
        return d
    
    
    def __get_obs_e_from_obs(obs):
        """Get trace containing observatory E component.
    
        Returns E if found, otherwise computes E from H,D.
    
        Parameters
        ----------
        obs : obspy.core.Stream
            observatory components (E) or (H, D).
    
        Returns
        -------
        obspy.core.Trace
            observatory component E.
        """
        try:
    
            e = obs.select(channel="E")[0]
    
        except IndexError:
    
            h = obs.select(channel="H")[0]
            d = obs.select(channel="D")[0]
            e = __get_trace(
                "E", d.stats, ChannelConverter.get_obs_e_from_obs(h.data, d.data)
            )