Exemple #1
0
def navigate(timecodes, satellite):
    orb = Orbital(satellite)


    first_time = timecode(timecodes[0])
    first_time = datetime(first_time.year, first_time.month, first_time.day)

    hrpttimes = [timecode(x) - first_time for x in timecodes]
    hrpttimes = np.array([x.seconds + x.microseconds / 1000000.0
                          for x in hrpttimes])
    
    scan_points = np.arange(2048)
    if satellite == "noaa 16":
        scan_angle = 55.25
    else:
        scan_angle = 55.37
    scans_nb = len(hrpttimes)
    avhrr_inst = np.vstack(((scan_points / 1023.5 - 1)
                            * np.deg2rad(-scan_angle),
                            np.zeros((len(scan_points),)))).T
    avhrr_inst = np.tile(avhrr_inst, [scans_nb, 1])

    offset = hrpttimes

    times = (np.tile(scan_points * 0.000025, [scans_nb, 1])
             + np.expand_dims(offset, 1))

    sgeom = ScanGeometry(avhrr_inst, times.ravel())

    s_times = sgeom.times(first_time)

    rpy = (0, 0, 0)
    pixels_pos = compute_pixels((orb.tle._line1, orb.tle._line2), sgeom, s_times, rpy)
    pos_time = get_lonlatalt(pixels_pos, s_times)
    return pos_time
Exemple #2
0
def navigate(timecodes, satellite):
    orb = Orbital(satellite)

    first_time = timecode(timecodes[0])
    first_time = datetime(first_time.year, first_time.month, first_time.day)

    hrpttimes = [timecode(x) - first_time for x in timecodes]
    hrpttimes = np.array(
        [x.seconds + x.microseconds / 1000000.0 for x in hrpttimes])

    scan_points = np.arange(2048)
    if satellite == "noaa 16":
        scan_angle = 55.25
    else:
        scan_angle = 55.37
    scans_nb = len(hrpttimes)
    avhrr_inst = np.vstack(
        ((scan_points / 1023.5 - 1) * np.deg2rad(-scan_angle),
         np.zeros((len(scan_points), )))).T
    avhrr_inst = np.tile(avhrr_inst, [scans_nb, 1])

    offset = hrpttimes

    times = (np.tile(scan_points * 0.000025, [scans_nb, 1]) +
             np.expand_dims(offset, 1))

    sgeom = ScanGeometry(avhrr_inst, times.ravel())

    s_times = sgeom.times(first_time)

    rpy = (0, 0, 0)
    pixels_pos = compute_pixels((orb.tle._line1, orb.tle._line2), sgeom,
                                s_times, rpy)
    pos_time = get_lonlatalt(pixels_pos, s_times)
    return pos_time
Exemple #3
0
    def test_scan_geometry(self):
        """Test the ScanGeometry object.
        """
        scans_nb = 1

        xy = np.vstack((np.deg2rad(np.array([10, 0, -10])), np.array([0, 0,
                                                                      0])))
        xy = np.tile(xy[:, np.newaxis, :], [1, np.int(scans_nb), 1])

        times = np.tile([-0.1, 0, 0.1], [np.int(scans_nb), 1])

        instrument = ScanGeometry(xy, times)

        self.assertTrue(
            np.allclose(np.rad2deg(instrument.fovs[0]), np.array([[10, 0,
                                                                   -10]])))

        # Test vectors

        pos = np.rollaxis(np.tile(np.array([0, 0, 7000]), [3, 1, 1]), 2)
        vel = np.rollaxis(np.tile(np.array([1, 0, 0]), [3, 1, 1]), 2)
        pos = np.stack([np.array([0, 0, 7000])] * 3, 1)[:, np.newaxis, :]
        vel = np.stack([np.array([1, 0, 0])] * 3, 1)[:, np.newaxis, :]

        vec = instrument.vectors(pos, vel)

        self.assertTrue(np.allclose(np.array([[0, 0, -1]]), vec[:, 0, 1]))

        # minus sin because we use trigonometrical direction of angles

        self.assertTrue(
            np.allclose(
                np.array(
                    [[0, -np.sin(np.deg2rad(10)), -np.cos(np.deg2rad(10))]]),
                vec[:, 0, 0]))
        self.assertTrue(
            np.allclose(
                np.array(
                    [[0, -np.sin(np.deg2rad(-10)), -np.cos(np.deg2rad(-10))]]),
                vec[:, 0, 2]))

        # Test times

        start_of_scan = np.datetime64(datetime(2014, 1, 8, 11, 30))
        times = instrument.times(start_of_scan)

        self.assertEqual(times[0, 1], start_of_scan)
        self.assertEqual(times[0, 0],
                         start_of_scan - np.timedelta64(100, 'ms'))
        self.assertEqual(times[0, 2],
                         start_of_scan + np.timedelta64(100, 'ms'))
    def test_scan_geometry(self):
        """Test the ScanGeometry object.
        """
        scans_nb = 1

        xy = np.vstack((np.deg2rad(np.array([10, 0, -10])),
                        np.array([0, 0, 0])))
        xy = np.tile(xy[:, np.newaxis, :], [1, np.int(scans_nb), 1])

        times = np.tile([-0.1, 0, 0.1], [np.int(scans_nb), 1])

        instrument = ScanGeometry(xy, times)

        self.assertTrue(np.allclose(np.rad2deg(instrument.fovs[0]),
                                    np.array([[10, 0, -10]])))

        # Test vectors

        pos = np.rollaxis(np.tile(np.array([0, 0, 7000]), [3, 1, 1]), 2)
        vel = np.rollaxis(np.tile(np.array([1, 0, 0]), [3, 1, 1]), 2)
        pos = np.stack([np.array([0, 0, 7000])] * 3, 1)[:, np.newaxis, :]
        vel = np.stack([np.array([1, 0, 0])] * 3, 1)[:, np.newaxis, :]

        vec = instrument.vectors(pos, vel)

        self.assertTrue(np.allclose(np.array([[0, 0, -1]]),
                                    vec[:, 0, 1]))

        # minus sin because we use trigonometrical direction of angles

        self.assertTrue(np.allclose(np.array([[0,
                                               -np.sin(np.deg2rad(10)),
                                               -np.cos(np.deg2rad(10))]]),
                                    vec[:, 0, 0]))
        self.assertTrue(np.allclose(np.array([[0,
                                               -np.sin(np.deg2rad(-10)),
                                               -np.cos(np.deg2rad(-10))]]),
                                    vec[:, 0, 2]))

        # Test times

        start_of_scan = np.datetime64(datetime(2014, 1, 8, 11, 30))
        times = instrument.times(start_of_scan)

        self.assertEquals(times[0, 1], start_of_scan)
        self.assertEquals(times[0, 0], start_of_scan -
                          np.timedelta64(100, 'ms'))
        self.assertEquals(times[0, 2], start_of_scan +
                          np.timedelta64(100, 'ms'))
Exemple #5
0
def olci(scans_nb, scan_points=None):
    """Definition of the OLCI instrument.

    Source: Sentinel-3 OLCI Coverage
    https://sentinel.esa.int/web/sentinel/user-guides/sentinel-3-olci/coverage
    """

    if scan_points is None:
        scan_len = 4000  # samples per scan
        scan_points = np.arange(4000)
    else:
        scan_len = len(scan_points)
    # scan_rate = 0.044  # single scan, seconds
    scan_angle_west = 46.5  # swath, degrees
    scan_angle_east = -22.1  # swath, degrees
    # sampling_interval = 18e-3  # single view, seconds
    # build the olci instrument scan line angles
    scanline_angles = np.linspace(np.deg2rad(scan_angle_west),
                                  np.deg2rad(scan_angle_east), scan_len)
    inst = np.vstack((scanline_angles, np.zeros(scan_len, )))

    inst = np.tile(inst[:, np.newaxis, :], [1, np.int(scans_nb), 1])

    # building the corresponding times array
    # times = (np.tile(scan_points * 0.000025 + 0.0025415, [scans_nb, 1])
    #         + np.expand_dims(offset, 1))

    times = np.tile(np.zeros_like(scanline_angles), [np.int(scans_nb), 1])
    # if apply_offset:
    #     offset = np.arange(np.int(scans_nb)) * frequency
    #     times += np.expand_dims(offset, 1)

    return ScanGeometry(inst, times)
Exemple #6
0
def avhrr(scans_nb,
          scan_points,
          scan_angle=55.37,
          frequency=1 / 6.0,
          apply_offset=True):
    """Definition of the avhrr instrument.

    Source: NOAA KLM User's Guide, Appendix J
    http://www.ncdc.noaa.gov/oa/pod-guide/ncdc/docs/klm/html/j/app-j.htm
    """
    # build the avhrr instrument (scan angles)
    avhrr_inst = np.vstack(
        ((scan_points / 1023.5 - 1) * np.deg2rad(-scan_angle),
         np.zeros((len(scan_points), ))))

    avhrr_inst = np.tile(avhrr_inst[:, np.newaxis, :],
                         [1, np.int(scans_nb), 1])

    # building the corresponding times array
    # times = (np.tile(scan_points * 0.000025 + 0.0025415, [scans_nb, 1])
    #         + np.expand_dims(offset, 1))

    times = np.tile(scan_points * 0.000025, [np.int(scans_nb), 1])
    if apply_offset:
        offset = np.arange(np.int(scans_nb)) * frequency
        times += np.expand_dims(offset, 1)

    return ScanGeometry(avhrr_inst, times)
def viirs(scans_nb,
          scan_indices=slice(0, None),
          chn_pixels=6400,
          scan_lines=32,
          scan_step=1):
    """Describe VIIRS instrument geometry, I-band by default.
    VIIRS scans several lines simultaneously (there are 16 detectors for each
    M-band, 32 detectors for each I-band) so the scan angles (and times) are
    two-dimensional arrays, contrary to AVHRR for example.

    scan_step: The increment in number of scans. E.g. if scan_step is 100 and
               the number of scans (scans_nb) is 10 then these 10 scans are
               distributed over the swath so that between each scan there are
               99 emtpy (excluded) scans

    """

    entire_width = np.arange(chn_pixels)
    scan_points = entire_width[scan_indices.astype('int')]
    scan_pixels = len(scan_points)

    # Initial angle 55.84 deg replaced with 56.28 deg found in
    # VIIRS User's Guide from NESDIS, version 1.2 (09/10/2013).
    # Ref : NOAA Technical Report NESDIS 142.
    # Seems to be better (not quantified).
    across_track = \
        (scan_points / (chn_pixels / 2. - 0.5) - 1) * np.deg2rad(-56.28)
    y_max_angle = np.arctan2(11.87 / 2, 824.0)
    along_track = \
        -(np.arange(scan_lines) / (scan_lines / 2. - 0.5) - 1) * \
        y_max_angle
    scan = np.dstack(
        (np.tile(across_track,
                 (scan_lines, 1)).T, np.tile(along_track, (scan_pixels, 1))))
    npp = np.tile(scan, [scans_nb, 1]).T

    # from the timestamp in the filenames, a granule takes 1:25.400 to record
    # (85.4 seconds) so 1.779166667 would be the duration of 1 scanline (48
    # scans per granule) dividing the duration of a single scan by a width of
    # 6400 pixels results in 0.0002779947917 seconds for each column of 32
    # pixels in the scanline

    # the individual times per pixel are probably wrong, unless the scanning
    # behaves the same as for AVHRR, The VIIRS sensor rotates to allow internal
    # calibration before each scanline. This would imply that the scanline
    # always moves in the same direction.  more info @
    # http://www.eoportal.org/directory/pres_NPOESSNationalPolarorbitingOperationalEnvironmentalSatelliteSystem.html

    SEC_EACH_SCANCOLUMN = 0.0002779947917
    sec_scan_duration = 1.779166667
    times = np.tile(scan_points * SEC_EACH_SCANCOLUMN,
                    [np.int32(scans_nb * scan_lines), 1])
    offset = np.repeat(
        np.arange(scans_nb) * sec_scan_duration * scan_step, scan_lines)
    times += np.expand_dims(offset, 1)

    # build the scan geometry object
    return ScanGeometry(npp, times)
def mwhs2(scans_nb, scan_points=None):
    """Describe MWHS-2 instrument geometry

    The scanning period is 2.667 s. Main beams of the antenna scan over the ob-
    serving swath (±53.35◦ from nadir) in the cross-track direction at a
    constant time of 1.71 s. There are 98 pixels sampled per scan during 1.71s,
    and each sample has the same integration period.

    See:

       http://english.nssc.cas.cn/rh/rp/201501/W020150122580098790190.pdf

    Parameters:
       scans_nb | int -  number of scan lines

     Keywords:
     * scan_points - FIXME!

    Returns:
       pyorbital.geoloc.ScanGeometry object

    """

    scan_len = 98  # 98 samples per scan
    scan_rate = 8 / 3.  # single scan, seconds
    scan_angle = -53.35  # swath, degrees
    sampling_interval = (8 / 3. - 1) / 98.  # single view, seconds
    # sampling_interval = 17.449e-3  # single view, seconds
    sync_time = 0.0  # delay before the actual scan starts - don't know! FIXME!

    if scan_points is None:
        scan_points = np.arange(0, scan_len)

    # build the instrument (scan angles)
    samples = np.vstack(
        ((scan_points / (scan_len * 0.5 - 0.5) - 1) * np.deg2rad(scan_angle),
         np.zeros((len(scan_points), ))))
    samples = np.tile(samples[:, np.newaxis, :], [1, np.int32(scans_nb), 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * scan_rate
    times = (np.tile(scan_points * sampling_interval + sync_time,
                     [np.int32(scans_nb), 1]) + np.expand_dims(offset, 1))

    # # build the instrument (scan angles)
    # scan_angles = np.linspace(-np.deg2rad(scan_angle), np.deg2rad(scan_angle), scan_len)[scan_points]

    # samples = np.vstack((scan_angles, np.zeros(len(scan_points) * 1,)))
    # samples = np.tile(samples[:, np.newaxis, :], [1, np.int(scans_nb), 1])

    # # building the corresponding times array
    # offset = np.arange(scans_nb) * scan_rate
    # times = (np.tile(scan_points * sampling_interval, [np.int(scans_nb), 1])
    #          + np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(samples, times)
def mhs(scans_nb, scan_points=None):
    """ Describe MHS instrument geometry

    See:

    - https://www.eumetsat.int/website/home/Satellites/CurrentSatellites/Metop/MetopDesign/MHS/index.html
    - https://www1.ncdc.noaa.gov/pub/data/satellite/publications/podguides/
          N-15%20thru%20N-19/pdf/0.0%20NOAA%20KLM%20Users%20Guide.pdf
      (NOAA KLM Users Guide –August 2014 Revision)

    Parameters:
       scans_nb | int -  number of scan lines

     Keywords:
     * scan_points - FIXME!

    Returns:
       pyorbital.geoloc.ScanGeometry object

    """

    scan_len = 90  # 90 samples per scan
    scan_rate = 8 / 3.  # single scan, seconds
    scan_angle = -49.444  # swath, degrees
    sampling_interval = (8 / 3. - 1) / 90.  # single view, seconds
    sync_time = 0.0  # delay before the actual scan starts - don't know! FIXME!

    if scan_points is None:
        scan_points = np.arange(0, scan_len)

    # build the instrument (scan angles)
    samples = np.vstack(
        ((scan_points / (scan_len * 0.5 - 0.5) - 1) * np.deg2rad(scan_angle),
         np.zeros((len(scan_points), ))))
    samples = np.tile(samples[:, np.newaxis, :], [1, np.int32(scans_nb), 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * scan_rate
    times = (np.tile(scan_points * sampling_interval + sync_time,
                     [np.int32(scans_nb), 1]) + np.expand_dims(offset, 1))

    # scan_angles = np.linspace(-np.deg2rad(scan_angle), np.deg2rad(scan_angle), scan_len)[scan_points]

    # samples = np.vstack((scan_angles, np.zeros(len(scan_points) * 1,)))
    # samples = np.tile(samples[:, np.newaxis, :], [1, np.int(scans_nb), 1])

    # # building the corresponding times array
    # offset = np.arange(scans_nb) * scan_rate
    # times = (np.tile(scan_points * sampling_interval, [np.int(scans_nb), 1])
    #          + np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(samples, times)
Exemple #10
0
    def test_scan_geometry(self):
        """Test the ScanGeometry object.
        """
        instrument = ScanGeometry(
            np.deg2rad(np.array([[10, 0], [0, 0], [-10, 0]])),
            np.array([-0.1, 0, 0.1]))
        self.assertTrue(
            np.allclose(np.rad2deg(instrument.fovs[:, 0]),
                        np.array([10, 0, -10])))

        # Test vectors

        pos = np.array([[0, 0, 7000]]).T
        vel = np.array([[1, 0, 0]]).T
        vec = instrument.vectors(pos, vel)
        self.assertTrue(np.allclose(np.array([[0, 0, -1]]), vec[:, 1]))

        # minus sin because we use trigonometrical direction of angles

        self.assertTrue(
            np.allclose(
                np.array(
                    [[0, -np.sin(np.deg2rad(10)), -np.cos(np.deg2rad(10))]]),
                vec[:, 0]))
        self.assertTrue(
            np.allclose(
                np.array(
                    [[0, -np.sin(np.deg2rad(-10)), -np.cos(np.deg2rad(-10))]]),
                vec[:, 2]))

        # Test times

        start_of_scan = datetime(2014, 1, 8, 11, 30)
        times = instrument.times(start_of_scan)
        self.assertEqual(times[1], start_of_scan)
        self.assertEqual(times[0], start_of_scan - timedelta(seconds=0.1))
        self.assertEqual(times[2], start_of_scan + timedelta(seconds=0.1))
Exemple #11
0
    def test_scan_geometry(self):
        """Test the ScanGeometry object.
        """
        instrument = ScanGeometry(np.deg2rad(np.array([[10, 0],
                                                       [0, 0],
                                                       [-10, 0]])),
                                  np.array([-0.1, 0, 0.1]))
        self.assertTrue(np.allclose(np.rad2deg(instrument.fovs[:, 0]),
                                    np.array([10, 0, -10])))

        # Test vectors
        
        pos = np.array([[0, 0, 7000]]).T
        vel = np.array([[1, 0, 0]]).T
        vec = instrument.vectors(pos, vel)
        self.assertTrue(np.allclose(np.array([[0, 0, -1]]),
                                    vec[:, 1]))

        # minus sin because we use trigonometrical direction of angles
        
        self.assertTrue(np.allclose(np.array([[0,
                                               -np.sin(np.deg2rad(10)),
                                               -np.cos(np.deg2rad(10))]]),
                                    vec[:, 0]))
        self.assertTrue(np.allclose(np.array([[0,
                                               -np.sin(np.deg2rad(-10)),
                                               -np.cos(np.deg2rad(-10))]]),
                                    vec[:, 2]))

        # Test times

        start_of_scan = datetime(2014, 1, 8, 11, 30)
        times = instrument.times(start_of_scan)
        self.assertEquals(times[1], start_of_scan)
        self.assertEquals(times[0], start_of_scan - timedelta(seconds=0.1))
        self.assertEquals(times[2], start_of_scan + timedelta(seconds=0.1))
Exemple #12
0
def viirs(scans_nb,
          scan_indices=slice(0, None),
          chn_pixels=6400,
          scan_lines=32):
    """Describe VIIRS instrument geometry, I-band by default.
    VIIRS scans several lines simultaneously (there are 16 detectors for each
    M-band, 32 detectors for each I-band) so the scan angles (and times) are
    two-dimensional arrays, contrary to AVHRR for example.
    """

    entire_width = np.arange(chn_pixels)
    scan_points = entire_width[scan_indices]
    scan_pixels = len(scan_points)
    ''' initial angle 55.84 deg replaced with 56.28 deg found in
    VIIRS User's Guide from NESDIS, version 1.2 (09/10/2013).
    Ref : NOAA Technical Report NESDIS 142.
    Seems to be better (not quantified)'''
    across_track = \
        (scan_points / (chn_pixels / 2. - 0.5) - 1) * np.deg2rad(-56.28)
    y_max_angle = np.arctan2(11.87 / 2, 824.0)
    along_track = \
        -(np.arange(scan_lines) / (scan_lines / 2. - 0.5) - 1) * \
        y_max_angle
    scan = np.dstack(
        (np.tile(across_track,
                 (scan_lines, 1)).T, np.tile(along_track, (scan_pixels, 1))))
    npp = np.tile(scan, [scans_nb, 1]).T

    # from the timestamp in the filenames, a granule takes 1:25.400 to record
    # (85.4 seconds) so 1.779166667 would be the duration of 1 scanline
    # dividing the duration of a single scan by a width of 6400 pixels results
    # in 0.0002779947917 seconds for each column of 32 pixels in the scanline

    # the individual times per pixel are probably wrong, unless the scanning
    # behaves the same as for AVHRR, The VIIRS sensor rotates to allow internal
    # calibration before each scanline. This would imply that the scanline
    # always moves in the same direction.  more info @
    # http://www.eoportal.org/directory/pres_NPOESSNationalPolarorbitingOperationalEnvironmentalSatelliteSystem.html

    offset = np.arange(scans_nb) * 1.779166667
    times = (np.tile(scan_points * 0.0002779947917,
                     [np.int(scan_lines), np.int(scans_nb)]) +
             np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(npp, times)
Exemple #13
0
def atms(scans_nb, edges_only=False):
    """ Describe MHS instrument geometry
    See:

    - https://dtcenter.org/com-GSI/users/docs/presentations/2013_workshop/
          Garrett_GSI_2013.pdf (Assimilation of Suomi-NPP ATMS, Kevin Garrett et al., August 8, 2013)
    - https://www.star.nesdis.noaa.gov/star/documents/meetings/2016JPSSAnnual/
          S4/S4_13_JPSSScience2016_session4Part2_ATMS_Scan_Reversal_HYANG.pdf
          (Suomi NPP ATMS Scan Reversal Study, Hu (Tiger) Yang, NOAA/STAR ATMS SDR Working Group)

    Parameters:
       scans_nb | int -  number of scan lines

     Keywords:
     * edges_only - use only edge pixels

    Returns:
       pyorbital.geoloc.ScanGeometry object

    """

    scan_len = 96  # 96 samples per scan
    scan_rate = 8 / 3.  # single scan, seconds
    scan_angle = -52.7  # swath, degrees
    sampling_interval = 18e-3  # single view, seconds

    if edges_only:
        scan_points = np.array([0, scan_len - 1])
    else:
        scan_points = np.arange(0, scan_len)

    # build the instrument (scan angles)
    samples = np.vstack(
        ((scan_points / (scan_len * 0.5 - 0.5) - 1) * np.deg2rad(scan_angle),
         np.zeros((len(scan_points), ))))
    samples = np.tile(samples[:, np.newaxis, :], [1, np.int(scans_nb), 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * scan_rate
    times = (np.tile(scan_points * sampling_interval, [np.int(scans_nb), 1]) +
             np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(samples, times)
Exemple #14
0
def mhs(scans_nb, edges_only=False):
    """ Describe MHS instrument geometry

    See:

    - https://www.eumetsat.int/website/home/Satellites/CurrentSatellites/Metop/MetopDesign/MHS/index.html
    - https://www1.ncdc.noaa.gov/pub/data/satellite/publications/podguides/
          N-15%20thru%20N-19/pdf/0.0%20NOAA%20KLM%20Users%20Guide.pdf
      (NOAA KLM Users Guide –August 2014 Revision)

    Parameters:
       scans_nb | int -  number of scan lines

     Keywords:
     * edges_only - use only edge pixels

    Returns:
       pyorbital.geoloc.ScanGeometry object

    """

    scan_len = 90  # 90 samples per scan
    scan_rate = 8 / 3.  # single scan, seconds
    scan_angle = -49.444  # swath, degrees
    sampling_interval = (8 / 3. - 1) / 90.  # single view, seconds

    if edges_only:
        scan_points = np.array([0, scan_len - 1])
    else:
        scan_points = np.arange(0, scan_len)

    # build the instrument (scan angles)
    samples = np.vstack(
        ((scan_points / (scan_len * 0.5 - 0.5) - 1) * np.deg2rad(scan_angle),
         np.zeros((len(scan_points), ))))
    samples = np.tile(samples[:, np.newaxis, :], [1, np.int(scans_nb), 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * scan_rate
    times = (np.tile(scan_points * sampling_interval, [np.int(scans_nb), 1]) +
             np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(samples, times)
def hirs4(scans_nb, scan_points=None):
    """Describe HIRS/4 instrument geometry.

    See:
    - https://www.eumetsat.int/website/home/Satellites/CurrentSatellites/Metop/MetopDesign/HIRS/index.html
    - https://www1.ncdc.noaa.gov/pub/data/satellite/publications/podguides/
          N-15%20thru%20N-19/pdf/0.0%20NOAA%20KLM%20Users%20Guide.pdf
      (NOAA KLM Users Guide –August 2014 Revision)

    Parameters:
       scans_nb | int -  number of scan lines

     Keywords:
     * scan_points - FIXME!

    Returns:
       pyorbital.geoloc.ScanGeometry object

    """

    scan_len = 56  # 56 samples per scan
    scan_rate = 6.4  # single scan, seconds
    scan_angle = -49.5  # swath, degrees
    sampling_interval = abs(scan_rate) / scan_len  # single view, seconds

    if scan_points is None:
        scan_points = np.arange(0, scan_len)

    # build the instrument (scan angles)
    samples = np.vstack(
        ((scan_points / (scan_len * 0.5 - 0.5) - 1) * np.deg2rad(scan_angle),
         np.zeros((len(scan_points), ))))
    samples = np.tile(samples[:, np.newaxis, :], [1, np.int32(scans_nb), 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * scan_rate
    times = (
        np.tile(scan_points * sampling_interval, [np.int32(scans_nb), 1]) +
        np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(samples, times)
Exemple #16
0
def avhrr(scans_nb, scan_points, scan_angle=55.37, decimate=1):
    """Definition of the avhrr instrument.

    Source: NOAA KLM User's Guide, Appendix J
    http://www.ncdc.noaa.gov/oa/pod-guide/ncdc/docs/klm/html/j/app-j.htm
    """
    # build the avhrr instrument (scan angles)
    avhrr_inst = np.vstack(
        ((scan_points / 1023.5 - 1) * np.deg2rad(-scan_angle),
         np.zeros((len(scan_points), )))).transpose()
    avhrr_inst = np.tile(avhrr_inst, [scans_nb, 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * decimate / 6.0
    #times = (np.tile(scan_points * 0.000025 + 0.0025415, [scans_nb, 1])
    #         + np.expand_dims(offset, 1))
    times = (np.tile(scan_points * 0.000025, [scans_nb, 1]) +
             np.expand_dims(offset, 1))

    return ScanGeometry(avhrr_inst, times.ravel())
Exemple #17
0
def ascat(scan_nb, scan_points=None):
    """ASCAT make two scans one to the left and one to the right of the
    sub-satellite track.

    """

    if scan_points is None:
        scan_len = 42  # samples per scan
        scan_points = np.arange(42)
    else:
        scan_len = len(scan_points)

    scan_angle_inner = -25.0  # swath, degrees
    scan_angle_outer = -53.0  # swath, degrees
    scan_rate = 3.74747474747  # single scan, seconds
    if scan_len < 2:
        raise ValueError("Need at least two scan points!")

    sampling_interval = scan_rate / float(np.max(scan_points) + 1)

    # build the Metop/ascat instrument scan line angles
    scanline_angles_one = np.linspace(-np.deg2rad(scan_angle_outer),
                                      -np.deg2rad(scan_angle_inner), 21)
    scanline_angles_two = np.linspace(np.deg2rad(scan_angle_inner),
                                      np.deg2rad(scan_angle_outer), 21)

    scan_angles = np.concatenate([scanline_angles_one,
                                  scanline_angles_two])[scan_points]

    inst = np.vstack((scan_angles, np.zeros(scan_len * 1, )))
    inst = np.tile(inst[:, np.newaxis, :], [1, np.int(scan_nb), 1])

    # building the corresponding times array
    offset = np.arange(scan_nb) * scan_rate

    times = (np.tile(scan_points * sampling_interval, [np.int(scan_nb), 1]) +
             np.expand_dims(offset, 1))

    return ScanGeometry(inst, times)
Exemple #18
0
def amsua(scans_nb, edges_only=False):
    """ Describe AMSU-A instrument geometry
    
    Parameters:
       scans_nb | int -  number of scan lines
     
     Keywords:
     * edges_only - use only edge pixels

    Returns:
       pyorbital.geoloc.ScanGeometry object
    
    """

    scan_len = 30  # 30 samples per scan
    scan_rate = 8  # single scan, seconds
    scan_angle = -48.3  # swath, degrees
    sampling_interval = 0.2  # single view, seconds
    sync_time = 0.00355  # delay before the actual scan starts

    if edges_only:
        scan_points = np.array([0, scan_len - 1])
    else:
        scan_points = np.arange(0, scan_len)

    # build the instrument (scan angles)
    samples = np.vstack(
        ((scan_points / (scan_len * 0.5 - 0.5) - 1) * np.deg2rad(scan_angle),
         np.zeros((len(scan_points), )))).transpose()
    samples = np.tile(samples, [scans_nb, 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * scan_rate
    times = (
        np.tile(scan_points * sampling_interval + sync_time, [scans_nb, 1]) +
        np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(samples, times.ravel())
Exemple #19
0
def avhrr_gac(scan_times, scan_points,
              scan_angle=55.37, frequency=0.5):
    """Definition of the avhrr instrument, gac version

    Source: NOAA KLM User's Guide, Appendix J
    http://www.ncdc.noaa.gov/oa/pod-guide/ncdc/docs/klm/html/j/app-j.htm
    """
    try:
        offset = np.array([(t - scan_times[0]).seconds +
                           (t - scan_times[0]).microseconds / 1000000.0 for t in scan_times])
    except TypeError:
        offset = np.arange(scan_times) * frequency
    scans_nb = len(offset)
    # build the avhrr instrument (scan angles)
    avhrr_inst = np.vstack(((scan_points / 1023.5 - 1)
                            * np.deg2rad(-scan_angle),
                            np.zeros((len(scan_points),)))).transpose()
    avhrr_inst = np.tile(avhrr_inst, [scans_nb, 1])

    # building the corresponding times array
    times = (np.tile(scan_points * 0.000025, [scans_nb, 1])
             + np.expand_dims(offset, 1))
    return ScanGeometry(avhrr_inst, times.ravel())
def amsua(scans_nb, scan_points=None):
    """ Describe AMSU-A instrument geometry

    Parameters:
       scans_nb | int -  number of scan lines

     Keywords:
     * scan_points - FIXME!

    Returns:
       pyorbital.geoloc.ScanGeometry object

    """

    scan_len = 30  # 30 samples per scan
    scan_rate = 8  # single scan, seconds
    scan_angle = -48.3  # swath, degrees
    sampling_interval = 0.2  # single view, seconds
    sync_time = 0.00355  # delay before the actual scan starts

    if scan_points is None:
        scan_points = np.arange(0, scan_len)

    # build the instrument (scan angles)
    samples = np.vstack(
        ((scan_points / (scan_len * 0.5 - 0.5) - 1) * np.deg2rad(scan_angle),
         np.zeros((len(scan_points), ))))
    samples = np.tile(samples[:, np.newaxis, :], [1, np.int32(scans_nb), 1])

    # building the corresponding times array
    offset = np.arange(scans_nb) * scan_rate
    times = (np.tile(scan_points * sampling_interval + sync_time,
                     [np.int32(scans_nb), 1]) + np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(samples, times)
Exemple #21
0
def viirs(scans_nb, scan_indices=slice(0, None)):
    """Describe VIIRS instrument geometry, I-band.

    """

    entire_width = np.arange(6400)
    scan_points = entire_width[scan_indices]

    across_track = (scan_points / 3199.5 - 1) * np.deg2rad(-55.84)
    y_max_angle = np.arctan2(11.87 / 2, 824.0)
    along_track = np.array([-y_max_angle, 0, y_max_angle])

    scan_pixels = len(scan_points)

    scan = np.vstack((np.tile(across_track,
                              scan_pixels), np.repeat(along_track, 6400))).T

    npp = np.tile(scan, [scans_nb, 1])

    # from the timestamp in the filenames, a granule takes 1:25.400 to record
    # (85.4 seconds) so 1.779166667 would be the duration of 1 scanline
    # dividing the duration of a single scan by a width of 6400 pixels results
    # in 0.0002779947917 seconds for each column of 32 pixels in the scanline

    # the individual times per pixel are probably wrong, unless the scanning
    # behaves the same as for AVHRR, The VIIRS sensor rotates to allow internal
    # calibration before each scanline. This would imply that the scanline
    # always moves in the same direction.  more info @
    # http://www.eoportal.org/directory/pres_NPOESSNationalPolarorbitingOperationalEnvironmentalSatelliteSystem.html

    offset = np.arange(scans_nb) * 1.779166667
    times = (np.tile(scan_points * 0.0002779947917, [scans_nb, scan_pixels]) +
             np.expand_dims(offset, 1))

    # build the scan geometry object
    return ScanGeometry(npp, times.ravel())
Exemple #22
0
# we take only every 40th point for plotting clarity
scan_points = np.arange(24, 2048, 40)


# build the avhrr instrument (scan angles)
avhrr = np.vstack(((scan_points - 1023.5) / 1024 * np.deg2rad(-55.37),
                   np.zeros((len(scan_points),)))).transpose()
avhrr = np.tile(avhrr, [scanline_nb, 1])

# building the corresponding times array
offset = np.arange(scanline_nb) * 0.1666667
times = (np.tile(scan_points * 0.000025 + 0.0025415, [scanline_nb, 1])
         + np.expand_dims(offset, 1))

# build the scan geometry object
sgeom = ScanGeometry(avhrr, times.ravel())

# roll, pitch, yaw in radians
rpy = (0, 0, 0)

# print the lonlats for the pixel positions
s_times = sgeom.times(t)
pixels_pos = compute_pixels((tle1, tle2), sgeom, s_times, rpy)
pos_time = get_lonlatalt(pixels_pos, s_times)

print pos_time


# Plot the result
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
# we take only every 40th point for plotting clarity
scan_points = np.arange(24, 2048, 40)

# build the avhrr instrument (scan angles)
avhrr = np.vstack(((scan_points - 1023.5) / 1024 * np.deg2rad(-55.37),
                   np.zeros((len(scan_points), )))).transpose()
avhrr = np.tile(avhrr, [scanline_nb, 1])

# building the corresponding times array
offset = np.arange(scanline_nb) * 0.1666667
times = (np.tile(scan_points * 0.000025 + 0.0025415, [scanline_nb, 1]) +
         np.expand_dims(offset, 1))

# build the scan geometry object
sgeom = ScanGeometry(avhrr, times.ravel())

# roll, pitch, yaw in radians
rpy = (0, 0, 0)

# print the lonlats for the pixel positions
s_times = sgeom.times(t)
pixels_pos = compute_pixels((tle1, tle2), sgeom, s_times, rpy)
pos_time = get_lonlatalt(pixels_pos, s_times)

print(pos_time)

# Plot the result
m = Basemap(projection='stere',
            llcrnrlat=24,
            urcrnrlat=70,