Exemplo n.º 1
0
def test_scalar_lin(lin, field='tens', cmap=plt.cm.jet): #{{{

    import lineament

    satfile="input/ConvectingEuropa_GlobalDiurnalNSR.ssrun"
    europa = ss.Satellite(open(satfile,'r'))
    NSR = ss.StressCalc([ss.NSR(europa),])

    mp_lons, mp_lats = lin.seg_midpoints()
    seg_lengths = lin.seg_lengths()

    min_lat = 0
    max_lat = np.pi/2.0
    min_lon = 0.0
    max_lon = np.pi

    the_fig = plt.figure(figsize=(10,10))
    map_ax  = the_fig.add_subplot(1,1,1)
    map_ax.set_title("Point by Point scalar stresses field (%s)" % (field,) )
    scalar_basemap = basemap.Basemap(llcrnrlon = np.degrees(min_lon),\
                                     llcrnrlat = np.degrees(min_lat),\
                                     urcrnrlon = np.degrees(max_lon),\
                                     urcrnrlat = np.degrees(max_lat),\
                                     ax = map_ax)

    scalar_points(stresscalc=NSR, lons=np.mod(mp_lons,np.pi), lats=np.mod(mp_lats,np.pi/2.0), symb_sizes=5000*seg_lengths, field=field, cmap=cmap, basemap_ax=scalar_basemap)
    junk = lineament.plotlinmap([lin,], map=scalar_basemap, lat_mirror=True, lon_cyc=np.pi)

    scalar_basemap.drawmeridians(np.degrees(np.linspace(min_lon, max_lon, 7)), labels=[1,0,0,1], linewidth=0.5, color='gray')
    scalar_basemap.drawparallels(np.degrees(np.linspace(min_lat, max_lat, 7)), labels=[1,0,0,1], linewidth=0.5, color='gray')
    scalar_basemap.drawmapboundary()
Exemplo n.º 2
0
def test_scalar_grid(min_lon=0.0, max_lon=np.pi, min_lat=-np.pi/2.0, max_lat=np.pi/2.0,\
                     nlats=181, nlons=181, field='tens', cmap=plt.cm.gray_r): #{{{

    satfile = "input/ConvectingEuropa_GlobalDiurnalNSR.ssrun"
    europa = ss.Satellite(open(satfile, 'r'))
    NSR = ss.StressCalc([
        ss.NSR(europa),
    ])

    the_fig = plt.figure(figsize=(10, 10))
    map_ax = the_fig.add_subplot(1, 1, 1)
    map_ax.set_title("Rasterized scalar stress field (%s)" % (field, ))
    scalar_basemap = basemap.Basemap(llcrnrlon = np.degrees(min_lon),\
                                     llcrnrlat = np.degrees(min_lat),\
                                     urcrnrlon = np.degrees(max_lon),\
                                     urcrnrlat = np.degrees(max_lat),\
                                     ax = map_ax)

    scalar_grid(stresscalc=NSR, nlons=nlons, nlats=nlats, min_lon=min_lon, max_lon=max_lon, min_lat=min_lat, max_lat=max_lat,\
                field=field, cmap=cmap, basemap_ax=scalar_basemap)

    scalar_basemap.drawmeridians(np.degrees(np.linspace(min_lon, max_lon, 7)),
                                 labels=[1, 0, 0, 1],
                                 linewidth=0.5,
                                 color='gray')
    scalar_basemap.drawparallels(np.degrees(np.linspace(min_lat, max_lat, 7)),
                                 labels=[1, 0, 0, 1],
                                 linewidth=0.5,
                                 color='gray')
    scalar_basemap.drawmapboundary()
Exemplo n.º 3
0
def main():

    usage = "usage: %prog [options] satfile gridfile outfile"
    description = __doc__
    op = OptionParser(usage)

    (options, args) = op.parse_args()

    # Do a (very) little error checking on the arguments:
    if len(args) != 3:
        op.error("incorrect number of arguments")

    # The satfile defines the satellite and forcings it is subject to:
    satfile = open(args[0], 'r')
    the_sat = ss.Satellite(satfile)
    satfile.close()

    # The gridfile defines the scope and resolution of the calculation:

    # Note here that we're actually storing information about the satellite in
    # two places: once in the Grid, and once in the StressDef objects that make
    # up the StressCalc object.  This is probably bad - since one could twiddle
    # with the parameters on one place, and not the other, and end up getting
    # apparently bogus output.  Be careful.
    gridfile = open(args[1], 'r')
    the_grid = Grid(gridfile, satellite=the_sat)
    gridfile.close()

    the_stresscalc = ss.StressCalc([ss.NSR(the_sat), ss.Diurnal(the_sat)])
    the_gridcalc = GridCalc(the_grid, the_stresscalc)
    the_gridcalc.write_netcdf(args[2])
Exemplo n.º 4
0
def test_vector_grid(plot_tens=True, plot_comp=True, plot_greater=True, plot_lesser=True, min_lon=0.0, max_lon=np.pi, nlons=13, min_lat=-np.pi/2.0, max_lat=np.pi/2.0, nlats=13, t=0.0): #{{{
    """
    An attempt to exercise the above routines...

    """

    satfile="input/ConvectingEuropa_GlobalDiurnalNSR.ssrun"
    europa = ss.Satellite(open(satfile,'r'))
    NSR = ss.StressCalc([ss.NSR(europa),])

    grid_min_lon = min_lon
    grid_max_lon = max_lon
    grid_min_lat = min_lat
    grid_max_lat = max_lat
    vector_grid_nlons = nlons
    vector_grid_nlats = nlats

    # Lon/Lat locations to plot the principal components:
    vector_grid_lons  = np.linspace(grid_min_lon, grid_max_lon, vector_grid_nlons)
    vector_grid_lats  = np.linspace(grid_min_lat, grid_max_lat, vector_grid_nlats)
    vector_mesh_lons, vector_mesh_lats = np.meshgrid(vector_grid_lons, vector_grid_lats)
                                                     
    vector_mesh_lons = np.ravel(vector_mesh_lons)
    vector_mesh_lats = np.ravel(vector_mesh_lats)

    vector_grid_fig = plt.figure(figsize=(10,10))
    vector_grid_ax  = vector_grid_fig.add_subplot(1,1,1)
    vector_grid_ax.set_title("Regularly gridded vectors")
    vector_grid_basemap = basemap.Basemap(llcrnrlon = np.degrees(grid_min_lon),\
                                          llcrnrlat = np.degrees(grid_min_lat),\
                                          urcrnrlon = np.degrees(grid_max_lon),\
                                          urcrnrlat = np.degrees(grid_max_lat),\
                                          ax = vector_grid_ax)

    vector_points(stresscalc=NSR, lons=vector_mesh_lons, lats=vector_mesh_lats, time_t=t,\
                  plot_greater=plot_greater, plot_lesser=plot_lesser,\
                  plot_comp=plot_comp, plot_tens=plot_tens, basemap_ax=vector_grid_basemap)

    vector_grid_basemap.drawmeridians(np.degrees(vector_grid_lons), labels=[1,0,0,1], linewidth=0.5, color='gray')
    vector_grid_basemap.drawparallels(np.degrees(vector_grid_lats), labels=[1,0,0,1], linewidth=0.5, color='gray')
    vector_grid_basemap.drawmapboundary()
Exemplo n.º 5
0
def lingen_nsr_library(nlats=36): #{{{
    """
    Create a regularaly spaced "grid" of synthetic NSR lineaments, for use in
    visualizing the expected NSR trajectories, and in fast fitting of
    lineaments to the stress field.

    """
    import satstress
    satfile   = "input/ConvectingEuropa_GlobalDiurnalNSR.ssrun"
    europa = satstress.Satellite(open(satfile,'r'))
    NSR = satstress.StressCalc([satstress.NSR(europa),])

    linlist = []
    for lat in linspace(0,pi/2,nlats+2)[1:-1]:
        linlist.append(lingen_nsr(NSR, init_lon=0.0, init_lat=lat, max_length=2*pi, prop_dir='both'))

    # Now mirror and shift that set of regular lineaments to cover the surface entirely:
    linlist += [Lineament(lons=lin.lons, lats=-lin.lats, stresscalc=lin.stresscalc) for lin in linlist]
    linlist += [Lineament(lons=lin.lons+pi, lats=lin.lats, stresscalc=lin.stresscalc) for lin in linlist]

    return linlist
Exemplo n.º 6
0
def test_vector_lin(lin, t=0.0, w_stress=False, w_length=False, scale=5e7, plot_tens=True, plot_comp=False, plot_greater=True, plot_lesser=False): #{{{
    
    import lineament

    satfile="input/ConvectingEuropa_GlobalDiurnalNSR.ssrun"
    europa = ss.Satellite(open(satfile,'r'))
    NSR = ss.StressCalc([ss.NSR(europa),])

    best_b = lin.best_fit()[1]
    mp_lons, mp_lats = lin.seg_midpoints()

    if w_length is True:
        scale_arr = len(mp_lons)*lin.seg_lengths()/lin.length
    else:
        scale_arr = np.ones(np.shape(mp_lons))

    min_lat = 0
    max_lat = np.pi/2.0
    min_lon = 0.0
    max_lon = np.pi

    vector_lin_fig = plt.figure()
    vector_lin_ax  = vector_lin_fig.add_subplot(1,1,1)
    vector_lin_ax.set_title("Vectors at arbitrary locations (e.g. along a feature)")

    vector_lin_basemap = basemap.Basemap(llcrnrlon = np.degrees(min_lon),\
                                         llcrnrlat = np.degrees(min_lat),\
                                         urcrnrlon = np.degrees(max_lon),\
                                         urcrnrlat = np.degrees(max_lat),\
                                         ax = vector_lin_ax)

    junk = lineament.plotlinmap([lin,], map=vector_lin_basemap, lat_mirror=True, lon_cyc=np.pi)
    vector_lin_basemap.drawmeridians(np.degrees(np.linspace(min_lon, max_lon,13)), labels=[1,0,0,1], linewidth=0.5, color='gray')
    vector_lin_basemap.drawparallels(np.degrees(np.linspace(min_lat, max_lat, 7)), labels=[1,0,0,1], linewidth=0.5, color='gray')
    vector_lin_basemap.drawmapboundary()

    vector_points(stresscalc=NSR, lons=np.mod(mp_lons,np.pi), lats=mp_lats, time_t=0.0, lonshift=best_b,\
                  plot_tens=plot_tens, plot_greater=plot_greater, plot_comp=plot_comp, plot_lesser=plot_lesser, basemap_ax=vector_lin_basemap, scale=scale, scale_arr=scale_arr, w_stress=w_stress)
Exemplo n.º 7
0
    def write_netcdf(self, outfile):
        """
        Output a netCDF file containing the results of the calculation
        specified by the GridCalc object.

        Each stress field encapsulated in the GridCalc object will be output
        within the netCDF file as three data fields, one for each of the stress
        tensor components L{Ttt}_NAME, L{Tpt}_NAME, L{Tpp}_NAME, where NAME is
        the name of the L{StressDef} object (e.g. L{Diurnal} or L{NSR}).

        Writing out the calculation results causes the calculation to take
        place.  No mechanism for performing the calculation and retaining it
        in memory for manipulation is currently provided.

        """

        # Create a netCDF file object to stick the calculation results in:
        nc_out = netCDF3.Dataset(outfile, 'w')

        # Set metadata fields of nc_out appropriate to the calculation at hand.

        nc_out.description = "satstress calculation on a regular grid.  All parameter units are SI (meters-kilograms-seconds)"
        nc_out.history = """Created: %s using the satstress python package: http://code.google.com/p/satstress""" % (
            time.ctime(time.time()))
        nc_out.Conventions = __NETCDF_CONVENTIONS__

        ########################################################################
        # Independent (input) parameters for the run:
        ########################################################################
        nc_out.grid_id = self.grid.grid_id
        nc_out.system_id = self.grid.satellite.system_id
        nc_out.planet_mass = self.grid.satellite.planet_mass
        nc_out.orbit_eccentricity = self.grid.satellite.orbit_eccentricity
        nc_out.orbit_semimajor_axis = self.grid.satellite.orbit_semimajor_axis

        nc_out.layer_id_0 = self.grid.satellite.layers[0].layer_id
        nc_out.density_0 = self.grid.satellite.layers[0].density
        nc_out.lame_mu_0 = self.grid.satellite.layers[0].lame_mu
        nc_out.lame_lambda_0 = self.grid.satellite.layers[0].lame_lambda
        nc_out.thickness_0 = self.grid.satellite.layers[0].thickness
        nc_out.viscosity_0 = self.grid.satellite.layers[0].viscosity
        nc_out.tensile_str_0 = self.grid.satellite.layers[0].tensile_str

        nc_out.layer_id_1 = self.grid.satellite.layers[1].layer_id
        nc_out.density_1 = self.grid.satellite.layers[1].density
        nc_out.lame_mu_1 = self.grid.satellite.layers[1].lame_mu
        nc_out.lame_lambda_1 = self.grid.satellite.layers[1].lame_lambda
        nc_out.thickness_1 = self.grid.satellite.layers[1].thickness
        nc_out.viscosity_1 = self.grid.satellite.layers[1].viscosity
        nc_out.tensile_str_1 = self.grid.satellite.layers[1].tensile_str

        nc_out.layer_id_2 = self.grid.satellite.layers[2].layer_id
        nc_out.density_2 = self.grid.satellite.layers[2].density
        nc_out.lame_mu_2 = self.grid.satellite.layers[2].lame_mu
        nc_out.lame_lambda_2 = self.grid.satellite.layers[2].lame_lambda
        nc_out.thickness_2 = self.grid.satellite.layers[2].thickness
        nc_out.viscosity_2 = self.grid.satellite.layers[2].viscosity
        nc_out.tensile_str_2 = self.grid.satellite.layers[2].tensile_str

        nc_out.layer_id_3 = self.grid.satellite.layers[3].layer_id
        nc_out.density_3 = self.grid.satellite.layers[3].density
        nc_out.lame_mu_3 = self.grid.satellite.layers[3].lame_mu
        nc_out.lame_lambda_3 = self.grid.satellite.layers[3].lame_lambda
        nc_out.thickness_3 = self.grid.satellite.layers[3].thickness
        nc_out.viscosity_3 = self.grid.satellite.layers[3].viscosity
        nc_out.tensile_str_3 = self.grid.satellite.layers[3].tensile_str

        ########################################################################
        # A selection of dependent (output) parameters for the run.
        ########################################################################
        nc_out.satellite_radius = self.grid.satellite.radius()
        nc_out.satellite_mass = self.grid.satellite.mass()
        nc_out.satellite_density = self.grid.satellite.density()
        nc_out.satellite_surface_gravity = self.grid.satellite.surface_gravity(
        )
        nc_out.satellite_orbit_period = self.grid.satellite.orbit_period()

        ########################################################################
        # What about Frequency dependent Parameters?
        ########################################################################
        # There are a variety of interesting frequency-dependent parameters
        # that we ought to really output as well (delta, and the complex Love
        # numbers, Lame parameters...) for reference, but they'll all depend on
        # exactly which slice (for instance) in NSR we're looking at, so the
        # right place to put this meta-data isn't really in the global section
        # it should be associated with the stress variables themselves.
        #
        # It seems that the right way to do this is to define several 1-d
        # variables that are not coordinate variables (that is, they don't
        # correspond to one of the dimensions, unlike latitude, or longitude)
        # e.g.:
        # nc_out.createVariable('nsr_delta_upper', self.grid.nsr_period_num, ('nsr_period'))
        # nc_out.createVariable('nsr_lame_mu_twiddle', self.grid.nsr_period_num, ('nsr_period'))

        ########################################################################
        # A few parameters pertaining to the web-interface only:
        ########################################################################
        # TODO
        nc_out.ssweb_run_id = ""
        nc_out.ssweb_username = ""
        nc_out.ssweb_ip_address = ""

        ########################################################################
        # Specify the size and shape of the output datacube.
        ########################################################################

        # LATITUDE:
        nc_out.createDimension('latitude', self.grid.lat_num)
        lats = nc_out.createVariable('latitude', 'f4', ('latitude', ))
        lats.units = "degrees_north"
        lats.long_name = "latitude"
        lats[:] = numpy.linspace(self.grid.lat_min, self.grid.lat_max,
                                 self.grid.lat_num)

        # LONGITUDE:
        nc_out.createDimension('longitude', self.grid.lon_num)
        lons = nc_out.createVariable('longitude', 'f4', ('longitude', ))
        lons.units = "degrees_east"
        lons.long_name = "longitude"
        lons[:] = numpy.linspace(self.grid.lon_min, self.grid.lon_max,
                                 self.grid.lon_num)

        # NSR_PERIOD
        nc_out.createDimension('nsr_period', self.grid.nsr_period_num)
        nsr_periods = nc_out.createVariable('nsr_period', 'f4',
                                            ('nsr_period', ))
        nsr_periods.units = "seconds"
        nsr_periods.long_name = "NSR period"
        nsr_periods[:] = numpy.logspace(numpy.log10(self.grid.nsr_period_min),
                                        numpy.log10(self.grid.nsr_period_max),
                                        self.grid.nsr_period_num)

        # TIME:
        # Check to see what kind of units we're using for time, and name the
        # variables and their units appropriately
        if self.grid.orbit_min is None:
            nc_out.createDimension('time', self.grid.time_num)
            times = nc_out.createVariable('time', 'f4', ('time', ))
            times.units = "seconds"
            times.long_name = "time after periapse"
            times[:] = numpy.linspace(self.grid.time_min, self.grid.time_max,
                                      self.grid.time_num)
        else:
            nc_out.createDimension('time', self.grid.orbit_num)
            times = nc_out.createVariable('time', 'f4', ('time', ))
            times.units = "degrees"
            times.long_name = "degrees after periapse"
            times[:] = numpy.linspace(self.grid.orbit_min, self.grid.orbit_max,
                                      self.grid.orbit_num)

        # At this point, we should have all the netCDF dimensions and their
        # corresponding coordinate variables created (latitutde, longitude,
        # time/orbit, nsr_period), but we still haven't created the data
        # variables, which will ultimately hold the results of our stress
        # calculation, and which depend on the aforedefined dimensions

        # DIURNAL:
        Ttt_Diurnal = nc_out.createVariable('Ttt_Diurnal', 'f4', (
            'time',
            'latitude',
            'longitude',
        ))
        Ttt_Diurnal.units = "Pa"
        Ttt_Diurnal.long_name = "north-south component of Diurnal eccentricity stresses"

        Tpt_Diurnal = nc_out.createVariable('Tpt_Diurnal', 'f4', (
            'time',
            'latitude',
            'longitude',
        ))
        Tpt_Diurnal.units = "Pa"
        Tpt_Diurnal.long_name = "shear component of Diurnal eccentricity stresses"

        Tpp_Diurnal = nc_out.createVariable('Tpp_Diurnal', 'f4', (
            'time',
            'latitude',
            'longitude',
        ))
        Tpp_Diurnal.units = "Pa"
        Tpp_Diurnal.long_name = "east-west component of Diurnal eccentricity stresses"

        # NSR:
        Ttt_NSR = nc_out.createVariable('Ttt_NSR', 'f4', (
            'nsr_period',
            'latitude',
            'longitude',
        ))
        Ttt_NSR.units = "Pa"
        Ttt_NSR.long_name = "north-south component of NSR stresses"

        Tpt_NSR = nc_out.createVariable('Tpt_NSR', 'f4', (
            'nsr_period',
            'latitude',
            'longitude',
        ))
        Tpt_NSR.units = "Pa"
        Tpt_NSR.long_name = "shear component of NSR stresses"

        Tpp_NSR = nc_out.createVariable('Tpp_NSR', 'f4', (
            'nsr_period',
            'latitude',
            'longitude',
        ))
        Tpp_NSR.units = "Pa"
        Tpp_NSR.long_name = "east-west component of NSR stresses"

        # Get the StressDef objects corresponding to Diurnal and NSR stresses:
        for stress in self.stresscalc.stresses:
            if stress.__name__ is 'Diurnal':
                diurnal_stress = ss.StressCalc([
                    stress,
                ])
            if stress.__name__ is 'NSR':
                nsr_stress = ss.StressCalc([
                    stress,
                ])

        # Loop over the time variable, doing diurnal calculations over an orbit
        for t in range(len(times[:])):
            # We need some kind of progress update, and we need to make sure that
            # we have a representation of the time coordinate in seconds, because
            # that's what the satstress library expects - even if we're ultimately
            # communicating time to the user in terms of "degrees after periapse"
            if self.grid.orbit_min is None:
                time_sec = times[t]
            else:
                time_sec = diurnal_stress.stresses[0].satellite.orbit_period(
                ) * (times[t] / 360.0)

            print "Calculating Diurnal stresses at", times[t], times.long_name

            for lon in range(len(lons[:])):
                for lat in range(len(lats[:])):

                    Tau_D = diurnal_stress.tensor(theta = scipy.radians(90.0-lats[lat]),\
                                                    phi = scipy.radians(lons[lon]),\
                                                      t = time_sec )

                    nc_out.variables['Ttt_Diurnal'][t, lat, lon] = Tau_D[0, 0]
                    nc_out.variables['Tpt_Diurnal'][t, lat, lon] = Tau_D[1, 0]
                    nc_out.variables['Tpp_Diurnal'][t, lat, lon] = Tau_D[1, 1]

        # Make sure everything gets written out to the file.
        nc_out.sync()

        # Change the satellite's eccentricity to zero to exclude the Diurnal
        # stresses for the purposes of calculating the NSR stresses:
        nsr_stress.stresses[0].satellite.orbit_eccentricity = 0.0

        # Loop over all the prescribed values of NSR_PERIOD, and do the NSR stress calculation
        # at each point on the surface.
        for p_nsr in range(len(nsr_periods[:])):

            # Adjust the properties of the Satellite and StressDef objects
            # for the nsr_period being considered:
            new_sat = nsr_stress.stresses[0].satellite
            new_sat.nsr_period = nsr_periods[p_nsr]
            nsr_stress = ss.StressCalc([
                ss.NSR(new_sat),
            ])

            print "Calculating NSR stresses for Pnsr = %g %s" % (
                nsr_periods[p_nsr],
                nsr_periods.units,
            )
            for lon in range(len(lons[:])):
                for lat in range(len(lats[:])):
                    Tau_N = nsr_stress.tensor(theta = scipy.radians(90-lats[lat]),\
                                                phi = scipy.radians(lons[lon]),\
                                                  t = 0 )

                    nc_out.variables['Ttt_NSR'][p_nsr, lat, lon] = Tau_N[0, 0]
                    nc_out.variables['Tpt_NSR'][p_nsr, lat, lon] = Tau_N[1, 0]
                    nc_out.variables['Tpp_NSR'][p_nsr, lat, lon] = Tau_N[1, 1]

        # Make sure everything gets written out to the file.
        nc_out.sync()