예제 #1
0
    def __init__(self, fname):
        """
        Initialize the Simulation instance.
        
        args: 
          
          fname - name of the .csv file that data
                  will be read from. The full path
                  does not need to be added.
                  
        example:
        
          sim = Simulation('HEO95W.csv')
        """

        setattr(self, 'fname', fname)
        setattr(self, 'elapsed', [])

        # use the csv package to read in the data
        fpath = os.path.join(Simulation.ddir, fname)
        with open(fpath, 'r') as f:
            data = csv.reader(f)

            for line, vals in enumerate(data):

                if line == 0:

                    # assign an empty list to each attribute
                    for p in Simulation.params:
                        setattr(self, p, [])
                else:
                    for k, param in enumerate(Simulation.params):

                        if k == 0:

                            # parse the time string provided by
                            # GMAT into a datetime object

                            t = time_utils.dt_from_GMAT(vals[k])
                            getattr(self, param).append(t)

                        else:

                            # all non-time fields should be floating
                            # point values

                            getattr(self, param).append(float(vals[k]))

        # create a list of time_util.Time instances, which
        # associate a datetime object with an elapsed time in seconds.
        # it becomes very useful to have these two values saved together

        self.times = [time_utils.Time(t, self.utc[0]) for t in self.utc]
예제 #2
0
def genetic_lattice(dtime, plot=False, **kwargs):
    ref_time = datetime(2015, 1, 1)
    time = time_utils.Time(dtime, ref_time)
    # mask of lat between 0->90 and lon -180->180
    mask_obj = genetic_helpers.clear_mask(time, plot=plot)
    # polygons describing said mask
    speed = False
    if speed:
        mask_polys = genetic_algorithm.get_mask_points(mask_obj)
    else:
        mask_polys = genetic_algorithm.get_mask_polys(mask_obj)
    # lattice of FOVs generated using that mask and genetic algorithm
    lattice = genetic_helpers.generate_fovs(mask_obj,
                                            mask_polys=mask_polys,
                                            **kwargs)
    genetic_helpers.plot_individual(lattice, mask_obj, "final", save=False)
예제 #3
0
def subtraction_lattice(dtime, plot=False):
    ref_time = datetime(2015, 1, 1)
    time = time_utils.Time(dtime, ref_time)
    # mask of lat between 0->90 and lon -180->180
    mask_obj = genetic_helpers.clear_mask(time)
    # coords = mask_obj.coords
    # clear = mask_obj.mask
    # num_ones = len(np.where(clear == 1)[0].flatten())
    # polygons describing said mask
    mask_polys = genetic_algorithm.get_mask_polys(mask_obj)
    # get one point chosen by taking 100 random samples and evaluating each
    best_observations = []
    best_obs_poly = Polygon([(0, 0), (0, 0), (0, 0), (0, 0)])
    members_per_pop = 100
    for fov_num in range(120):
        print("loop", fov_num)
        mask_polys = remove(best_obs_poly, mask_polys)
        best_obs_pop = genetic_helpers.generate_fovs(
            mask_obj,
            mask_polys=mask_polys,
            generations=1,
            members_per_pop=members_per_pop,  # num_ones,
            fovs_per_member=1,
            num_parents_mating=0,
            hpixels=64,
            vpixels=64)
        best_obs_poly = best_obs_pop[0]
        best_observations.append(best_obs_poly)
        # genetics.plot_individual(
        #     best_obs_pop, mask_obj, fov_num, save=False,
        #     mask_polys=mask_polys)

        # print(best_obs_poly)
    best_observations = np.array(best_observations)
    # for obs in best_observations:
    #     print(obs)
    genetic_helpers.plot_individual(best_observations,
                                    mask_obj,
                                    fov_num,
                                    save=True)
예제 #4
0
                    time.datetime.strftime("%d %b %Y %H:%M:%S UTC"),
                    ha='center',
                    va='center')

        # create a folder for the set of images, and save each one
        print("Saving Figure")
        figdir = '../figures/vza_orthographic/'

        folder = os.path.join(figdir, name_template)
        if not os.path.exists(folder): os.mkdir(folder)

        fname = "".join([name_template, "_{:02}.png".format(k + 1)])
        fpath = os.path.join(folder, fname)

        plt.savefig(fpath, dpi=240)
        plt.close()

    print("Finished")


if __name__ == '__main__':

    t0 = time_utils.Time((2015, 11, 15), (2015, 7, 15))

    region_snapshots('TAP_july15_november',
                     t0,
                     'TAP95W_july15.csv',
                     'TAP25E_july15.csv',
                     interval=3600,
                     N=48)
예제 #5
0
def combined(sim_file, lattice_files, datetime, centre, xco2_lims=None, map_bkgd='bluemarble', cmap='jet', out='show', **kwargs):
    """
    Create a combined plot 
    """

    _, (xco2_ax, cld_ax, ret_ax) = plt.subplots(nrows=1, ncols=3, figsize=(15,8))
    
    
    ##############################################################
    
    plt.sca(xco2_ax)
    
    
    xco2, xco2_lats, xco2_lons = ec_cas.global_XCO2(datetime)
    
    proj_xco2 = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='l')
    
    proj_xco2.drawcoastlines(linewidth=0.75)
    proj_xco2.drawcountries(linewidth=0.5)
    proj_xco2.drawmeridians(np.arange(-180, 181, 30), latmax=90, linewidth=0.5)
    proj_xco2.drawparallels(np.arange(-90, 91, 15), latmax=90, linewidth=0.5)
    
    
    lon, lat = np.meshgrid(xco2_lons, xco2_lats)
    x,y = proj_xco2(lon, lat)
    
    xco2_mask = np.ma.masked_greater(x, 1e15).mask
    xco2_masked = np.ma.array(xco2, mask=xco2_mask)
    
    if xco2_lims:
        vmin_xco2, vmax_xco2 = xco2_lims
    else:
        vmin_xco2 = xco2.min() // 1.
        vmax_xco2 = xco2.max() // 1. + 1.
    
    sm_xco2 = ScalarMappable(Normalize(vmin=vmin_xco2, vmax=vmax_xco2), cmap=cmap)
    levs_xco2 = np.linspace(vmin_xco2, vmax_xco2, 256)
    clevs_xco2 = [sm_xco2.to_rgba(lev) for lev in levs_xco2]
    
    xco2_ctr = plt.contourf(x, y, xco2_masked, levs_xco2, colors=clevs_xco2, extend='both')
    
    xco2_cbar = plt.colorbar(xco2_ctr, orientation='horizontal', fraction=0.1, aspect=40)
    xco2_cbar.set_label('Xco$_2$ [ppm]')
    xco2_cbar.set_ticks(np.arange(vmin_xco2, vmax_xco2 + 1, 1))
    
    plt.title(datetime.strftime('EC-CAS Run %d %b %Y %H:%M:%S'))
    
    
    ##############################################################
    
    plt.sca(cld_ax)
    
    
    mission = retrievals.Mission(sim_file, *lattice_files, **kwargs)
    
    obs_time = time_utils.Time(datetime, mission.satellite.times[0].ref)        
        
    # find the closest apogee point to obs_time
    apogees = mission.satellite.get_apogees()
    apogee_ind = time_utils.closest_index(obs_time, apogees)
    
    # create the ObservationPeriod instance, and generate the Retrieval instances
    obs = retrievals.ObservationPeriod(mission, apogees[apogee_ind], mission.lattice_files[apogee_ind%2])
    obs.main_filter()
    obs.generate_retrievals()
    
    # find the closest segment of the observation period
    obs_ind = time_utils.closest_index(obs_time, obs.obs_middle)
    
    # clat, clon = centre
    proj_cld = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='c')
    
    # draw cloud data that was used to determine FOV locations
    obs.cloud_collection.show_clouds_ortho(obs.cloud_times[obs_ind], centre, map_bkgd=map_bkgd, out='')
    
    proj_cld.nightshade(datetime)
    
    # draw a red border around each of the selected FOVs
    for ret in obs.retrievals[obs_ind]:
        
        lats = np.concatenate([ret.pixel_lats[:,0], ret.pixel_lats[-1,:], ret.pixel_lats[::-1,-1], ret.pixel_lats[0,::-1]])
        lons = np.concatenate([ret.pixel_lons[:,0], ret.pixel_lons[-1,:], ret.pixel_lons[::-1,-1], ret.pixel_lons[0,::-1]])
        
        x,y = proj_cld(lons, lats)
        coords = np.vstack([x,y]).T
        
        if not np.sum(coords > 1e15):
        
            p = Polygon(coords, fill=False, edgecolor='r', zorder=10)
            plt.gca().add_patch(p)
        
    plt.title('FoV Selections {0} - {1} UTC'.format(obs.obs_times[obs_ind].strf('%d %B %Y %H:%M'), obs.obs_times[obs_ind+1].strf('%H:%M')))
    
    
    ##############################################################
    
    plt.sca(ret_ax)
    
    
    proj_ret = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='l')
    
    if map_bkgd == 'bluemarble':
        proj_ret.bluemarble()
    elif map_bkgd == 'etopo':
        proj_ret.etopo()
    elif map_bkgd == 'mask':
        proj_ret.drawlsmask(land_color='limegreen', ocean_color='dodgerblue', resolution='l')
        
        proj_ret.drawcoastlines(linewidth=0.75)
        proj_ret.drawcountries(linewidth=0.5)
        proj_ret.drawmeridians(np.arange(-180, 181, 30), latmax=90, linewidth=0.5)
        proj_ret.drawparallels(np.arange(-90, 91, 15), latmax=90, linewidth=0.5)
    else:
        raise ValueError('invalid map background specification')
    
    proj_ret.nightshade(datetime)
    
    
    sm_ret = ScalarMappable(Normalize(vmin=vmin_xco2, vmax=vmax_xco2), cmap=cmap)
    levs_ret = np.linspace(vmin_xco2, vmax_xco2, 256)
    clevs_ret = [sm_ret.to_rgba(lev) for lev in levs_ret]
    
    xco2_interp = RegularGridInterpolator((xco2_lats, xco2_lons), xco2, bounds_error=False, fill_value=None)
    
    for ret in obs.retrievals[obs_ind]:
                
        x,y = proj_ret(ret.pixel_lons, ret.pixel_lats)
                
        if not np.sum(x > 1e15):
        
            latlon_arr = np.dstack([ret.pixel_lats, ret.pixel_lons])
            xco2_ret = xco2_interp(latlon_arr)
            
            retmask = ret.valid_retrievals == 0
            xco2_ret_masked = np.ma.array(xco2_ret, mask=retmask)
            
            ret_ctr = plt.contourf(x, y, xco2_ret_masked, levs_ret, colors=clevs_ret, extend='both')
        
    
    ret_cbar = plt.colorbar(ret_ctr, orientation='horizontal', fraction=0.1, aspect=40)
    ret_cbar.set_label('Xco$_2$ [ppm]')
    ret_cbar.set_ticks(np.arange(vmin_xco2, vmax_xco2 + 1, 1))
    
    plt.title('AIM-North Retrievals {0} - {1} UTC'.format(obs.obs_times[obs_ind].strf('%d %B %Y %H:%M'), obs.obs_times[obs_ind+1].strf('%H:%M')))   
            
    
    ##############################################################
    
    
    plt.suptitle('AIM-North Observing Strategy')
    plt.subplots_adjust(wspace=0.05, left=0.05, right=0.95, top=1., bottom=0.1)
    
    cld_ax.set_position([0.35, 0.2525, 0.3, 0.675])
        
    
    if out == 'show':
        plt.show()
    elif out == '':
        pass
    else:
        plt.savefig(os.path.join('../figures/combined_plots/', out))
        plt.close()
예제 #6
0
def combined_all_ghgs(sim_file, lattice_files, datetime, centre, xco2_lims=None, xco_lims=None, xch4_lims=None, map_bkgd='bluemarble', cmap='jet', out='show', **kwargs):

    fig = plt.figure(figsize=(15,12))
    
    xco2_ax = fig.add_subplot(231)
    xco_ax = fig.add_subplot(232)
    xch4_ax = fig.add_subplot(233)
    cld_ax = fig.add_subplot(223)
    ret_ax = fig.add_subplot(224)
    
    
    #####################################
    
    plt.sca(xco2_ax)
    
    
    xco2, xco2_lats, xco2_lons = ec_cas.global_XCO2(datetime)
    
    proj_xco2 = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='l')
    
    proj_xco2.drawcoastlines(linewidth=0.75)
    proj_xco2.drawcountries(linewidth=0.5)
    proj_xco2.drawmeridians(np.arange(-180, 181, 30), latmax=90, linewidth=0.5)
    proj_xco2.drawparallels(np.arange(-90, 91, 15), latmax=90, linewidth=0.5)
    
    
    lon, lat = np.meshgrid(xco2_lons, xco2_lats)
    x,y = proj_xco2(lon, lat)
    
    xco2_mask = np.ma.masked_greater(x, 1e15).mask
    xco2_masked = np.ma.array(xco2, mask=xco2_mask)
    
    if xco2_lims:
        vmin_xco2, vmax_xco2 = xco2_lims
    else:
        vmin_xco2 = xco2_masked.min() // 1.
        vmax_xco2 = xco2_masked.max() // 1. + 1.
    
    sm_xco2 = ScalarMappable(Normalize(vmin=vmin_xco2, vmax=vmax_xco2), cmap=cmap)
    levs_xco2 = np.linspace(vmin_xco2, vmax_xco2, 256)
    clevs_xco2 = [sm_xco2.to_rgba(lev) for lev in levs_xco2]
    
    xco2_ctr = plt.contourf(x, y, xco2_masked, levs_xco2, colors=clevs_xco2, extend='both')
    
    xco2_cbar = plt.colorbar(xco2_ctr, orientation='vertical', fraction=0.05, aspect=40, shrink=0.75)
    xco2_cbar.set_label('XCO$_2$ [ppm]')
    xco2_cbar.set_ticks(np.arange(vmin_xco2, vmax_xco2+0.25, 0.5))
    
    plt.title(datetime.strftime('XCO$_2$ %d %b %Y %H:%M:%S'))
    
    
    ######################################
    
    plt.sca(xco_ax)
    
    xco, xch4, xlats, xlons = ec_cas.global_ghg(datetime)
    
    proj_xco = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='l')
    
    proj_xco.drawcoastlines(linewidth=0.75)
    proj_xco.drawcountries(linewidth=0.5)
    proj_xco.drawmeridians(np.arange(-180, 181, 30), latmax=90, linewidth=0.5)
    proj_xco.drawparallels(np.arange(-90, 91, 15), latmax=90, linewidth=0.5)
    
    
    lon, lat = np.meshgrid(xlons, xlats)
    x,y = proj_xco(lon, lat)
    
    xco_mask = np.ma.masked_greater(x, 1e15).mask
    xco_masked = np.ma.array(xco, mask=xco_mask)
    
    if xco_lims:
        vmin_xco, vmax_xco = xco_lims
    else:
        vmin_xco = xco_masked.min() // 1.
        vmax_xco = xco_masked.max() // 1. + 1.
    
    sm_xco = ScalarMappable(Normalize(vmin=vmin_xco, vmax=vmax_xco), cmap=cmap)
    levs_xco = np.linspace(vmin_xco, vmax_xco, 256)
    clevs_xco = [sm_xco.to_rgba(lev) for lev in levs_xco]
    
    xco_ctr = plt.contourf(x, y, xco_masked, levs_xco, colors=clevs_xco, extend='both')
    
    xco_cbar = plt.colorbar(xco_ctr, orientation='vertical', fraction=0.1, aspect=40, shrink=0.75)
    xco_cbar.set_label('XCO [ppb]')
    xco_cbar.set_ticks(np.int64(np.arange(vmin_xco, vmax_xco+1, 10)))
    
    plt.title(datetime.strftime('XCO %d %b %Y %H:%M:%S'))
    
    
    #######################################
    
    plt.sca(xch4_ax)
    
    proj_xch4 = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='l')
    
    proj_xch4.drawcoastlines(linewidth=0.75)
    proj_xch4.drawcountries(linewidth=0.5)
    proj_xch4.drawmeridians(np.arange(-180, 181, 30), latmax=90, linewidth=0.5)
    proj_xch4.drawparallels(np.arange(-90, 91, 15), latmax=90, linewidth=0.5)
    
    
    lon, lat = np.meshgrid(xlons, xlats)
    x,y = proj_xch4(lon, lat)
    
    xch4_mask = np.ma.masked_greater(x, 1e15).mask
    xch4_masked = np.ma.array(xch4, mask=xch4_mask)
    
    if xch4_lims:
        vmin_xch4, vmax_xch4 = xch4_lims
    else:
        vmin_xch4 = xch4_masked.min() // 1.
        vmax_xch4 = xch4_masked.max() // 1. + 1.
    
    sm_xch4 = ScalarMappable(Normalize(vmin=vmin_xch4, vmax=vmax_xch4), cmap=cmap)
    levs_xch4 = np.linspace(vmin_xch4, vmax_xch4, 256)
    clevs_xch4 = [sm_xch4.to_rgba(lev) for lev in levs_xch4]
    
    xch4_ctr = plt.contourf(x, y, xch4_masked, levs_xch4, colors=clevs_xch4, extend='both')
    
    xch4_cbar = plt.colorbar(xch4_ctr, orientation='vertical', fraction=0.1, aspect=40, shrink=0.75)
    xch4_cbar.set_label('XCH$_4$ [ppb]')
    xch4_cbar.set_ticks(np.int64(np.arange(vmin_xch4, vmax_xch4 + 1, 20)))
    
    plt.title(datetime.strftime('XCH$_4$ %d %b %Y %H:%M:%S'))
    
    
    ##############################################################
    
    plt.sca(cld_ax)
    
    
    mission = retrievals.Mission(sim_file, *lattice_files, **kwargs)
    
    obs_time = time_utils.Time(datetime, mission.satellite.times[0].ref)        
        
    # find the closest apogee point to obs_time
    apogees = mission.satellite.get_apogees()
    apogee_ind = time_utils.closest_index(obs_time, apogees)
    
    # create the ObservationPeriod instance, and generate the Retrieval instances
    obs = retrievals.ObservationPeriod(mission, apogees[apogee_ind], mission.lattice_files[apogee_ind%2])
    obs.main_filter()
    obs.generate_retrievals()
    
    # find the closest segment of the observation period
    obs_ind = time_utils.closest_index(obs_time, obs.obs_middle)
    
    clat, clon = centre
    proj_cld = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='c')
    
    # draw cloud data that was used to determine FOV locations
    obs.cloud_collection.show_clouds_ortho(obs.cloud_times[obs_ind], centre, map_bkgd=map_bkgd, out='')
    
    proj_cld.nightshade(datetime)
    
    # draw a red border around each of the selected FOVs
    for ret in obs.retrievals[obs_ind]:
        
        lats = np.concatenate([ret.pixel_lats[:,0], ret.pixel_lats[-1,:], ret.pixel_lats[::-1,-1], ret.pixel_lats[0,::-1]])
        lons = np.concatenate([ret.pixel_lons[:,0], ret.pixel_lons[-1,:], ret.pixel_lons[::-1,-1], ret.pixel_lons[0,::-1]])
        
        x,y = proj_cld(lons, lats)
        coords = np.vstack([x,y]).T
        
        if not np.sum(coords > 1e15):
        
            p = Polygon(coords, fill=False, edgecolor='r', zorder=10)
            plt.gca().add_patch(p)
        
    plt.title('FoV Selections {0} - {1} UTC'.format(obs.obs_times[obs_ind].strf('%d %B %Y %H:%M'), obs.obs_times[obs_ind+1].strf('%H:%M')))
    
    
    ##############################################################
    
    plt.sca(ret_ax)
    
    
    proj_ret = Basemap(projection='ortho', lat_0=centre[0], lon_0=centre[1], resolution='l')
    
    if map_bkgd == 'bluemarble':
        proj_ret.bluemarble()
    elif map_bkgd == 'etopo':
        proj_ret.etopo()
    elif map_bkgd == 'mask':
        proj_ret.drawlsmask(land_color='limegreen', ocean_color='dodgerblue', resolution='l')
        
        proj_ret.drawcoastlines(linewidth=0.75)
        proj_ret.drawcountries(linewidth=0.5)
        proj_ret.drawmeridians(np.arange(-180, 181, 30), latmax=90, linewidth=0.5)
        proj_ret.drawparallels(np.arange(-90, 91, 15), latmax=90, linewidth=0.5)
    else:
        raise ValueError('invalid map background specification')
    
    proj_ret.nightshade(datetime)
    
    
    
    for ret in obs.retrievals[obs_ind]:
                
        x,y = proj_ret(ret.pixel_lons, ret.pixel_lats)
                
        if not np.sum(x > 1e15):
        
            
            ret_mask = ret.valid_retrievals == 0
            ret_masked = np.ma.array(np.ones(ret.pixel_lats.shape), mask=ret_mask)
            
            ret_ctr = plt.contourf(x, y, ret_masked, [0,1], colors=['red'], extend='both')
        
    
    plt.title('AIM-North Retrievals {0} - {1} UTC'.format(obs.obs_times[obs_ind].strf('%d %B %Y %H:%M'), obs.obs_times[obs_ind+1].strf('%H:%M')))   
            
    ##############################################################
    
    plt.subplots_adjust(left=0.01, right=0.95, bottom=0.025, top = 0.975, wspace=0.175, hspace=0.1)
    
    if out == 'show':
        plt.show()
    elif out == '':
        pass
    else:
        plt.savefig(os.path.join('../figures/combined_plots/', out))
        plt.close()
예제 #7
0
def FoV_selections(sim_file,
                   lattice_files,
                   datetime,
                   centre,
                   map_bkgd='bluemarble',
                   out='show',
                   **mission_params):
    """
    Plots the fields of view chosen by the intelligent pointing algorithm onto a map.
    
    Args:
    - sim_file: GMAT output file path to use
    - lattice_files: list - List of lattice files used for the mission
    - datetime: dt.datetime instance - Time at which to plot points
    - center: tuple: (latitude, longitude) to be used as the center of an orthographic projection
    - map_bkgd: Background to plot on the map
    - out: either 'save' or 'show. Saves or shows the figure
    
    mission_params:
    - kwargs for retrievals.Mission instance.
    """

    mission = retrievals.Mission(sim_file, *lattice_files, **mission_params)

    obs_time = time_utils.Time(datetime, mission.satellite.times[0].ref)

    # find the closest apogee point to obs_time
    apogees = mission.satellite.get_apogees()
    apogee_ind = time_utils.closest_index(obs_time, apogees)

    # create the ObservationPeriod instance, and generate the Retrieval instances
    obs = retrievals.ObservationPeriod(
        mission, apogees[apogee_ind],
        mission.lattice_files[apogee_ind % len(lattice_files)])
    obs.main_filter()
    obs.generate_retrievals()
    print(len(obs.retrievals))

    # find the closest segment of the observation period
    obs_ind = time_utils.closest_index(obs_time, obs.obs_middle)

    proj_cld = Basemap(projection='ortho',
                       lat_0=centre[0],
                       lon_0=centre[1],
                       resolution='c')
    proj_cld.drawcoastlines()
    proj_cld.drawcountries()
    # draw cloud data that was used to determine FOV locations
    obs.cloud_collection.show_clouds_ortho(obs.cloud_times[obs_ind],
                                           centre,
                                           map_bkgd=map_bkgd,
                                           out='')

    proj_cld.nightshade(datetime)

    # draw a red border around each of the selected FOVs
    for ret in obs.retrievals[obs_ind]:

        lats = np.concatenate([
            ret.pixel_lats[:, 0], ret.pixel_lats[-1, :],
            ret.pixel_lats[::-1, -1], ret.pixel_lats[0, ::-1]
        ])
        lons = np.concatenate([
            ret.pixel_lons[:, 0], ret.pixel_lons[-1, :],
            ret.pixel_lons[::-1, -1], ret.pixel_lons[0, ::-1]
        ])

        x, y = proj_cld(lons, lats)
        coords = np.vstack([x, y]).T

        if not np.sum(coords > 1e15):

            p = Polygon(coords, fill=False, edgecolor='r', zorder=10)
            plt.gca().add_patch(p)

    plt.title('FoV Selections {0} - {1} UTC'.format(
        obs.obs_times[obs_ind].strf('%d %B %Y %H:%M'),
        obs.obs_times[obs_ind + 1].strf('%H:%M')))

    if out == 'show':
        plt.show()
    elif out == '':
        pass
    else:
        plt.savefig(out)
        plt.close()
예제 #8
0
def animate_FoV(sim_file, lattice_files, date_range, map_bkgd='mask', out='show', **mission_params):
    print("animate_FOV")
    assert type(sim_file) == str
    assert type(lattice_files) == list
    assert type(date_range) == tuple
    """
    Creates an animation (avi file) of field-of-view selections and cloud cover over time for one satellite.
    
    Args: 
    
    - sim_file: GMAT output file path to use
    - lattice_file: list - List of lattice files used for the mission. Must be given in order of W-E, starting with the first apogee
    - date_range: tuple of dt.datetime instances - (start time, end time) tuple for the animation. Requires year, month, day, hour.
    - map_bkgd: Background to plot on the map
    - out: either 'save' or 'show. Saves or shows the figure
    
    mission_params:
    - kwargs for retrievals.Mission instance.
    
    """
    
    # Set up the mission instance and find the apogees
    mission = retrievals.Mission(sim_file, *lattice_files, **mission_params)
    apogees = mission.satellite.get_apogees()
    
    # Get the start and end times and convert them from dt.datetime instances to time_utils.Time instances
    start_time = time_utils.Time(date_range[0], mission.satellite.times[0].ref)
    end_time = time_utils.Time(date_range[1], mission.satellite.times[0].ref)
    
    
    # Get the indices of the first and last apogees relevant to the time period
    apogee_start_ind = time_utils.closest_index(start_time, apogees)
    apogee_last_ind = time_utils.closest_index(end_time, apogees)

    # Empty directory to store temporary images before making the animation
    temp_dir = '../figures/animation_temp' 
    if not os.path.exists(temp_dir):
        os.mkdir(temp_dir)
    
    # Generate a retrievals.ObservationPeriod instance for every apogee in the relevant time frame
    for k in range(apogee_start_ind, apogee_last_ind + 1):
        # create the ObservationPeriod instance, and generate the Retrieval instances
        if lattice_files == []:
            lat_file = None
        else:
            lat_file = mission.lattice_files[k%len(lattice_files)]
        obs = retrievals.ObservationPeriod(mission, apogees[k], lat_file)
        obs.main_filter()
        obs.generate_retrievals()
        
        # after this point we're just plotting stuff, no actual analysis
        col = 'xkcd:red'
        lat_0 = 90
        lon_0 = -95
        map_params = {"projection": 'ortho',
                    "lat_0": lat_0,
                    "lon_0": lon_0,
                    "resolution": 'c'}
        # Plot cloud data and pointing selections for each segment of each observation period
        for i in range(len(obs.retrievals)):
            
            proj_cld = Basemap(**map_params)
            
            # draw cloud data that was used to determine FOV locations
            obs.cloud_collection.show_clouds_ortho(
                obs.cloud_times[i], (lat_0, lon_0), map_bkgd=map_bkgd, out='')
            # Draw terminator
            proj_cld.nightshade(
                obs.obs_times[i].to_datetime64().astype(dt.datetime))
            
            # Draw a bullseye at the sub-satellite point
            satx, saty = proj_cld(obs.satlon[i], obs.satlat[i])
            inner = Circle(
                (satx,saty), radius=9e4, color=col, zorder=10)
            outer = Circle(
                (satx,saty), radius=2e5, linewidth=1.5, facecolor = 'k',
                edgecolor=col, zorder = 10 )
            plt.gca().add_patch(outer)
            plt.gca().add_patch(inner)
            
            for ret in obs.retrievals[i]:
                # draw a border around each of the selected FOVs
                lats = np.concatenate([ret.pixel_lats[:,0],
                    ret.pixel_lats[-1,:],
                    ret.pixel_lats[::-1,-1],
                    ret.pixel_lats[0,::-1]])
                lons = np.concatenate([ret.pixel_lons[:,0],
                    ret.pixel_lons[-1,:],
                    ret.pixel_lons[::-1,-1],
                    ret.pixel_lons[0,::-1]])
        
                x,y = proj_cld(lons, lats)
                coords = np.vstack([x,y]).T
                
                if not np.sum(coords > 1e15):
                    p = Polygon(coords, fill=False, edgecolor=col, zorder=10,
                        antialiased = True) 
                    plt.gca().add_patch(p)

            plt.title('{0} - {1} UTC'.format(
                obs.obs_times[i].strftime('%d %B %H:%M'),
                obs.obs_times[i+1].strftime('%H:%M')))
            # Save the figure in the temporary directory
            fname = 'FoVs{0}.png'.format(
                obs.obs_times[i].strftime('%y%m%d%H:%M'))
            fpath = os.path.join(temp_dir, fname)
            plt.savefig(fpath, dpi=500)
            print('Saved figure: {0}-{1}.png'.format(
                obs.obs_times[i].strftime('%m%d%Y%H:%M'),
                obs.obs_times[i+1].strftime('%H:%M')))
            #plt.show()
            plt.close()

    # Create an animation using all the temporary images
    os.system(('mencoder -o '
               '../figures/constellationview_{0}_{1}.avi '
               'mf://../figures/animation_temp/FoVs*.png '
               '-ovc lavc -lavcopts vcodec=msmpeg4v2 -mf '
               'fps=2').format(start_time.strftime('%y%m%d'),
                              end_time.strftime('%y%m%d')))
    # Delete the temporary images
    os.system('rm ../figures/animation_temp/*.png')
    os.system('rmdir ../figures/animation_temp')