示例#1
0
    def get_angles(self):
        self.get_times()
        tle1, tle2 = self.get_tle_lines()
        orb = Orbital(self.spacecrafts_orbital[self.spacecraft_id],
                      line1=tle1,
                      line2=tle2)

        sat_azi, sat_elev = orb.get_observer_look(self.times[:, np.newaxis],
                                                  self.lons, self.lats, 0)

        sat_zenith = 90 - sat_elev

        sun_zenith = astronomy.sun_zenith_angle(self.times[:, np.newaxis],
                                                self.lons, self.lats)

        alt, sun_azi = astronomy.get_alt_az(self.times[:, np.newaxis],
                                            self.lons, self.lats)
        del alt
        sun_azi = np.rad2deg(sun_azi)
        sun_azi = np.where(sun_azi < 0, sun_azi + 180, sun_azi - 180)

        rel_azi = abs(sat_azi - sun_azi)
        rel_azi = np.where(rel_azi > 180.0, 360.0 - rel_azi, rel_azi)

        return sat_azi, sat_zenith, sun_azi, sun_zenith, rel_azi
示例#2
0
    def __call__(self, projectables, optional_datasets=None, **info):
        """Get the corrected reflectance when removing Rayleigh scattering. Uses
        pyspectral.
        """
        from pyspectral.rayleigh import Rayleigh

        (vis, red) = projectables
        if vis.shape != red.shape:
            raise IncompatibleAreas
        try:
            (sata, satz, suna, sunz) = optional_datasets
        except ValueError:
            from pyorbital.astronomy import get_alt_az, sun_zenith_angle
            from pyorbital.orbital import get_observer_look
            lons, lats = vis.info['area'].get_lonlats()
            sunalt, suna = get_alt_az(vis.info['start_time'], lons, lats)
            suna = np.rad2deg(suna)
            sunz = sun_zenith_angle(vis.info['start_time'], lons, lats)
            sata, satel = get_observer_look(vis.info['satellite_longitude'],
                                            vis.info['satellite_latitude'],
                                            vis.info['satellite_altitude'],
                                            vis.info['start_time'], lons, lats,
                                            0)
            satz = 90 - satel
            del satel
        LOG.info('Removing Rayleigh scattering and aerosol absorption')

        # First make sure the two azimuth angles are in the range 0-360:
        sata = np.mod(sata, 360.)
        suna = np.mod(suna, 360.)
        ssadiff = np.abs(suna - sata)
        ssadiff = np.where(ssadiff > 180, 360 - ssadiff, ssadiff)
        del sata, suna

        atmosphere = self.info.get('atmosphere', 'us-standard')
        aerosol_type = self.info.get('aerosol_type', 'marine_clean_aerosol')

        corrector = Rayleigh(vis.info['platform_name'],
                             vis.info['sensor'],
                             atmosphere=atmosphere,
                             aerosol_type=aerosol_type)

        try:
            refl_cor_band = corrector.get_reflectance(sunz, satz, ssadiff,
                                                      vis.id.name, red)
        except KeyError:
            LOG.warning(
                "Could not get the reflectance correction using band name: %s",
                vis.id.name)
            LOG.warning(
                "Will try use the wavelength, however, this may be ambiguous!")
            refl_cor_band = corrector.get_reflectance(sunz, satz, ssadiff,
                                                      vis.id.wavelength[1],
                                                      red)

        proj = Dataset(vis - refl_cor_band, copy=False, **vis.info)
        self.apply_modifier_info(vis, proj)

        return proj
示例#3
0
    def parse_jaxa_hotspot_txt(self, file_path):
        """
        Parse the JAXA Himawari-8/9 AHI hotspot text file and insert attrs into the Pandas DataFrame

        Args:
            file_path (str): File path to the JAXA Himawari-8/9 hotspot .csv

        Returns:
            hs_df (obj): DataFrame obj that contains attr of Himawari-8/9 hospot
        """
        hs_ahi_df = pd.DataFrame()
        cols_to_use_list = [0, 2, *(i for i in range(7, 24))]
        date_col_list = [0]
        names_list = ['date', 'satellite', 'lon', 'lat', 'viewzenang', 'viewazang', 'pixwid', 'pixlen', 't07',
                      't14', 't07_t14', 'meant07', 'meant14', 'meandt', 'sdt07', 'sdt14', 'sddt',
                      'ref3', 'ref4']

        for file in glob.glob(file_path):
            try:
                log.debug(f'Reading {file}')
                temp_hs_ahi_df = pd.read_csv(file, sep=",", skiprows=[0], \
                                             header=None, usecols=cols_to_use_list, \
                                             names=names_list, \
                                             parse_dates=date_col_list)
                temp_hs_ahi_df['satellite'] = 'Himawari-8/9'
            except Exception as e:
                log.error(f'Error reading {file}')
                log.error(e)
                continue

            if len(temp_hs_ahi_df) > 0:
                try:
                    temp_hs_ahi_df['solarazang'] = temp_hs_ahi_df.apply( \
                        lambda x: np.degrees(astronomy.get_alt_az(x['date'], x['lon'], x['lat'])[1]), axis=1)
                    temp_hs_ahi_df['solarzenang'] = temp_hs_ahi_df.apply( \
                        lambda x: astronomy.sun_zenith_angle(x['date'], x['lon'], x['lat']), axis=1)
                    temp_hs_ahi_df['relazang'] = temp_hs_ahi_df['solarazang'] - temp_hs_ahi_df['viewazang']
                    temp_hs_ahi_df['sunglint_angle'] = temp_hs_ahi_df.apply(compute_sun_glint_angle, axis=1)
                except Exception as e:
                    temp_hs_ahi_df['sunglint_angle'] = np.nan

                try:
                    temp_hs_ahi_df.loc[(temp_hs_ahi_df['date'].dt.hour >= 0) \
                                       & (temp_hs_ahi_df['date'].dt.hour <= 11), 'daynight'] = 'day'
                    temp_hs_ahi_df.loc[temp_hs_ahi_df['date'].dt.hour > 11, \
                                       'daynight'] = 'night'
                    temp_hs_ahi_df['date'] = temp_hs_ahi_df['date'].dt.strftime( \
                        "%d/%m/%Y %H:%M:%S")
                except Exception as e:
                    date_from_file = datetime.strptime(filename[4:17], "%Y%m%d_%H%M")
                    temp_hs_ahi_df['date'] = date_from_file.strftime("%d/%m/%Y %H:%M:%S")

            hs_ahi_df = pd.concat([hs_ahi_df, temp_hs_ahi_df])

        if len(hs_ahi_df) > 0:
            hs_ahi_df = hs_ahi_df.reset_index(drop=True)

        self.hs_df = pd.concat([hs_ahi_df, self.hs_df])
示例#4
0
文件: viirs.py 项目: ColinDuff/satpy
    def get_angles(self, vis):
        from pyorbital.astronomy import get_alt_az, sun_zenith_angle
        from pyorbital.orbital import get_observer_look

        lons, lats = vis.attrs['area'].get_lonlats_dask(chunks=vis.data.chunks)
        suna = get_alt_az(vis.attrs['start_time'], lons, lats)[1]
        suna = xu.rad2deg(suna)
        sunz = sun_zenith_angle(vis.attrs['start_time'], lons, lats)
        sata, satel = get_observer_look(vis.attrs['satellite_longitude'],
                                        vis.attrs['satellite_latitude'],
                                        vis.attrs['satellite_altitude'],
                                        vis.attrs['start_time'], lons, lats, 0)
        satz = 90 - satel
        return sata, satz, suna, sunz
示例#5
0
    def get_angles(self):
        """Get azimuth and zenith angles.

        Azimuth angle definition is the same as in pyorbital, but with
        different units (degrees not radians for sun azimuth angles)
        and different ranges.

        Returns:
            sat_azi: satellite azimuth angle
                degree clockwise from north in range ]-180, 180],
            sat_zentih: satellite zenith angles in degrees in range [0,90],
            sun_azi: sun azimuth angle
                degree clockwise from north in range ]-180, 180],
            sun_zentih: sun zenith angles in degrees in range [0,90],
            rel_azi: absolute azimuth angle difference in degrees between sun
                and sensor in range [0, 180]

        """
        self.get_times()
        self.get_lonlat()
        tle1, tle2 = self.get_tle_lines()
        times = self.times
        orb = Orbital(self.spacecrafts_orbital[self.spacecraft_id],
                      line1=tle1,
                      line2=tle2)

        sat_azi, sat_elev = orb.get_observer_look(times[:, np.newaxis],
                                                  self.lons, self.lats, 0)

        sat_zenith = 90 - sat_elev

        sun_zenith = astronomy.sun_zenith_angle(times[:, np.newaxis],
                                                self.lons, self.lats)

        alt, sun_azi = astronomy.get_alt_az(times[:, np.newaxis], self.lons,
                                            self.lats)
        del alt
        sun_azi = np.rad2deg(sun_azi)
        rel_azi = get_absolute_azimuth_angle_diff(sun_azi, sat_azi)

        # Scale angles range to half open interval ]-180, 180]
        sat_azi = centered_modulus(sat_azi, 360.0)
        sun_azi = centered_modulus(sun_azi, 360.0)

        # Mask corrupt scanlines
        for arr in (sat_azi, sat_zenith, sun_azi, sun_zenith, rel_azi):
            arr[self.mask] = np.nan

        return sat_azi, sat_zenith, sun_azi, sun_zenith, rel_azi
示例#6
0
    def __call__(self, projectables, optional_datasets=None, **info):
        """Get the corrected reflectance when removing Rayleigh scattering. Uses
        pyspectral.
        """
        from pyspectral.rayleigh import Rayleigh

        (vis, blue) = projectables
        if vis.shape != blue.shape:
            raise IncompatibleAreas
        try:
            (sata, satz, suna, sunz) = optional_datasets
        except ValueError:
            from pyorbital.astronomy import get_alt_az, sun_zenith_angle
            from pyorbital.orbital import get_observer_look
            sunalt, suna = get_alt_az(
                vis.info['start_time'], *vis.info['area'].get_lonlats())
            suna = np.rad2deg(suna)
            sunz = sun_zenith_angle(
                vis.info['start_time'], *vis.info['area'].get_lonlats())
            lons, lats = vis.info['area'].get_lonlats()
            sata, satel = get_observer_look(vis.info['satellite_longitude'],
                                            vis.info['satellite_latitude'],
                                            vis.info['satellite_altitude'],
                                            vis.info['start_time'],
                                            lons, lats, 0)
            satz = 90 - satel
            del satel
        LOG.info('Removing Rayleigh scattering and aerosol absorption')

        ssadiff = np.abs(suna - sata)
        ssadiff = np.where(ssadiff > 180, 360 - ssadiff, ssadiff)
        del sata, suna

        atmosphere = self.info.get('atmosphere', 'us-standard')
        aerosol_type = self.info.get('aerosol_type', 'marine_clean_aerosol')

        corrector = Rayleigh(vis.info['platform_name'], vis.info['sensor'],
                             atmosphere=atmosphere,
                             aerosol_type=aerosol_type)

        refl_cor_band = corrector.get_reflectance(
            sunz, satz, ssadiff, vis.id.wavelength[1], blue)

        proj = Dataset(vis - refl_cor_band,
                       copy=False,
                       **vis.info)
        self.apply_modifier_info(vis, proj)

        return proj
def getSentinel2Geometry(startDateUTC, lengthDays, lat, lon, alt=0.0, mission="Sentinel-2a",
                         tleFile="../TLE/norad_resource_tle.txt"):
    """Calculate approximate geometry for Sentinel overpasses.
    Approximate because it assumes maximum satellite elevation
    is the time at which target is imaged.

    :param startDateUTC: a datetime object specifying when to start prediction.
    :type startDateUTC: object
    :param lengthDays: number of days over which to perform calculations.
    :type lengthDays: int
    :param lat: latitude of target.
    :type lat: float
    :param lon: longitude of target.
    :type lon: float
    :param alt: altitude of target (in km).
    :type alt: float
    :param mission: mission name as in TLE file.
    :type mission: str
    :param tleFile: TLE file.
    :type tleFile: str
    :return: a python list containing instances of the sensorGeometry class arranged in date order.
    :rtype: list
    """
    orb = Orbital(mission, tleFile)
    passes = orb.get_next_passes(startDateUTC, 24 * lengthDays, lon, lat, alt)

    geomList = []

    for p in passes:
        look = orb.get_observer_look(p[2], lon, lat, alt)
        vza = 90 - look[1]
        vaa = look[0]
        sza = ast.sun_zenith_angle(p[2], lon, lat)
        saa = np.rad2deg(ast.get_alt_az(p[2], lon, lat)[1])

        if sza < 90 and vza < 10.3:
            thisGeom = sensorGeometry()
            thisGeom.date_utc = p[2]
            thisGeom.vza = vza
            thisGeom.vaa = vaa
            thisGeom.sza = sza
            thisGeom.saa = saa
            geomList.append(thisGeom)

    return geomList
示例#8
0
    def get_angles(self, vis):
        from pyorbital.astronomy import get_alt_az, sun_zenith_angle
        from pyorbital.orbital import get_observer_look

        lons, lats = vis.attrs['area'].get_lonlats_dask(
            chunks=vis.data.chunks)

        sunalt, suna = get_alt_az(vis.attrs['start_time'], lons, lats)
        suna = xu.rad2deg(suna)
        sunz = sun_zenith_angle(vis.attrs['start_time'], lons, lats)
        sata, satel = get_observer_look(
            vis.attrs['satellite_longitude'],
            vis.attrs['satellite_latitude'],
            vis.attrs['satellite_altitude'],
            vis.attrs['start_time'],
            lons, lats, 0)
        satz = 90 - satel
        return sata, satz, suna, sunz
示例#9
0
    def get_angles(self, vis):
        from pyorbital.astronomy import get_alt_az, sun_zenith_angle
        from pyorbital.orbital import get_observer_look

        lons, lats = vis.attrs['area'].get_lonlats_dask(chunks=vis.data.chunks)
        suna = get_alt_az(vis.attrs['start_time'], lons, lats)[1]
        suna = np.rad2deg(suna)
        sunz = sun_zenith_angle(vis.attrs['start_time'], lons, lats)
        sat_lon, sat_lat, sat_alt = get_satpos(vis)
        sata, satel = get_observer_look(
            sat_lon,
            sat_lat,
            sat_alt / 1000.0,  # km
            vis.attrs['start_time'],
            lons,
            lats,
            0)
        satz = 90 - satel
        return sata, satz, suna, sunz
示例#10
0
    def __call__(self, projectables, optional_datasets=None, **info):
        """Get the corrected reflectance when removing Rayleigh scattering. Uses
        pyspectral.
        """

        from pyspectral.rayleigh import Rayleigh

        (vis, ) = projectables
        try:
            (sata, satz, suna, sunz) = optional_datasets
        except ValueError:
            from pyorbital.astronomy import get_alt_az, sun_zenith_angle
            from pyorbital.orbital import get_observer_look
            sunalt, suna = get_alt_az(vis.info['start_time'],
                                      *vis.info['area'].get_lonlats())
            sunz = sun_zenith_angle(vis.info['start_time'],
                                    *vis.info['area'].get_lonlats())
            lons, lats = vis.info['area'].get_lonlats()
            sata, satel = get_observer_look(vis.info['satellite_longitude'],
                                            vis.info['satellite_latitude'],
                                            vis.info['satellite_altitude'],
                                            vis.info['start_time'], lons, lats,
                                            0)
            satz = 90 - satel

        LOG.info('Removing Rayleigh scattering')

        ssadiff = np.abs(suna - sata)
        ssadiff = np.where(np.greater(ssadiff, 180), 360 - ssadiff, ssadiff)

        corrector = Rayleigh(vis.info['platform_name'],
                             vis.info['sensor'],
                             atmosphere='us-standard',
                             rural_aerosol=False)

        refl_cor_band = corrector.get_reflectance(sunz, satz, ssadiff,
                                                  vis.info['id'].wavelength[1],
                                                  vis)

        proj = Projectable(vis - refl_cor_band, copy=False, **vis.info)
        self.apply_modifier_info(vis, proj)

        return proj
示例#11
0
 def get_angles(self, vis):
     """Get sun and satellite angles to use in crefl calculations."""
     from pyorbital.astronomy import get_alt_az, sun_zenith_angle
     from pyorbital.orbital import get_observer_look
     lons, lats = vis.attrs['area'].get_lonlats(chunks=vis.data.chunks)
     lons = da.where(lons >= 1e30, np.nan, lons)
     lats = da.where(lats >= 1e30, np.nan, lats)
     suna = get_alt_az(vis.attrs['start_time'], lons, lats)[1]
     suna = np.rad2deg(suna)
     sunz = sun_zenith_angle(vis.attrs['start_time'], lons, lats)
     sat_lon, sat_lat, sat_alt = get_satpos(vis)
     sata, satel = get_observer_look(
         sat_lon,
         sat_lat,
         sat_alt / 1000.0,  # km
         vis.attrs['start_time'],
         lons, lats, 0)
     satz = 90 - satel
     return sata, satz, suna, sunz
示例#12
0
文件: __init__.py 项目: pytroll/satpy
    def __call__(self, projectables, optional_datasets=None, **info):
        """Get the corrected reflectance when removing Rayleigh scattering. Uses
        pyspectral.
        """

        from pyspectral.rayleigh import Rayleigh

        (vis,) = projectables
        try:
            (sata, satz, suna, sunz) = optional_datasets
        except ValueError:
            from pyorbital.astronomy import get_alt_az, sun_zenith_angle
            from pyorbital.orbital import get_observer_look
            sunalt, suna = get_alt_az(
                vis.info['start_time'], *vis.info['area'].get_lonlats())
            sunz = sun_zenith_angle(
                vis.info['start_time'], *vis.info['area'].get_lonlats())
            lons, lats = vis.info['area'].get_lonlats()
            sata, satel = get_observer_look(vis.info['satellite_longitude'],
                                            vis.info['satellite_latitude'],
                                            vis.info['satellite_altitude'],
                                            vis.info['start_time'],
                                            lons, lats, 0)
            satz = 90 - satel

        LOG.info('Removing Rayleigh scattering')

        ssadiff = np.abs(suna - sata)
        ssadiff = np.where(np.greater(ssadiff, 180), 360 - ssadiff, ssadiff)

        corrector = Rayleigh(
            vis.info['platform_name'], vis.info['sensor'], atmosphere='us-standard', rural_aerosol=False)

        refl_cor_band = corrector.get_reflectance(
            sunz, satz, ssadiff, vis.info['id'].wavelength[1], vis)

        proj = Projectable(vis - refl_cor_band,
                           copy=False,
                           **vis.info)
        self.apply_modifier_info(vis, proj)

        return proj
示例#13
0
def get_solar_angles(scene, lons, lats):
    """Compute solar angles.

    Compute angles for each scanline using their acquisition time to account for
    the earth's rotation over the course of one scan.

    Returns:
        Solar azimuth angle, Solar zenith angle in degrees

    """
    suna = np.full(lons.shape, np.nan)
    sunz = np.full(lons.shape, np.nan)
    mean_acq_time = get_mean_acq_time(scene)
    for line, acq_time in enumerate(mean_acq_time.values):
        if np.isnat(acq_time):
            continue
        _, suna_line = get_alt_az(acq_time, lons[line, :], lats[line, :])
        suna_line = np.rad2deg(suna_line)
        suna[line, :] = suna_line
        sunz[line, :] = sun_zenith_angle(acq_time, lons[line, :],
                                         lats[line, :])
    return suna, sunz
示例#14
0
def _get_sun_azimuth_ndarray(lons: np.ndarray, lats: np.ndarray,
                             start_time: datetime) -> np.ndarray:
    with ignore_invalid_float_warnings():
        suna = get_alt_az(start_time, lons, lats)[1]
        suna = np.rad2deg(suna)
    return suna
                                        lats[:, :][::1, ::1])
print(sun_zenith.shape)
#------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------
# Apply the sun zenith correction
data1 = (data1) / (np.cos(np.deg2rad(sun_zenith)))
data2 = (data2) / (np.cos(np.deg2rad(sun_zenith)))
data3 = (data3) / (np.cos(np.deg2rad(sun_zenith)))
#------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------
# Applying the Rayleigh correction

from pyorbital.astronomy import get_alt_az
from pyorbital.orbital import get_observer_look

sunalt, suna = get_alt_az(utc_time, lons, lats)
suna = np.rad2deg(suna)
#sata, satel = get_observer_look(sat_lon, sat_lat, sat_alt, vis.attrs['start_time'], lons, lats, 0)
sata, satel = get_observer_look(longitude, 0.0, sat_h, utc_time, lons, lats, 0)
satz = 90 - satel

# Reyleigh Correction
atmosphere = 'us-standard'
aerosol_type = 'rayleigh_only'
rayleigh_key = ('GOES-16', 'abi', atmosphere, aerosol_type)
corrector = Rayleigh('GOES-16',
                     'abi',
                     atmosphere=atmosphere,
                     aerosol_type=aerosol_type)

sata = sata % 360.
示例#16
0
def process_one_scan(tslot_files,
                     out_path,
                     process_buggy_satellite_zenith_angles=False):
    """ Make level 1c files in PPS-format """
    tic = time.time()
    image_num = 0  # name of first dataset is image0
    #if len(tslot_files) != 8 * len(BANDNAMES) + 2:
    #    raise Exception("Some data is missing")
    platform_shortname = p__.parse(os.path.basename(
        tslot_files[0]))['platform_shortname']
    start_time = p__.parse(os.path.basename(tslot_files[0]))['start_time']
    platform_name = PLATFORM_SHORTNAMES[platform_shortname]
    #Load channel data for one scene and set some attributes
    coefs = get_calibration_for_time(platform=platform_shortname,
                                     time=start_time)

    scn_ = Scene(reader='seviri_l1b_hrit',
                 filenames=tslot_files,
                 reader_kwargs={
                     'calib_mode': CALIB_MODE,
                     'ext_calib_coefs': coefs
                 })
    scn_.attrs['platform_name'] = platform_name

    #SEVIRI data only
    if scn_.attrs['sensor'] == {'seviri'}:
        sensor = 'seviri'
        scn_.load(BANDNAMES)
    for band in BANDNAMES:
        idtag = PPS_TAGNAMES[band]
        scn_[band].attrs['id_tag'] = idtag
        scn_[band].attrs['description'] = 'SEVIRI ' + str(band)
        scn_[band].attrs['sun_earth_distance_correction_applied'] = 'False'
        scn_[band].attrs['sun_earth_distance_correction_factor'] = 1.0
        scn_[band].attrs['sun_zenith_angle_correction_applied'] = 'False'
        scn_[band].attrs['name'] = "image{:d}".format(image_num)
        scn_[band].attrs['coordinates'] = 'lon lat'
        image_num += 1

    #correct area
    area_corr = pyresample.geometry.AreaDefinition(
        'seviri-corrected', 'Corrected SEVIRI L1.5 grid (since Dec 2017)',
        'geosmsg', {
            'a': 6378169.00,
            'b': 6356583.80,
            'h': 35785831.0,
            'lon_0': 0.0,
            'proj': 'geos',
            'units': 'm'
        }, 3712, 3712, (5567248.28340708, 5570248.686685662,
                        -5570248.686685662, -5567248.28340708))
    if not scn_['IR_108'].attrs['georef_offset_corrected']:
        scn_ = scn_.resample(area_corr)
        print(scn_['IR_108'].attrs['georef_offset_corrected'])

    #import pdb;pdb.set_trace()
    #Set som header attributes:
    scn_.attrs['platform'] = platform_name
    scn_.attrs['instrument'] = sensor.upper()
    scn_.attrs['source'] = "seviri2pps.py"
    scn_.attrs['orbit_number'] = "99999"
    #scn_.attrs['orbit'] = "99999"
    nowutc = datetime.utcnow()
    scn_.attrs['date_created'] = nowutc.strftime("%Y-%m-%dT%H:%M:%SZ")
    #Find lat/lon data
    irch = scn_['IR_108']
    lons, lats = irch.attrs['area'].get_lonlats()
    lons[lons > 360] = -999.0
    lons[lons < -360] = -999.0
    lats[lats > 360] = -999.0
    lats[lats < -360] = -999.0

    #Find angles data
    sunalt, suna = get_alt_az(irch.attrs['start_time'],
                              *irch.attrs['area'].get_lonlats())
    suna = np.rad2deg(suna)
    sunz = sun_zenith_angle(irch.attrs['start_time'],
                            *irch.attrs['area'].get_lonlats())

    # if:
    #   Buggy data is requested buggy data is prepared!
    # elif:
    #   1) get_observer_look() gives wrong answer ...
    #   ... for satellite altitude in m. AND
    #   2) get_observer_look() gives correct answer ...
    #   ....  for satellite altitude in km. AND
    #   3) Satellite altitude is m.:
    #    => Satellite alltitude need to be converted to km.
    # else:
    #    => There have been updates to SatPy and this script
    #       need to be modified.
    if process_buggy_satellite_zenith_angles:
        print(" Making buggy satellite zenith angels on purpose!")
        sata, satel = get_observer_look(
            irch.attrs['orbital_parameters']['satellite_actual_longitude'],
            irch.attrs['orbital_parameters']['satellite_actual_latitude'],
            irch.attrs['orbital_parameters']['satellite_actual_altitude'],
            irch.attrs['start_time'], lons, lats, 0)
    elif (get_observer_look(0, 0, 36000 * 1000, datetime.utcnow(),
                            np.array([16]), np.array([58]), np.array(
                                [0]))[1] > 30
          and get_observer_look(0, 0, 36000, datetime.utcnow(), np.array([16]),
                                np.array([58]), np.array([0]))[1] < 23
          and irch.attrs['orbital_parameters']['satellite_actual_altitude'] >
          38000):
        sata, satel = get_observer_look(
            irch.attrs['orbital_parameters']['satellite_actual_longitude'],
            irch.attrs['orbital_parameters']['satellite_actual_latitude'],
            0.001 *
            irch.attrs['orbital_parameters']['satellite_actual_altitude'],
            irch.attrs['start_time'], lons, lats, 0)
    else:
        raise UnexpectedSatpyVersion(
            "You might have a newer version of satpy/pyorbital that"
            "handles units. In that case the m => km conversion might"
            "be unneeded and wrong.")

    satz = 90 - satel
    azidiff = make_azidiff_angle(sata, suna, -32767)
    #Add lat/lon  and angles datasets to the scen object
    my_coords = scn_['IR_108'].coords
    my_coords['time'] = irch.attrs['start_time']
    scn_['lat'] = xr.DataArray(da.from_array(lats, chunks=(53, 3712)),
                               dims=['y', 'x'],
                               coords={
                                   'y': scn_['IR_108']['y'],
                                   'x': scn_['IR_108']['x']
                               })
    scn_['lat'].attrs['long_name'] = 'latitude coordinate'
    scn_['lat'].attrs['standard_name'] = 'latitude'
    scn_['lat'].attrs['units'] = 'degrees_north'
    scn_['lat'].attrs['start_time'] = irch.attrs['start_time']
    scn_['lat'].attrs['end_time'] = irch.attrs['end_time']
    scn_['lon'] = xr.DataArray(da.from_array(lons, chunks=(53, 3712)),
                               dims=['y', 'x'],
                               coords={
                                   'y': scn_['IR_108']['y'],
                                   'x': scn_['IR_108']['x']
                               })
    scn_['lon'].attrs['long_name'] = 'longitude coordinate'
    scn_['lon'].attrs['standard_name'] = 'longitude'
    scn_['lon'].attrs['units'] = 'degrees_east'
    scn_['lon'].attrs['start_time'] = irch.attrs['start_time']
    scn_['lon'].attrs['end_time'] = irch.attrs['end_time']
    #sunzenith
    scn_['sunzenith'] = xr.DataArray(da.from_array(sunz[:, :],
                                                   chunks=(53, 3712)),
                                     dims=['y', 'x'],
                                     coords=my_coords)
    scn_['sunzenith'].attrs['id_tag'] = 'sunzenith'
    scn_['sunzenith'].attrs['long_name'] = 'sun zenith angle'
    scn_['sunzenith'].attrs['standard_name'] = 'solar_zenith_angle'
    scn_['sunzenith'].attrs['valid_range'] = [0, 18000]
    scn_['sunzenith'].attrs['name'] = "image{:d}".format(image_num)
    image_num += 1
    #satzenith
    scn_['satzenith'] = xr.DataArray(da.from_array(satz[:, :],
                                                   chunks=(53, 3712)),
                                     dims=['y', 'x'],
                                     coords=my_coords)
    scn_['satzenith'].attrs['id_tag'] = 'satzenith'
    scn_['satzenith'].attrs['long_name'] = 'satellite zenith angle'
    scn_['satzenith'].attrs['standard_name'] = 'platform_zenith_angle'
    scn_['satzenith'].attrs['valid_range'] = [0, 9000]
    scn_['satzenith'].attrs['name'] = "image{:d}".format(image_num)
    image_num += 1
    #azidiff
    scn_['azimuthdiff'] = xr.DataArray(da.from_array(azidiff[:, :],
                                                     chunks=(53, 3712)),
                                       dims=['y', 'x'],
                                       coords=my_coords)
    scn_['azimuthdiff'].attrs['id_tag'] = 'azimuthdiff'
    #scn_['azimuthdiff'].attrs['standard_name'] = (
    #    'angle_of_rotation_from_solar_azimuth_to_platform_azimuth')
    scn_['azimuthdiff'].attrs[
        'long_name'] = 'absoulte azimuth difference angle'
    scn_['azimuthdiff'].attrs['valid_range'] = [0, 18000]
    scn_['azimuthdiff'].attrs['name'] = "image{:d}".format(image_num)
    image_num += 1
    for angle in ['azimuthdiff', 'satzenith', 'sunzenith']:
        scn_[angle].attrs['units'] = 'degree'
        for attr in irch.attrs.keys():
            if attr in [
                    "start_time", "end_time", "navigation",
                    "georef_offset_corrected", "projection"
            ]:
                scn_[angle].attrs[attr] = irch.attrs[attr]

    #Get filename
    start_time = scn_['IR_108'].attrs['start_time']
    end_time = scn_['IR_108'].attrs['end_time']
    filename = os.path.join(
        out_path, "S_NWC_seviri_{:s}_{:s}_{:s}Z_{:s}Z.nc".format(
            platform_name.lower().replace('-', ''), "99999",
            start_time.strftime('%Y%m%dT%H%M%S%f')[:-5],
            end_time.strftime('%Y%m%dT%H%M%S%f')[:-5]))

    #Encoding for channels
    save_info = {}
    for band in BANDNAMES:
        idtag = PPS_TAGNAMES[band]
        name = scn_[band].attrs['name']
        scn_[band].attrs.pop('area', None)
        # Add time coordinate. To make cfwriter aware that we want 3D data.
        my_coords = scn_[band].coords
        my_coords['time'] = irch.attrs['start_time']

        if 'tb' in idtag:
            save_info[name] = {
                'dtype': 'int16',
                'scale_factor': 0.01,
                '_FillValue': -32767,
                'zlib': True,
                'complevel': 4,
                'add_offset': 273.15
            }
        else:
            save_info[name] = {
                'dtype': 'int16',
                'scale_factor': 0.01,
                'zlib': True,
                'complevel': 4,
                '_FillValue': -32767,
                'add_offset': 0.0
            }
    #Encoding for angles and lat/lon
    for name in ['image11', 'image12', 'image13']:
        save_info[name] = {
            'dtype': 'int16',
            'scale_factor': 0.01,
            'zlib': True,
            'complevel': 4,
            '_FillValue': -32767,
            'add_offset': 0.0
        }

    for name in ['lon', 'lat']:
        save_info[name] = {
            'dtype': 'float32',
            'zlib': True,
            'complevel': 4,
            '_FillValue': -999.0
        }
    header_attrs = scn_.attrs.copy()
    header_attrs['start_time'] = time.strftime(
        "%Y-%m-%d %H:%M:%S", irch.attrs['start_time'].timetuple())
    header_attrs['end_time'] = time.strftime(
        "%Y-%m-%d %H:%M:%S", irch.attrs['end_time'].timetuple())
    header_attrs['sensor'] = sensor.lower()
    header_attrs.pop('platform_name', None)

    scn_.save_datasets(writer='cf',
                       filename=filename,
                       header_attrs=header_attrs,
                       engine='netcdf4',
                       encoding=save_info,
                       include_lonlats=False,
                       pretty=True,
                       flatten_attrs=True,
                       exclude_attrs=['raw_metadata'])
    print("Saved file {:s} after {:3.1f} seconds".format(
        os.path.basename(filename),
        time.time() - tic))  #About 40 seconds
    return filename
示例#17
0
 def _get_sun_angles(self, vis, lons, lats):
     from pyorbital.astronomy import get_alt_az, sun_zenith_angle
     suna = get_alt_az(vis.attrs['start_time'], lons, lats)[1]
     suna = np.rad2deg(suna)
     sunz = sun_zenith_angle(vis.attrs['start_time'], lons, lats)
     return suna, sunz
def get_satellite_geometry(startDateUTC,
                           lengthDays,
                           lon,
                           lat,
                           alt=0.0,
                           mission="Sentinel-2a",
                           tleFile="/data/tle/norad_resource_tle.txt"):
    """Calculate approximate geometry for Sentinel overpasses.
    Approximate because it assumes maximum satellite elevation
    is the time at which target is imaged.

    :param startDateUTC: a datetime object specifying when to start prediction.
    :type startDateUTC: object
    :param lengthDays: number of days over which to perform calculations.
    :type lengthDays: int
    :param lat: latitude of target.
    :type lat: float
    :param lon: longitude of target.
    :type lon: float
    :param alt: altitude of target (in km).
    :type alt: float
    :param mission: mission name as in TLE file.
    :type mission: str
    :param tleFile: TLE file.
    :type tleFile: str
    :return: a python list containing instances of the sensorGeometry class arranged in date order.
    :rtype: list
    """
    orb = Orbital(mission, tleFile)
    passes = orb.get_next_passes(startDateUTC, 24 * lengthDays, lon, lat, alt)

    geom_inst = SensorGeometry()
    geom_inst.date_utc = []
    geom_inst.vza = []
    geom_inst.vaa = []
    geom_inst.sza = []
    geom_inst.saa = []

    for p in passes:
        look = orb.get_observer_look(p[2], lon, lat, alt)
        vza = 90 - look[1]
        vaa = look[0]
        sza = ast.sun_zenith_angle(p[2], lon, lat)
        saa = np.rad2deg(ast.get_alt_az(p[2], lon, lat)[1])

        if mission == 'Sentinel-1b':
            if 75 < vaa < 105 and 20. < vza < 45.:  # vaa usually [0, 180], testing observation times
                geom_inst.date_utc.append(p[2])
                geom_inst.vza.append(vza)
                geom_inst.vaa.append(vaa)
                geom_inst.sza.append(sza)
                geom_inst.saa.append(saa)
        elif mission == 'Sentinel-1a':
            if 75 < vaa < 105 and 20. < vza < 45.:  # vaa usually [0, 180], testing observation times
                geom_inst.date_utc.append(p[2])
                geom_inst.vza.append(vza)
                geom_inst.vaa.append(vaa)
                geom_inst.sza.append(sza)
                geom_inst.saa.append(saa)
        elif mission == 'Sentinel-2a':
            if sza < 90 and vza < 10.3:
                geom_inst.date_utc.append(p[2])
                geom_inst.vza.append(vza)
                geom_inst.vaa.append(vaa)
                geom_inst.sza.append(sza)
                geom_inst.saa.append(saa)

    return geom_inst