Skip to content

Commit e7e5465

Browse files
Merge pull request #80 from ninahakansson/seviri_azimuth_angles
Add azimuth angles for SEVIRI
2 parents 78d2698 + 2532e58 commit e7e5465

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

bin/seviri2pps.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
help="Output directory where to store level1c file.")
5050
parser.add_argument('--no-rotation', action='store_true',
5151
help="Don't rotate images")
52+
parser.add_argument('--azimuth_angles', action='store_true',
53+
help="Save azimuth angles")
5254
parser.add_argument('-ne', '--nc_engine', type=str, nargs='?',
5355
required=False, default='h5netcdf',
5456
help="Engine for saving netcdf files netcdf4 or h5netcdf (default).")
@@ -64,5 +66,6 @@
6466
rotate=not options.no_rotation,
6567
engine=options.nc_engine,
6668
use_nominal_time_in_filename=options.use_nominal_time_in_filename,
67-
apply_sun_earth_distance_correction=not options.no_sun_earth_distance_correction
69+
apply_sun_earth_distance_correction=not options.no_sun_earth_distance_correction,
70+
save_azimuth_angles=options.azimuth_angles,
6871
)

level1c4pps/seviri2pps_lib.py

+32-6
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,11 @@ def _create_scene(file_format, filenames, calib_coefs):
137137

138138

139139
def _check_is_seviri_data(scene):
140-
if not scene.attrs['sensor'] == {'seviri'}:
140+
if hasattr(scene, 'sensor_names') and 'seviri' in scene.sensor_names:
141+
pass
142+
elif scene.attrs['sensor'] == {'seviri'}:
143+
pass
144+
else:
141145
raise ValueError('Not SEVIRI data')
142146

143147

@@ -322,6 +326,8 @@ def update_coords(scene):
322326

323327

324328
def add_ancillary_datasets(scene, lons, lats, sunz, satz, azidiff,
329+
suna, sata,
330+
save_azimuth_angles=False,
325331
chunks=(512, 3712)):
326332
"""Add ancillary datasets to the scene.
327333
@@ -375,6 +381,18 @@ def add_ancillary_datasets(scene, lons, lats, sunz, satz, azidiff,
375381
da.from_array(azidiff[:, :], chunks=chunks),
376382
dims=['y', 'x'], coords=angle_coords)
377383

384+
# Sunazimuth
385+
if save_azimuth_angles:
386+
scene['sunazimuth'] = xr.DataArray(
387+
da.from_array(suna[:, :], chunks=chunks),
388+
dims=['y', 'x'], coords=angle_coords)
389+
390+
# Satazimuth
391+
if save_azimuth_angles:
392+
scene['satazimuth'] = xr.DataArray(
393+
da.from_array(sata[:, :], chunks=chunks),
394+
dims=['y', 'x'], coords=angle_coords)
395+
378396
# Update the attributes
379397
update_angle_attributes(scene, band=scene['IR_108'])
380398

@@ -470,7 +488,7 @@ def get_encoding_seviri(scene):
470488
encoding['time'] = {'units': 'days since 2004-01-01 00:00',
471489
'calendar': 'standard',
472490
'_FillValue': None,
473-
'chunksizes': [1]}
491+
'chunksizes': (1,)}
474492

475493
return encoding
476494

@@ -564,7 +582,8 @@ def _postproc_hrit(self, parsed):
564582
def process_one_scan(tslot_files, out_path, rotate=True, engine='h5netcdf',
565583
use_nominal_time_in_filename=False,
566584
apply_sun_earth_distance_correction=True,
567-
clip_calib=False):
585+
clip_calib=False,
586+
save_azimuth_angles=False):
568587
"""Make level 1c files in PPS-format."""
569588
for fname in tslot_files:
570589
if not os.path.isfile(fname):
@@ -577,7 +596,9 @@ def process_one_scan(tslot_files, out_path, rotate=True, engine='h5netcdf',
577596
rotate=rotate,
578597
clip_calib=clip_calib
579598
)
580-
599+
if hasattr(scn_, 'start_time'):
600+
scn_.attrs['start_time'] = scn_.start_time
601+
scn_.attrs['end_time'] = scn_.end_time
581602
# Find lat/lon data
582603
lons, lats = get_lonlats(scn_['IR_108'])
583604

@@ -590,8 +611,12 @@ def process_one_scan(tslot_files, out_path, rotate=True, engine='h5netcdf',
590611
update_coords(scn_)
591612

592613
# Add ancillary datasets to the scene
593-
add_ancillary_datasets(scn_, lons=lons, lats=lats, sunz=sunz, satz=satz,
594-
azidiff=azidiff)
614+
add_ancillary_datasets(scn_,
615+
lons=lons, lats=lats,
616+
sunz=sunz, satz=satz,
617+
azidiff=azidiff,
618+
suna=suna, sata=sata,
619+
save_azimuth_angles=save_azimuth_angles)
595620
add_proj_satpos(scn_)
596621

597622
# Set attributes. This changes SEVIRI band names to PPS band names.
@@ -601,6 +626,7 @@ def process_one_scan(tslot_files, out_path, rotate=True, engine='h5netcdf',
601626
ir108_for_filename = scn_['IR_108']
602627
if use_nominal_time_in_filename:
603628
ir108_for_filename = set_nominal_scan_time(ir108_for_filename)
629+
604630
filename = compose_filename(
605631
scene=scn_,
606632
out_path=out_path,

level1c4pps/tests/test_seviri2pps.py

+21-6
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ def get_fake_scene():
4242
scene = Scene()
4343
start_time = dt.datetime(2020, 1, 1, 12)
4444
scene['VIS006'] = xr.DataArray(
45-
[[1, 2],
46-
[3, 4]],
45+
[[1.0, 2.0],
46+
[3.0, 4.0]],
4747
dims=('y', 'x'),
4848
attrs={'calibration': 'reflectance',
4949
'sun_earth_distance_correction_applied': True,
@@ -299,6 +299,8 @@ def test_add_ancillary_datasets(self):
299299
lats = np.array([[1.1, 2.1], [3.1, 4.1]])
300300
sunz = np.array([[1.2, 2.2], [3.2, 4.2]])
301301
satz = np.array([[1.3, 2.3], [3.3, 4.3]])
302+
suna = np.array([[5.2, 2.2], [5.2, 1.2]])
303+
sata = np.array([[3.3, 2.3], [3.3, 7.3]])
302304
azidiff = np.array([[1.4, 2.4], [3.4, 4.4]])
303305

304306
ir_108 = xr.DataArray(data=np.array([[0.1, 0.2], [0.3, 0.4]]),
@@ -310,9 +312,12 @@ def test_add_ancillary_datasets(self):
310312
'orbital_parameters': 'orb_params',
311313
'georef_offset_corrected': True})
312314
scene = {'IR_108': ir_108}
313-
seviri2pps.add_ancillary_datasets(scene, lons=lons, lats=lats,
315+
seviri2pps.add_ancillary_datasets(scene,
316+
lons=lons, lats=lats,
314317
sunz=sunz, satz=satz,
315-
azidiff=azidiff)
318+
azidiff=azidiff,
319+
suna=suna, sata=sata,
320+
save_azimuth_angles=True)
316321

317322
# Test lon/lat
318323
np.testing.assert_array_equal(scene['lon'].data, lons)
@@ -331,6 +336,12 @@ def test_add_ancillary_datasets(self):
331336
np.testing.assert_array_equal(scene['azimuthdiff'].data, azidiff)
332337
self.assertEqual(scene['azimuthdiff'].attrs['name'], 'azimuthdiff')
333338

339+
np.testing.assert_array_equal(scene['satazimuth'].data, sata)
340+
self.assertEqual(scene['satazimuth'].attrs['name'], 'satazimuth')
341+
342+
np.testing.assert_array_equal(scene['sunazimuth'].data, suna)
343+
self.assertEqual(scene['sunazimuth'].attrs['name'], 'sunazimuth')
344+
334345
for angle in ['azimuthdiff', 'satzenith', 'sunzenith']:
335346
self.assertTupleEqual(scene[angle].dims, ('y', 'x'))
336347
np.testing.assert_array_equal(scene[angle].coords['x'].data, xvals)
@@ -398,7 +409,7 @@ def test_get_encoding(self):
398409
enc_exp_time = {'units': 'days since 2004-01-01 00:00',
399410
'calendar': 'standard',
400411
'_FillValue': None,
401-
'chunksizes': [1]}
412+
'chunksizes': (1,)}
402413
enc_exp_acq = {'units': 'milliseconds since 2009-07-01 12:15',
403414
'calendar': 'standard',
404415
'_FillValue': -9999.0}
@@ -426,7 +437,11 @@ def test_get_encoding(self):
426437
'acq_time': enc_exp_acq
427438
}
428439
encoding = seviri2pps.get_encoding_seviri(scene)
429-
self.assertDictEqual(encoding, encoding_exp)
440+
for key in encoding_exp:
441+
print(key)
442+
print(encoding[key],encoding_exp[key])
443+
444+
self.assertDictEqual(encoding[key], encoding_exp[key])
430445

431446
def test_get_header_attrs(self):
432447
"""Test get the header attributes."""

0 commit comments

Comments
 (0)