Ejemplo n.º 1
0
def _main():
    """This _main is a faux unit-test of cotr

    It makes 3d plots using both Viscid and Mayavi
    """
    plot_mpl = True
    plot_mvi = True
    crd_system = 'gse'

    dtfmt = "%Y-%m-%d %H:%M"

    t = "2010-06-23T00:00:00.0"
    print("Dipole Moment at {0},".format(format_datetime(t, dtfmt)))
    print("    - mhd:", get_dipole_moment(t, crd_system='gse', strength=1.0))
    print("    - gse:", get_dipole_moment(t, crd_system='mhd', strength=1.0))

    if plot_mpl:
        from matplotlib import pyplot as plt
        import matplotlib.dates as mdates
        try:
            from viscid.plot import mpl
        except ImportError:
            pass

        times = linspace_datetime64("2010-01-01T00:00:00.0",
                                    "2010-06-21T00:00:00.0", n=(365//2*24))
        # times = linspace_datetime64("1952-01-01T00:00:00.0",
        #                             "1956-01-01T00:00:00.0", n=(4*365*24*2))

        t_dt = as_datetime(times).tolist()
        m_gse = np.empty((len(times), 3), dtype='f8')
        m_sm = np.empty((len(times), 3), dtype='f8')
        psi = np.empty((len(times), ), dtype='f8')
        mu = np.empty((len(times), ), dtype='f8')
        message_cadence = len(times) // 20
        for i, t in enumerate(times):
            if i % message_cadence == 0:
                print("Getting moment for: {0} {1} ({2:.0f}% complete)"
                      "".format(i, t, 100 * i / len(times)))
            c = Cotr(t)
            m_gse[i, :] = c.get_dipole_moment(crd_system='gse', strength=1)
            m_sm[i, :] = c.get_dipole_moment(crd_system='sm', strength=1)
            mu[i], psi[i] = c.get_dipole_angles()
        dip_angle = np.rad2deg(np.arccos(np.sum(m_gse * m_sm, axis=1)))

        i_smallest_diptilt = np.argmin(np.abs(mu))
        i_largest_diptilt = np.argmax(np.abs(mu))
        i_smallest_dipangle = np.argmin(np.abs(dip_angle))
        i_largest_dipangle = np.argmax(np.abs(dip_angle))

        print()
        print("Dipole info between {0} and {1},"
              "".format(format_datetime(times[0], dtfmt),
                        format_datetime(times[-1], dtfmt)))
        print("    - Smallest dipole tilt angle: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_smallest_diptilt], dtfmt),
                        mu[i_smallest_diptilt]))
        print("    - Largest dipole tilt angle: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_largest_diptilt], dtfmt),
                        mu[i_largest_diptilt]))
        print("    - Smallest angle between dip and GSE-Z: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_smallest_dipangle], dtfmt),
                        dip_angle[i_smallest_dipangle]))
        print("    - Largest angle between dip and GSE-Z: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_largest_dipangle], dtfmt),
                        dip_angle[i_largest_dipangle]))

        plt.clf()
        ax0 = plt.subplot(211)
        plt.plot(t_dt, psi, label='GSM Angle')
        plt.plot(t_dt, mu, label='DIP Tilt Angle')
        plt.gca().get_xaxis().set_visible(False)
        plt.legend(loc=0)
        plt.subplot(212, sharex=ax0)
        plt.plot(t_dt, dip_angle, label='Angle between dip and GSE-Z')
        # plt.ylim(11.62, 11.73)  # to see knee on 1954-12-14 @ 17:05
        dateFmt = mdates.DateFormatter(dtfmt)
        plt.gca().xaxis.set_major_formatter(dateFmt)
        plt.gcf().autofmt_xdate()
        plt.legend(loc=0)
        plt.subplots_adjust(left=0.15, right=0.98, top=0.97)
        plt.show()

        # m = m_gse
        # plt.clf()
        # plt.subplot(311)
        # plt.plot(times, m[:, 0], label='M$_{0}$')
        # plt.subplot(312)
        # plt.plot(times, m[:, 1], label='M$_{1}$')
        # plt.subplot(313)
        # plt.plot(times, m[:, 2], label='M$_{2}$')
        # plt.show()

    if plot_mvi:
        import os
        import viscid
        from viscid.plot import mvi

        mvi.figure(size=(768, 768), fgcolor=(0, 0, 0), bgcolor=(1, 1, 1),
                   offscreen=True)

        def _plot_time_range(times, figname):
            for i, t in enumerate(times):
                mvi.clf()
                cotr = Cotr(t)

                mvi.plot_blue_marble(r=1.0, rotate=t, crd_system=crd_system,
                                     nphi=256, ntheta=128, res=4, lines=True)

                mvi.plot_earth_3d(radius=1.005, crd_system=crd_system,
                                  night_only=True, opacity=0.5)

                mag_north = cotr.transform('sm', crd_system, [0, 0, 1.0])

                mvi.mlab.points3d(*mag_north, scale_factor=0.05, mode='sphere',
                                  color=(0.992, 0.455, 0.0), resolution=32)
                mvi.orientation_axes(line_width=4.0)

                mvi.mlab.text(0.325, 0.95, viscid.format_datetime(t))

                mvi.view(azimuth=0.0, elevation=90.0, distance=5.0,
                         focalpoint=[0, 0, 0])
                mvi.savefig("{0}_eq_{1:06d}.png".format(figname, i))
                mvi.view(azimuth=0.0, elevation=0.0, distance=5.0,
                         focalpoint=[0, 0, 0])
                mvi.savefig("{0}_pole_{1:06d}.png".format(figname, i))

        path = os.path.expanduser("~/Desktop/day/{0}/".format(crd_system))
        if not os.path.exists(path):
            os.makedirs(path)
        print()
        print("Writing 3D images in:", path)

        # summer solstice (earth-sun line @ tropic of cancer)
        print()
        print("Making a movie for the June solstice")
        solstice_times = linspace_datetime64("2010-06-21T00:00:00.0",
                                             "2010-06-22T00:00:00.0", n=49)
        _plot_time_range(solstice_times, path + "solstice")
        pfx = path + "solstice_eq"
        viscid.vutil.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)
        pfx = path + "solstice_pole"
        viscid.vutil.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)

        # autumnal equinox (earth-sun line @ equator)
        print()
        print("Making a movie for the September equinox")
        equinox_times = linspace_datetime64("2010-09-23T00:00:00.0",
                                            "2010-09-24T00:00:00.0", n=49)
        _plot_time_range(equinox_times, path + "equinox")
        pfx = path + "equinox_eq"
        viscid.vutil.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)
        pfx = path + "equinox_pole"
        viscid.vutil.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)

        # Watching the magnetic pole move year-by-year
        print()
        print("Making a movie to show magnetic pole motion")
        years = range(1950, 2016, 1)
        times = [as_datetime64("{0:04d}-06-21".format(y)) for y in years]
        _plot_time_range(times, path + "year")
        pfx = path + "year_eq"
        viscid.vutil.make_animation(pfx + '.mp4', pfx, yes=1, framerate=8)
        pfx = path + "year_pole"
        viscid.vutil.make_animation(pfx + '.mp4', pfx, yes=1, framerate=8)
Ejemplo n.º 2
0
def _main():
    """This _main is a faux unit-test of cotr

    It makes 3d plots using both Viscid and Mayavi
    """
    plot_mpl = True
    plot_vlab = True
    crd_system = 'gse'

    dtfmt = "%Y-%m-%d %H:%M"

    t = "2010-06-23T00:00:00.0"
    print("Dipole Moment at {0},".format(format_datetime(t, dtfmt)))
    print("    - mhd:", get_dipole_moment(t, crd_system='gse', strength=1.0))
    print("    - gse:", get_dipole_moment(t, crd_system='mhd', strength=1.0))

    if plot_mpl:
        from matplotlib import pyplot as plt
        import matplotlib.dates as mdates
        try:
            from viscid.plot import vpyplot as vlt
        except ImportError:
            pass

        times = linspace_datetime64("2010-01-01T00:00:00.0",
                                    "2010-06-21T00:00:00.0",
                                    n=(365 // 2 * 24))
        # times = linspace_datetime64("1952-01-01T00:00:00.0",
        #                             "1956-01-01T00:00:00.0", n=(4*365*24*2))

        t_dt = as_datetime(times).tolist()
        m_gse = np.empty((len(times), 3), dtype='f8')
        m_sm = np.empty((len(times), 3), dtype='f8')
        psi = np.empty((len(times), ), dtype='f8')
        mu = np.empty((len(times), ), dtype='f8')
        message_cadence = len(times) // 20
        for i, t in enumerate(times):
            if i % message_cadence == 0:
                print("Getting moment for: {0} {1} ({2:.0f}% complete)"
                      "".format(i, t, 100 * i / len(times)))
            c = Cotr(t)
            m_gse[i, :] = c.get_dipole_moment(crd_system='gse', strength=1)
            m_sm[i, :] = c.get_dipole_moment(crd_system='sm', strength=1)
            mu[i], psi[i] = c.get_dipole_angles()
        dip_angle = np.rad2deg(np.arccos(np.sum(m_gse * m_sm, axis=1)))

        i_smallest_diptilt = np.argmin(np.abs(mu))
        i_largest_diptilt = np.argmax(np.abs(mu))
        i_smallest_dipangle = np.argmin(np.abs(dip_angle))
        i_largest_dipangle = np.argmax(np.abs(dip_angle))

        print()
        print("Dipole info between {0} and {1},"
              "".format(format_datetime(times[0], dtfmt),
                        format_datetime(times[-1], dtfmt)))
        print("    - Smallest dipole tilt angle: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_smallest_diptilt], dtfmt),
                        mu[i_smallest_diptilt]))
        print("    - Largest dipole tilt angle: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_largest_diptilt], dtfmt),
                        mu[i_largest_diptilt]))
        print("    - Smallest angle between dip and GSE-Z: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_smallest_dipangle], dtfmt),
                        dip_angle[i_smallest_dipangle]))
        print("    - Largest angle between dip and GSE-Z: {1:.03g} deg @ {0}"
              "".format(format_datetime(times[i_largest_dipangle], dtfmt),
                        dip_angle[i_largest_dipangle]))

        plt.clf()
        ax0 = plt.subplot(211)
        plt.plot(t_dt, psi, label='GSM Angle')
        plt.plot(t_dt, mu, label='DIP Tilt Angle')
        plt.gca().get_xaxis().set_visible(False)
        plt.legend(loc=0)
        plt.subplot(212, sharex=ax0)
        plt.plot(t_dt, dip_angle, label='Angle between dip and GSE-Z')
        # plt.ylim(11.62, 11.73)  # to see knee on 1954-12-14 @ 17:05
        dateFmt = mdates.DateFormatter(dtfmt)
        plt.gca().xaxis.set_major_formatter(dateFmt)
        plt.gcf().autofmt_xdate()
        plt.legend(loc=0)
        plt.subplots_adjust(left=0.15, right=0.98, top=0.97)
        plt.show()

        # m = m_gse
        # plt.clf()
        # plt.subplot(311)
        # plt.plot(times, m[:, 0], label='M$_{0}$')
        # plt.subplot(312)
        # plt.plot(times, m[:, 1], label='M$_{1}$')
        # plt.subplot(313)
        # plt.plot(times, m[:, 2], label='M$_{2}$')
        # plt.show()

    if plot_vlab:
        import os
        import viscid
        from viscid.plot import vlab

        vlab.figure(size=(768, 768),
                    fgcolor=(0, 0, 0),
                    bgcolor=(1, 1, 1),
                    offscreen=True)

        def _plot_time_range(times, figname):
            for i, t in enumerate(times):
                vlab.clf()
                cotr = Cotr(t)

                vlab.plot_blue_marble(r=1.0,
                                      rotate=t,
                                      crd_system=crd_system,
                                      nphi=256,
                                      ntheta=128,
                                      res=4,
                                      lines=True)

                vlab.plot_earth_3d(radius=1.005,
                                   crd_system=crd_system,
                                   night_only=True,
                                   opacity=0.5)

                mag_north = cotr.transform('sm', crd_system, [0, 0, 1.0])

                vlab.mlab.points3d(*mag_north,
                                   scale_factor=0.05,
                                   mode='sphere',
                                   color=(0.992, 0.455, 0.0),
                                   resolution=32)
                vlab.orientation_axes(line_width=4.0)

                vlab.mlab.text(0.325, 0.95, viscid.format_datetime(t))

                vlab.view(azimuth=0.0,
                          elevation=90.0,
                          distance=5.0,
                          focalpoint=[0, 0, 0])
                vlab.savefig("{0}_eq_{1:06d}.png".format(figname, i))
                vlab.view(azimuth=0.0,
                          elevation=0.0,
                          distance=5.0,
                          focalpoint=[0, 0, 0])
                vlab.savefig("{0}_pole_{1:06d}.png".format(figname, i))

        path = os.path.expanduser("~/Desktop/day/{0}/".format(crd_system))
        if not os.path.exists(path):
            os.makedirs(path)
        print()
        print("Writing 3D images in:", path)

        # summer solstice (earth-sun line @ tropic of cancer)
        print()
        print("Making a movie for the June solstice")
        solstice_times = linspace_datetime64("2010-06-21T00:00:00.0",
                                             "2010-06-22T00:00:00.0",
                                             n=49)
        _plot_time_range(solstice_times, path + "solstice")
        pfx = path + "solstice_eq"
        viscid.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)
        pfx = path + "solstice_pole"
        viscid.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)

        # autumnal equinox (earth-sun line @ equator)
        print()
        print("Making a movie for the September equinox")
        equinox_times = linspace_datetime64("2010-09-23T00:00:00.0",
                                            "2010-09-24T00:00:00.0",
                                            n=49)
        _plot_time_range(equinox_times, path + "equinox")
        pfx = path + "equinox_eq"
        viscid.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)
        pfx = path + "equinox_pole"
        viscid.make_animation(pfx + '.mp4', pfx, framerate=23.976, yes=1)

        # Watching the magnetic pole move year-by-year
        print()
        print("Making a movie to show magnetic pole motion")
        years = range(1950, 2016, 1)
        times = [as_datetime64("{0:04d}-06-21".format(y)) for y in years]
        _plot_time_range(times, path + "year")
        pfx = path + "year_eq"
        viscid.make_animation(pfx + '.mp4', pfx, yes=1, framerate=8)
        pfx = path + "year_pole"
        viscid.make_animation(pfx + '.mp4', pfx, yes=1, framerate=8)
Ejemplo n.º 3
0
    def __init__(self, time='1967-01-01', dip_tilt=None, dip_gsm=None, rdim=3,
                 notilt1967=True):
        """Construct Cotr instance

        Args:
            time (datetime-like): A specific date and time for the
                transformations (sets earth's geographic and dipole
                orientations)
            rdim (int): Dimensionality of rotation matrices
            dip_tilt (float): if given, override the dipole tilt angle
                (mu in degrees, positive points north pole sunward)
            dip_gsm (float): if given, override the dipole gse->gsm
                angle (psi in degrees, positive points north pole
                duskward)
            notilt1967 (bool): if True, then all transforms (except
                <->mhd transforms) are set to the identity. This is
                the special OpenGGCM no-dipole-tilt-time.
        """
        self._emat_cache = dict()
        self._xform_cache = dict()

        # exact UT time of interest
        time = as_datetime64(time)
        self.time = time

        # dimension of rotation matrices (3 or 4), use 4 to support
        # translations
        self.rdim = rdim

        # modified julian date is days from 00:00UT on 17 Nov 1858
        mjd0 = as_datetime64('1858-11-17T00:00:00.0')
        mjd_td = as_timedelta(time.astype(mjd0.dtype) - mjd0)
        self.mjd = mjd_td.total_seconds() // (24 * 3600)

        # ut is hours from midnight
        dt = as_datetime(time)
        day = as_datetime64("{0:04d}-{1:02d}-{2:02d}"
                            "".format(dt.year, dt.month, dt.day))
        secs = as_timedelta(time - day.astype(time.dtype)).total_seconds()
        self.ut = secs / 3600.0

        # julian centuries (36525 days) since 1 Jan 2000 (epoch 2000)
        self.t0 = (self.mjd - 51544.5) / 36525.0

        # interpolated IGRF
        g10, g11, h11 = _igrf_interpolate(self.time, notilt1967=notilt1967)
        self.g10 = g10
        self.g11 = g11
        self.h11 = h11

        self._disable_mag_crds = dip_tilt is not None or dip_gsm is not None
        years = datetime64_as_years(time)
        notilt = notilt1967 and np.abs(years - 1967.0) < 0.0006

        if self._disable_mag_crds or notilt:
            dip_tilt = 0.0 if dip_tilt is None else dip_tilt
            dip_gsm = 0.0 if dip_gsm is None else dip_gsm

        self._cached_sun_ecliptic_longitude = None
        self._cached_q_g = None
        self._cached_q_e = None
        self._cached_dip_geolon_rad = None
        self._cached_dip_geolat_rad = None
        self._cached_dip_tilt = dip_tilt
        self._cached_dip_gsm = dip_gsm

        # hack the cache to set all geocentric transforms to the identity
        # except GSE -> MHD
        if notilt:
            eye = np.eye(self.rdim)
            # matrices 3, 4, and 6 are missing so that gse, gsm, sm, mhd
            # transformations still do something (from dip_tilt and dip_gsm)
            for i in (1, 2, 5):
                self._emat_cache[-i] = eye
                self._emat_cache[i] = eye
Ejemplo n.º 4
0
    def __init__(self,
                 time='1967-01-01',
                 dip_tilt=None,
                 dip_gsm=None,
                 rdim=3,
                 notilt1967=True):
        """Construct Cotr instance

        Args:
            time (datetime-like): A specific date and time for the
                transformations (sets earth's geographic and dipole
                orientations)
            rdim (int): Dimensionality of rotation matrices
            dip_tilt (float): if given, override the dipole tilt angle
                (mu in degrees, positive points north pole sunward)
            dip_gsm (float): if given, override the dipole gse->gsm
                angle (psi in degrees, positive points north pole
                duskward)
            notilt1967 (bool): if True, then all transforms (except
                <->mhd transforms) are set to the identity if time is
                Jan 1 1967. This is the special OpenGGCM
                no-dipole-tilt-time.
        """
        self._emat_cache = dict()
        self._xform_cache = dict()

        # exact UT time of interest
        time = as_datetime64(time)
        self.time = time

        # dimension of rotation matrices (3 or 4), use 4 to support
        # translations
        self.rdim = rdim

        # modified julian date is days from 00:00UT on 17 Nov 1858
        mjd0 = as_datetime64('1858-11-17T00:00:00.0')
        mjd_td = as_timedelta(time.astype(mjd0.dtype) - mjd0)
        self.mjd = mjd_td.total_seconds() // (24 * 3600)

        # ut is hours from midnight
        dt = as_datetime(time)
        day = as_datetime64("{0:04d}-{1:02d}-{2:02d}"
                            "".format(dt.year, dt.month, dt.day))
        secs = as_timedelta(time - day.astype(time.dtype)).total_seconds()
        self.ut = secs / 3600.0

        # julian centuries (36525 days) since 1 Jan 2000 (epoch 2000)
        self.t0 = (self.mjd - 51544.5) / 36525.0

        # interpolated IGRF
        g10, g11, h11 = _igrf_interpolate(self.time, notilt1967=notilt1967)
        self.g10 = g10
        self.g11 = g11
        self.h11 = h11

        self._disable_mag_crds = dip_tilt is not None or dip_gsm is not None
        years = datetime64_as_years(time)
        notilt = notilt1967 and np.abs(years - 1967.0) < 0.0006

        # do i really want the self._disable_mag_crds part of this? what
        # if i want dip_gsm set by the time, and dip_tilt set by hand...
        # would anyone ever want that? is it really more natural to say that
        # if you specify dip_tilt or dip_gsm then both ignore the time?
        if self._disable_mag_crds or notilt:
            dip_tilt = 0.0 if dip_tilt is None else dip_tilt
            dip_gsm = 0.0 if dip_gsm is None else dip_gsm

        self._cached_sun_ecliptic_longitude = None
        self._cached_q_g = None
        self._cached_q_e = None
        self._cached_dip_geolon_rad = None
        self._cached_dip_geolat_rad = None
        self._cached_dip_tilt = dip_tilt
        self._cached_dip_gsm = dip_gsm

        # hack the cache to set all geocentric transforms to the identity
        # except GSE -> MHD
        if notilt:
            eye = np.eye(self.rdim)
            # matrices 3, 4, and 6 are missing so that gse, gsm, sm, mhd
            # transformations still do something (from dip_tilt and dip_gsm)
            for i in (1, 2, 5):
                self._emat_cache[-i] = eye
                self._emat_cache[i] = eye