def _get_view_zenith(scn, obs_lon, obs_lat): """ helper function to compute the view zenith angle to a observed lat/lon point (at zero altitude) for the given satellite. The satellite position is stored within the satpy Scene object, so we get the required info from the scn metadata. Note this only works after the true_color composite is loaded. """ obs_datetime = scn.attrs['start_time'] obs_alt = 0.0 # orbital parameters are stored in different keys for # GOES and Himawari; first branch is the GOES version. if 'orbital_parameters' in scn['true_color'].attrs: orb_pars = scn['true_color'].attrs['orbital_parameters'] sat_lon = orb_pars['satellite_nominal_longitude'] sat_lat = orb_pars['satellite_nominal_latitude'] sat_alt = orb_pars['satellite_nominal_altitude'] else: sat_lon = scn['true_color'].attrs['satellite_longitude'] sat_lat = 0.0 sat_alt = scn['true_color'].attrs['satellite_altitude'] # in scn object, this is units [m], need [km] for pyorbital function. sat_alt *= 1e-3 # get_observer_look expects array like inputs; if we put sat_lon inside # a 1-element list, everything gets broadcast to that shape. _, view_el = get_observer_look([sat_lon], sat_lat, sat_alt, obs_datetime, obs_lon, obs_lat, obs_alt) # convert back to scalar while changing from elevation to zenith. view_zenith = 90 - view_el[0] return view_zenith
def __call__(self, projectables, optional_datasets=None, **info): """Get the atmospherical correction. Uses pyspectral. """ from pyspectral.atm_correction_ir import AtmosphericalCorrection band = projectables[0] if optional_datasets: satz = optional_datasets[0] else: from pyorbital.orbital import get_observer_look lons, lats = band.attrs['area'].get_lonlats_dask(CHUNK_SIZE) try: dummy, satel = get_observer_look( band.attrs['satellite_longitude'], band.attrs['satellite_latitude'], band.attrs['satellite_altitude'], band.attrs['start_time'], lons, lats, 0) except KeyError: raise KeyError('Band info is missing some meta data!') satz = 90 - satel del satel LOG.info('Correction for limb cooling') corrector = AtmosphericalCorrection(band.attrs['platform_name'], band.attrs['sensor']) atm_corr = corrector.get_correction(satz, band.attrs['name'], band) proj = band - atm_corr proj.attrs = band.attrs self.apply_modifier_info(band, proj) return proj
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
def test_basic_numpy(self): """Test with numpy array inputs""" from pyorbital import orbital azi, elev = orbital.get_observer_look(self.sat_lon, self.sat_lat, self.sat_alt, self.t, self.lon, self.lat, self.alt) np.testing.assert_allclose(azi, self.exp_azi) np.testing.assert_allclose(elev, self.exp_elev)
def _get_sensor_angles_ndarray(lons, lats, start_time, sat_lon, sat_lat, sat_alt) -> np.ndarray: with ignore_invalid_float_warnings(): sata, satel = get_observer_look( sat_lon, sat_lat, sat_alt / 1000.0, # km start_time, lons, lats, 0) satz = 90 - satel return np.stack([sata, satz])
def get_satellite_angles(dataset, lons, lats): """Compute satellite angles. Returns: Satellite azimuth angle, Satellite zenith angle in degrees """ sat_lon, sat_lat, sat_alt = satpy.utils.get_satpos(dataset) # Double check that pyorbital/satpy behave as expected (satpy returning # altitude in meters and pyorbital expecting km). # # if: # 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 not (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 sat_alt > 38000): raise UnexpectedSatpyVersion( 'Unexpected handling of satellite altitude in pyorbital/' 'satpy. Conversion to km is probably unneeded and wrong.') # Convert altitude from meters to kilometers, as expected by the # current version of pyorbital sat_alt *= 0.001 # Compute angles sata, satel = get_observer_look(sat_lon, sat_lat, sat_alt, dataset.attrs['start_time'], lons, lats, 0) satz = 90 - satel return sata, satz
def _get_sensor_angles(self, vis, lons, lats): from pyorbital.orbital import get_observer_look 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
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
def test_basic_dask(self): """Test with dask array inputs""" from pyorbital import orbital import dask.array as da sat_lon = da.from_array(self.sat_lon, chunks=2) sat_lat = da.from_array(self.sat_lat, chunks=2) sat_alt = da.from_array(self.sat_alt, chunks=2) lon = da.from_array(self.lon, chunks=2) lat = da.from_array(self.lat, chunks=2) alt = da.from_array(self.alt, chunks=2) azi, elev = orbital.get_observer_look(sat_lon, sat_lat, sat_alt, self.t, lon, lat, alt) np.testing.assert_allclose(azi.compute(), self.exp_azi) np.testing.assert_allclose(elev.compute(), self.exp_elev)
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 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
def test_xarray_with_numpy(self): """Test with xarray DataArray with numpy array as inputs""" from pyorbital import orbital import xarray as xr def _xarr_conv(input): return xr.DataArray(input) sat_lon = _xarr_conv(self.sat_lon) sat_lat = _xarr_conv(self.sat_lat) sat_alt = _xarr_conv(self.sat_alt) lon = _xarr_conv(self.lon) lat = _xarr_conv(self.lat) alt = _xarr_conv(self.alt) azi, elev = orbital.get_observer_look(sat_lon, sat_lat, sat_alt, self.t, lon, lat, alt) np.testing.assert_allclose(azi.data, self.exp_azi) np.testing.assert_allclose(elev.data, self.exp_elev)
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
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
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
def test_xarray_with_dask(self): """Test with xarray DataArray with dask array as inputs""" from pyorbital import orbital import dask.array as da import xarray as xr def _xarr_conv(input): return xr.DataArray(da.from_array(input, chunks=2)) sat_lon = _xarr_conv(self.sat_lon) sat_lat = _xarr_conv(self.sat_lat) sat_alt = _xarr_conv(self.sat_alt) lon = _xarr_conv(self.lon) lat = _xarr_conv(self.lat) alt = _xarr_conv(self.alt) azi, elev = orbital.get_observer_look(sat_lon, sat_lat, sat_alt, self.t, lon, lat, alt) np.testing.assert_allclose(azi.data.compute(), self.exp_azi) np.testing.assert_allclose(elev.data.compute(), self.exp_elev)
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
def __call__(self, projectables, optional_datasets=None, **info): """Get the atmospherical correction. Uses pyspectral. """ from pyspectral.atm_correction_ir import AtmosphericalCorrection band = projectables[0] if optional_datasets: satz = optional_datasets[0] else: from pyorbital.orbital import get_observer_look lons, lats = band.attrs['area'].get_lonlats( chunks=band.data.chunks) sat_lon, sat_lat, sat_alt = get_satpos(band) try: dummy, satel = get_observer_look( sat_lon, sat_lat, sat_alt / 1000.0, # km band.attrs['start_time'], lons, lats, 0) except KeyError: raise KeyError('Band info is missing some meta data!') satz = 90 - satel del satel logger.info('Correction for limb cooling') corrector = AtmosphericalCorrection(band.attrs['platform_name'], band.attrs['sensor']) atm_corr = corrector.get_correction(satz, band.attrs['name'], band) proj = xr.DataArray(atm_corr, attrs=band.attrs, dims=band.dims, coords=band.coords) self.apply_modifier_info(band, proj) return proj
def __call__(self, projectables, optional_datasets=None, **info): """Get the atmospherical correction. Uses pyspectral. """ from pyspectral.atm_correction_ir import AtmosphericalCorrection band = projectables[0] if optional_datasets: satz = optional_datasets[0] else: from pyorbital.orbital import get_observer_look lons, lats = band.attrs['area'].get_lonlats_dask(CHUNK_SIZE) try: dummy, satel = get_observer_look(band.attrs['satellite_longitude'], band.attrs[ 'satellite_latitude'], band.attrs[ 'satellite_altitude'], band.attrs['start_time'], lons, lats, 0) except KeyError: raise KeyError( 'Band info is missing some meta data!') satz = 90 - satel del satel LOG.info('Correction for limb cooling') corrector = AtmosphericalCorrection(band.attrs['platform_name'], band.attrs['sensor']) atm_corr = corrector.get_correction(satz, band.attrs['name'], band) proj = band - atm_corr proj.attrs = band.attrs self.apply_modifier_info(band, proj) return proj
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
def read2h5(self, infile): # 主程序 # print(infile) try: f = h5py.File(infile, 'r') except: errordir = os.path.dirname(infile) + os.sep + 'error' if not os.path.exists(errordir): os.makedirs(errordir) errors = glob.glob(infile[0:-3] + '*') for error in errors: shutil.move(error, errordir + os.sep + os.path.basename(error)) return # 输出文件名 millisecond = f['Millisecond/Millisecond'][()] hour = np.min(millisecond) // (1000 * 60 * 60) minute = (np.min(millisecond) - hour * (1000 * 60 * 60)) // (1000 * 60) second = (np.min(millisecond) - hour * (1000 * 60 * 60) - minute * 1000 * 60) // (1000) time1 = datetime.datetime(int('20' + os.path.basename(infile)[6:8]), 1, 1) + \ datetime.timedelta(days=int(os.path.basename(infile)[8:11]) - 1) + \ datetime.timedelta(hours=int(hour)) + datetime.timedelta(minutes=int(minute)) + \ datetime.timedelta(seconds=int(second)) hour = np.max(millisecond) // (1000 * 60 * 60) minute = (np.max(millisecond) - hour * (1000 * 60 * 60)) // (1000 * 60) second = (np.max(millisecond) - hour * (1000 * 60 * 60) - minute * 1000 * 60) // (1000) time2 = datetime.datetime(int('20' + os.path.basename(infile)[6:8]), 1, 1) + \ datetime.timedelta(days=int(os.path.basename(infile)[8:11]) - 1) + \ datetime.timedelta(hours=int(hour)) + datetime.timedelta(minutes=int(minute)) + \ datetime.timedelta(seconds=int(second)) # del millisecond tree = ET.ElementTree(file=infile[0:-2] + 'xml') root = tree.getroot() node = root[0].find("OrbitNumber") outfile = os.path.dirname(infile) + os.sep + 'H1A_OPER_OCT_L1B_' + time1.strftime("%Y%m%dT%H%M%S") + '_' + \ time2.strftime("%Y%m%dT%H%M%S") + '_' + node.text + '_10.h5' if os.access(outfile, os.R_OK): return outfile f_new = h5py.File(outfile, 'a') # Calibration calibration = f_new.create_group('Calibration') data = np.zeros((10, 1)) calibration.create_dataset('Calibration Coefficients Offsets factor', (data.shape[0], data.shape[1]), dtype='f', data=data) del data data = np.ones((10, 1)) calibration.create_dataset('Calibration Coefficients Scale factor', (data.shape[0], data.shape[1]), dtype='f', data=data) del data data = np.ones((10, 1)) calibration.create_dataset('Mirror-side Correction Scale Factors', (data.shape[0], 1), dtype='f', data=data[:, 0]) data = np.zeros((10, 1)) calibration.create_dataset('Mirror-side Correction Offsets Factors', (data.shape[0], 1), dtype='f', data=data[:, 0]) del data data = np.zeros((10, 1)) calibration.create_dataset('Time-dependent Correction Constant Terms', (data.shape[0], data.shape[1]), dtype='f', data=data) del data data = np.ones((10, 1)) calibration.create_dataset( 'Time-dependent Correction Linear Coefficients', (data.shape[0], data.shape[1]), dtype='f', data=data) del data data = np.ones((10, 1)) calibration.create_dataset( 'Time-dependent Correction Quadratic Coefficients', (data.shape[0], data.shape[1]), dtype='f', data=data) del data data = np.array([[1], [1], [1], [1], [1], [1], [1], [1]]) calibration.create_dataset('Vicarious Calibration gan factor', (data.shape[0], data.shape[1]), dtype='f', data=data) del data calibration.attrs['Calibration Entry Year'] = np.int16(2019) calibration.attrs['Calibration Entry Day'] = np.int16(330) calibration.attrs['Calibration Reference Year'] = np.int16(0) calibration.attrs['Calibration Reference Day'] = np.int16(0) calibration.attrs['Calibration Reference Minute'] = np.int32(0) calibration.attrs['Visible Channel Radiance Data Unit'] = np.string_( 'mWcm-2 um-1 sr-1') calibration.attrs['Infrared Channel Radiance Data Unit'] = np.string_( 'mWcm-2 um-1 sr-1') # geophysical Data group = f_new.create_group('Geophysical Data') for j, dataset_of_group in enumerate(f['Scan image data'].items()): dataset = group.create_dataset(dataset_of_group[0], dataset_of_group[1].shape, dtype=np.float32, data=dataset_of_group[1][()]) dataset.attrs['Unit'] = np.string_('None') dataset.attrs['long_name'] = np.string_('Top of Atmosphere B' + dataset_of_group[0][2:] + 'nm/um radiance counts') del group, dataset # Extra Data group = f_new.create_group('Extra Data') Ext_xxx = [ '412', '443', '490', '520', '565', '670', '750', '865', '11', '12' ] try: L0file = glob.glob( os.path.dirname(infile) + os.sep + os.path.basename(infile)[0:-6] + 'L0.bz2')[0] L0 = L0parase() data = L0.run_this_function(L0file) # print('LA') except: data = np.zeros(shape=(10, dataset_of_group[1].shape[0], 43)) for j, ext_x in enumerate(Ext_xxx): ext = group.create_dataset('Ext_' + ext_x, (data.shape[1], 43), dtype='uint16', data=data[j, :, :]) if len(ext_x) == 2: ext.attrs['long_name'] = np.string_('B' + ext_x + 'um Extra data counts') else: ext.attrs['long_name'] = np.string_('B' + ext_x + 'nm Extra data counts') del group, ext # navigaton data group = f_new.create_group('Navigation Data') # 计算四个角度 # ======================================================================================================================= lat = f['Pixels location data/latitude'][()] lon = f['Pixels location data/longitude'][()] millisecond = f['Millisecond/Millisecond'][()] # year = np.ones(shape=lat.shape) * int('20' + os.path.basename(infile)[6:8]) # # year= np.array([[2003,2003],[2003,2004]]) # # month=np.array([[1,2],[6,12]]) # # day=np.array([[2,16],[14,2]]) # DOY = np.ones(shape=lat.shape) * int(os.path.basename(infile)[8:11]) # # millisecond = np.repeat(millisecond, 102, axis=1) # # hour = np.array([[1, 2], [3, 4]]) # hour = np.trunc(millisecond / 1000 / 3600) # minu = np.trunc((millisecond - hour * 1000 * 3600) / 1000 / 60) # sec = (millisecond - hour * 1000 * 3600 - minu * 1000 * 60) / 1000 # # minu=np.array([[23,23],[23,22]]) # # sec=np.array([[1,2],[24,55]]) # # TimeZone = np.trunc((lon - np.sign(lon) * 7.5) / 15 + np.sign(lon)) # # # N0 sitar=θ # N0 = 79.6764 + 0.2422 * (year - 1985) - np.trunc((year - 1985) / 4.0) # sitar = 2 * np.pi * (DOY - N0) / 365.2422 # ED1 = 0.3723 + 23.2567 * np.sin(sitar) + 0.1149 * np.sin(2 * sitar) - 0.1712 * np.sin( # 3 * sitar) - 0.758 * np.cos( # sitar) + 0.3656 * np.cos(2 * sitar) + 0.0201 * np.cos(3 * sitar) # ED = ED1 * np.pi / 180 # ED本身有符号 # # dLon = (lon - TimeZone * 15.0) * np.sign(lon) # # # 时差 # Et = 0.0028 - 1.9857 * np.sin(sitar) + 9.9059 * np.sin(2 * sitar) - 7.0924 * np.cos(sitar) - 0.6882 * np.cos( # 2 * sitar) # gtdt1 = hour + minu / 60.0 + sec / 3600.0 + dLon / 15 # 地方时 # gtdt = gtdt1 + Et / 60.0 # dTimeAngle1 = 15.0 * (gtdt - 12) # dTimeAngle = dTimeAngle1 * np.pi / 180 # latitudeArc = lat * np.pi / 180 # # # 高度角计算公式 # HeightAngleArc = np.arcsin( # np.sin(latitudeArc) * np.sin(ED) + np.cos(latitudeArc) * np.cos(ED) * np.cos(dTimeAngle)) # # 方位角计算公式 # CosAzimuthAngle = (np.sin(HeightAngleArc) * np.sin(latitudeArc) - np.sin(ED)) / np.cos(HeightAngleArc) / np.cos( # latitudeArc) # AzimuthAngleArc = np.arccos(CosAzimuthAngle) # HeightAngle = HeightAngleArc * 180 / np.pi # sza = 90 - HeightAngle # AzimuthAngle1 = AzimuthAngleArc * 180 / np.pi # saa = 180 + AzimuthAngle1 * np.sign(dTimeAngle) # ======================================================================================================================== # 使用pysolar计算sza saa time = [*map( lambda t: datetime.datetime(int('20' + os.path.basename(infile)[6:8]), 1, 1, tzinfo=datetime.timezone.utc) + \ datetime.timedelta(days=(int(os.path.basename(infile)[8:11]) - 1)) + \ datetime.timedelta(milliseconds=t[0]), millisecond.tolist())] time = np.repeat(np.array(time).reshape(-1, 1), 102, axis=1) time = time.flatten() lat = lat.flatten() lon = lon.flatten() sza = np.array([ *map(lambda sx, sy, t: 90 - get_altitude(sx, sy, t), lat, lon, time) ]) sza = sza.reshape(-1, 102) saa = np.array( [*map(lambda sx, sy, t: get_azimuth(sx, sy, t), lat, lon, time)]) saa = saa.reshape(-1, 102) # sza = np.array([*map(lambda x, y, t: 90.0 - get_altitude(x, y, t), lat, lon, time)]).reshape(-1, 102) # saa = np.array([*map(lambda x, y, t: get_azimuth(x, y, t), lat, lon, time)]).reshape(-1, 102) center_lat = f['Center Latitude/Center Latitude'][()] center_lon = f['Center Longitude/Center Longitude'][()] center_lat = np.repeat(center_lat, 102, axis=1) center_lon = np.repeat(center_lon, 102, axis=1) center_lat = center_lat.flatten() center_lon = center_lon.flatten() # pyorbital.orbital.get_observer_look(sat_lon, sat_lat, sat_alt, utc_time, lon, lat, alt) view_angle = np.array([ *map( lambda sx, sy, t, x, y: orbital.get_observer_look( np.atleast_1d(sx), np.atleast_1d(sy), np.atleast_1d(798), t, np.atleast_1d(x), np.atleast_1d(y), np.atleast_1d(0)), center_lon, center_lat, time, lon, lat) ]) vaa = (view_angle[:, 0]).reshape(-1, 102) vza = (90 - view_angle[:, 1]).reshape(-1, 102) lon = lon.reshape(-1, 102) lat = lat.reshape(-1, 102) parameters = [lon, lat, sza, saa, vza, vaa] parameter_ID = [ 'Longitude', 'Latitude', 'Solar Zenith Angle', 'Solar Azimuth Angle', 'Satellite Zenith Angle', 'Satellite Azimuth Angle' ] for ID, parameter in enumerate(parameters): nl = np.arange(parameter.shape[0]) # 当经度跨过180度经线时, if parameter_ID[ID] == 'Longitude': if parameter.max() - parameter.min() > 300: # 跨180经度时 parameter[parameter < 0] = parameter[ parameter < 0] + 360.0 # 180经线两边数值连续,以正确插值 parameter_inter = np.array( [*map(lambda n: self.interp(parameter[n, :]), nl)]) parameter_inter[parameter_inter > 180] = parameter_inter[ parameter_inter > 180] - 360.0 # 变回来 group.create_dataset( parameter_ID[ID], (parameter_inter.shape[0], parameter_inter.shape[1]), dtype=np.float32, data=parameter_inter) continue # 经度无需再写 # 按行计算 parameter_inter = np.array( [*map(lambda n: self.interp(parameter[n, :]), nl)]) group.create_dataset( parameter_ID[ID], (parameter_inter.shape[0], parameter_inter.shape[1]), dtype='f', data=parameter_inter) group.attrs['Navigation Point Counts'] = np.int32( parameter_inter.shape[1]) group.attrs['First Navigation Points'] = np.int32(1) group.attrs['Pixel-intervals of Navigation Point'] = np.int32(1) del group, parameters # QC Attributes group = f_new.create_group('QC Attributes') parameters = ['Staturated Pixel Counts', 'Zero Pixel Counts'] data = f['Saturated Pixels/Saturated Pixels'][()] group.create_dataset('Staturated Pixel Counts', (data.shape[0], data.shape[1]), dtype='uint16', data=data) data = f['Zero Pixels/Zero Pixels'][()] group.create_dataset('Zero Pixel Counts', (data.shape[0], data.shape[1]), dtype='uint16', data=data) group.attrs['Missing Frame Counts'] = np.int32(0) del group, data # Scan Line Attributes group = f_new.create_group('Scan Line Attributes') # data = (f.select('Attitude Parameters')).get() # group.create_dataset('Attitude Parameters', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) # del data data = f['Center Latitude/Center Latitude'][()] group.create_dataset('Center Latitude', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) del data data = f['Center Latitude/Center Latitude'][()] group.create_dataset('Center Longitude', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) del data data = f['Center Solar Zenith/Center Solar Zenith'][()] group.create_dataset('Center Solar Zenith Angle', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) del data data = f['Start Latitude/Start Latitude'][()] group.create_dataset('Start Latitude', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) del data data = f['Start Longitude/Start Longitude'][()] group.create_dataset('Start Longitude', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) del data data = f['End Latitude/End Latitude'][()] group.create_dataset('End Latitude', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) del data data = f['End Longitude/End Longitude'][()] group.create_dataset('End Longitude', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) frame = (np.arange(data.shape[0])) % 8 frame.shape = (frame.shape[0], 1) group.create_dataset('Frame Number', (frame.shape[0], frame.shape[1]), dtype='int16', data=frame) del data # data = (f.select('Infrared Channel Calibration Data')).get() # group.create_dataset('Infrared Channel Calibration Data', (data.shape[0], data.shape[1], data.shape[2]), # dtype=type(data[0][0][0]), data=data) # del data data = f['Millisecond/Millisecond'][()] millisecond = group.create_dataset('Millisecond', (data.shape[0], data.shape[1]), dtype=np.float64, data=data) millisecond.attrs['Fillin_value'] = -999.0 millisecond.attrs['Unit'] = np.string_( 'milliseconds since at 00:00:00 on this day ') del data # data = (f.select('Mirror-side Flag')).get() # # group.create_dataset('Mirror-side Flag', (data.shape[0], data.shape[1]), dtype='|S1', data=data) # # del data # no ORB_VEC dataset in HDF # data = (f.select('ORB_VEC')).get() # group.create_dataset('ORB_VEC', (data.shape[0], data.shape[1]), dtype=type(data[0][0]), data=data) # del data group.attrs['Instrument Parameters'] = np.string_( '412nm,443nm,490nm,520nm,565nm,670nm,750nm,865nm,10.3-11.4um,' '11.5-12.5um') # file attributes f_new.attrs.create('Calibration Flag', 'None', shape=(1, ), dtype='S10') f_new.attrs.create('Calibration Version', '1.00', shape=(1, ), dtype='S10') f_new.attrs.create('DayorNight', 'D', shape=(1, ), dtype='S10') distance = 1 - 0.01672 * np.cos( 0.9856 * (int(os.path.basename(infile)[8:11]) - 4)) f_new.attrs.create('Earth-Sun Distance', distance, shape=(1, ), dtype=np.float32) f_new.attrs.create('Easternmost Longitude', np.max(lon), shape=(1, ), dtype=np.float32) f_new.attrs.create('End Center Longitude', center_lon[-1], shape=(1, ), dtype=np.float32) f_new.attrs.create('End Center Latitude', center_lat[-1], shape=(1, ), dtype=np.float32) f_new.attrs.create('GEO Correction Method', 'Unkonwn', shape=(1, ), dtype='S10') f_new.attrs.create('Input File', os.path.basename(infile), shape=(1, ), dtype='S10') f_new.attrs.create('Latitude Unit', 'degree', shape=(1, ), dtype='S10') f_new.attrs.create('Longitude Unit', 'degree', shape=(1, ), dtype='S10') f_new.attrs.create('Lower Left Latitude', lat[-1, 0], shape=(1, ), dtype=np.float32) f_new.attrs.create('Lower Left Longitude', lon[-1, 0], shape=(1, ), dtype=np.float32) f_new.attrs.create('Lower Right Latitude', lat[-1, -1], shape=(1, ), dtype=np.float32) f_new.attrs.create('Lower Right Longitude', lon[-1, -1], shape=(1, ), dtype=np.float32) node = root[0].find("NodeCrossingTime") time = datetime.datetime(int('20' + node.text[0:2]), 1, 1) + datetime.timedelta(days=int(node.text[2:5]) - 1) + \ datetime.timedelta(hours=int(node.text[5:7])) + datetime.timedelta(minutes=int(node.text[7:9])) f_new.attrs.create('Node Crossing Time', time.strftime("%Y-%m-%dT%H-%M-%S"), shape=(1, ), dtype='S10') f_new.attrs.create('Northernmost Latitude', np.max(lat), shape=(1, ), dtype=np.float32) f_new.attrs.create('Number of Bands', 16, shape=(1, ), dtype=np.int16) f_new.attrs.create('Number of Scan Lines', f['Scan image data/L_412'].shape[0], shape=(1, ), dtype=np.int32) f_new.attrs.create('Orbit Node Longitude', root[0].find("OrbitNodeLongitude").text, shape=(1, ), dtype=np.float32) f_new.attrs.create('Orbit Number', root[0].find("OrbitNumber").text, shape=(1, ), dtype=np.int32) f_new.attrs.create('Pixels Per Scan Line', 1024, shape=(1, ), dtype=np.int32) f_new.attrs.create('Processing Center', 'NSOAS', shape=(1, ), dtype='S10') f_new.attrs.create('Processing Control', 'IMG', shape=(1, ), dtype='S10') f_new.attrs.create( 'Processing Time', datetime.datetime.now().strftime("%Y-%m-%dT%H-%M-%S"), shape=(1, ), dtype='S10') f_new.attrs.create('Product Name', os.path.basename(outfile), shape=(1, ), dtype='S10') f_new.attrs.create('Radiometric Method', 'unknown', shape=(1, ), dtype='S10') day = datetime.datetime(int('20' + os.path.basename(infile)[6:8]), 1, 1) + \ datetime.timedelta(days=int(os.path.basename(infile)[8:11]) - 1) f_new.attrs.create('Range Beginning Date', day.strftime("%Y%m%d") + ' ' + os.path.basename(infile)[8:11], shape=(1, ), dtype='S10') f_new.attrs.create('Range Ending Date', day.strftime("%Y%m%d") + ' ' + os.path.basename(infile)[8:11], shape=(1, ), dtype='S10') hour = np.min(millisecond) % (1000 * 60 * 60) minute = (np.min(millisecond) - hour * (1000 * 60 * 60)) % (1000 * 60) second = (np.min(millisecond) - hour * (1000 * 60 * 60) - minute * 1000 * 60) / (1000) f_new.attrs.create('Range Beginning Time', str(hour) + ':' + str(minute) + ':' + str(second), shape=(1, ), dtype='S10') hour = np.max(millisecond) // (1000 * 60 * 60) minute = (np.max(millisecond) - hour * (1000 * 60 * 60)) // (1000 * 60) second = (np.max(millisecond) - hour * (1000 * 60 * 60) - minute * 1000 * 60) // (1000) f_new.attrs.create('Range Ending Time', str(hour) + ':' + str(minute) + ':' + str(second), shape=(1, ), dtype='S10') f_new.attrs.create('Realtime Delay Flag', 'Unknown', shape=(1, ), dtype='S10') f_new.attrs.create('Receiving End Time', 'Unknown', shape=(1, ), dtype='S10') f_new.attrs.create('Receiving Start Time', 'Unknown', shape=(1, ), dtype='S10') f_new.attrs.create('Ref Band Number', 6, shape=(1, ), dtype=np.int32) node = root[0].find("MissionCharacter") f_new.attrs.create('Satellite Character', node.text, shape=(1, ), dtype='S10') f_new.attrs.create('Satellite Name', 'HY-1A', shape=(1, ), dtype='S10') node = root[0].find("SceneCenterLatitude") f_new.attrs.create('Sence Center Latitude', node.text, shape=(1, ), dtype=np.float32) node = root[0].find("SceneCenterLongitude") f_new.attrs.create('Sence Center Longitude', node.text, shape=(1, ), dtype=np.float32) node = root[0].find("SceneCenterSolarZenith") f_new.attrs.create('Sence Center Solar Zenith', node.text, shape=(1, ), dtype=np.float32) node = root[0].find("SceneCenterTime") time = datetime.datetime(int('20' + node.text[0:2]), 1, 1) + datetime.timedelta(days=int(node.text[2:5]) - 1) + \ datetime.timedelta(hours=int(node.text[5:7])) + datetime.timedelta(minutes=int(node.text[7:9])) f_new.attrs.create('Sence Center Solar Time', time.strftime("%Y-%m-%dT%H-%M-%S"), shape=(1, ), dtype='S10') f_new.attrs.create('Sensor Mode', 'Unknown', shape=(1, ), dtype='S10') f_new.attrs.create( 'Sensor Name', 'COCTS, Chinese Ocean Color and Temperature Scanner', shape=(1, ), dtype='S10') f_new.attrs.create('Sensor Pitch Element', 'Unknown', shape=(1, ), dtype='S10') f_new.attrs.create('Sensor Yaw Element', 'Unknown', shape=(1, ), dtype='S10') f_new.attrs.create('Software Version', '01.00', shape=(1, ), dtype='S10') f_new.attrs.create('Southernmost Latitude', np.min(lat), shape=(1, ), dtype=np.float32) f_new.attrs.create('Start Center Longitude', center_lon[0], shape=(1, ), dtype=np.float32) f_new.attrs.create('Start Center Latitude', center_lat[0], shape=(1, ), dtype=np.float32) f_new.attrs.create('TLE', '', shape=(1, ), dtype='S10') f_new.attrs.create( 'The Parameters of Sensor Characteristics', '412nm,443nm,490nm,520nm,565nm,670nm,750nm,865nm,10.3-11.4um,' '11.5-12.5um', shape=(1, ), dtype='S10') f_new.attrs.create('Title', 'HY-1A OCT Level-1B', shape=(1, ), dtype='S10') f_new.attrs.create('Upper Left Latitude', lat[0, 0], shape=(1, ), dtype=np.float32) f_new.attrs.create('Upper Left Longitude', lon[0, 0], shape=(1, ), dtype=np.float32) f_new.attrs.create('Upper Right Latitude', lat[0, -1], shape=(1, ), dtype=np.float32) f_new.attrs.create('Upper Right Longitude', lon[0, -1], shape=(1, ), dtype=np.float32) f_new.attrs.create('Westernmost Longitude', np.min(lon), shape=(1, ), dtype=np.float32) f.close() f_new.close() return outfile
#------------------------------------------------------------------------------------------------------ # 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. suna = suna % 360. ssadiff = np.absolute(suna - sata) ssadiff = np.minimum(ssadiff, 360 - ssadiff)