Newer
Older

Paolo Veglio
committed
import numpy as np

Paolo Veglio
committed
import ruamel_yaml as yml
from glob import glob
import read_data as rd

Paolo Veglio
committed
# lsf: land sea flag
_scene_list = ['ocean_day', 'ocean_night', 'land_day', 'land_night', 'snow_day', 'snow_night', 'coast_day',
'desert_day', 'antarctic_day', 'polar_day_snow', 'polar_day_desert', 'polar_day_ocean',

Paolo Veglio
committed
'polar_day_desert_coast', 'polar_day_coast', 'polar_day_land', 'polar_night_snow',
'polar_night_land', 'polar_night_ocean', 'land_day_desert_coast']

Paolo Veglio
committed
_flags = ['day', 'night', 'land', 'coast', 'sh_lake', 'sh_ocean', 'water', 'polar', 'sunglint',

Paolo Veglio
committed
'greenland', 'high_elevation', 'antarctica', 'desert', 'visusd', 'vrused', 'map_snow', 'map_ice',
'ndsi_snow', 'snow', 'ice', 'new_zealand']
# temp value, need to verify what the actual bad_data value is in the C code
_bad_data = -999.0

Paolo Veglio
committed

Paolo Veglio
committed
_dtr = np.pi/180.
_rtd = 180./np.pi

Paolo Veglio
committed
# I'm defining here the flags for difference scenes. Eventually I want to find a better way of doing this
land = 1

Paolo Veglio
committed
#coast = .2

Paolo Veglio
committed
sh_lake = .3
sh_ocean = .4
water = 5
polar = 60
sunglint = 70
day = 100
night = 200

Paolo Veglio
committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# #################################################################### #
# TEST CASE
# data:
datapath = '/ships19/hercules/pveglio/mvcm_viirs_hires'
fname_mod02 = glob(f'{datapath}/VNP02MOD.A2022173.1448.001.*.uwssec.nc')[0]
fname_mod03 = glob(f'{datapath}/VNP03MOD.A2022173.1448.001.*.uwssec.nc')[0]
fname_img02 = glob(f'{datapath}/VNP02IMG.A2022173.1448.001.*.uwssec.nc')[0]
fname_img03 = glob(f'{datapath}/VNP03IMG.A2022173.1448.001.*.uwssec.nc')[0]
# thresholds:
threshold_file = '/home/pveglio/mvcm_leo/thresholds/new_thresholds.mvcm.snpp.v1.0.0.yaml'
# ancillary files:
geos_atm_1 = 'GEOS.fpit.asm.inst3_2d_asm_Nx.GEOS5124.20220622_1500.V01.nc4'
geos_atm_2 = 'GEOS.fpit.asm.inst3_2d_asm_Nx.GEOS5124.20220622_1800.V01.nc4'
geos_land = 'GEOS.fpit.asm.tavg1_2d_lnd_Nx.GEOS5124.20220622_1630.V01.nc4'
geos_ocean = 'GEOS.fpit.asm.tavg1_2d_ocn_Nx.GEOS5124.20220622_1630.V01.nc4'
geos_constants = 'GEOS.fp.asm.const_2d_asm_Nx.00000000_0000.V01.nc4'
ndvi_file = 'NDVI.FM.c004.v2.0.WS.00-04.177.hdf'
sst_file = 'oisst.20220622'
eco_file = 'goge1_2_img.v1'
# #################################################################### #
def test_scene():
ancillary_file_names = {'GEOS_atm_1': geos_atm_1,
'GEOS_atm_2': geos_atm_2,
'GEOS_land': geos_land,
'GEOS_ocean': geos_ocean,
'GEOS_constants': geos_constants,
'NDVI': ndvi_file,
'SST': sst_file,
'ANC_DIR': f'{datapath}/ancillary'
}
viirs_data = rd.read_data('viirs', f'{fname_mod02}', f'{fname_mod03}')
viirs_data = rd.read_ancillary_data(ancillary_file_names, viirs_data)
with open(threshold_file) as f:
text = f.read()
thresholds = yml.safe_load(text)
sunglint_angle = thresholds['Sun_Glint']['bounds'][3]
scene = find_scene(viirs_data, sunglint_angle)
return scene

Paolo Veglio
committed

Paolo Veglio
committed
def find_scene(data, sunglint_angle):

Paolo Veglio
committed
eco = data['eco'].values
lsf = data['land_water_mask'].values
lat = data['latitude'].values
lon = data['longitude'].values
sza = data['solar_zenith'].values

Paolo Veglio
committed
vza = data['sensor_zenith'].values
raz = data['relative_azimuth'].values
b065 = data['M05'].values
b086 = data['M07'].values

Paolo Veglio
committed
elev = data['height'].values
ndvibk = data['ndvi'].values
sfctmp = data['geos_sfct'].values
dim1 = data.latitude.shape[0]
dim2 = data.latitude.shape[1]

Paolo Veglio
committed

Paolo Veglio
committed
day = np.zeros((dim1, dim2))
day[sza <= 85] = 1
cos_refang = np.sin(vza*_dtr) * np.sin(sza*_dtr) * np.cos(raz*_dtr) + np.cos(vza*_dtr) * np.cos(sza*_dtr)
refang = np.arccos(cos_refang) * _rtd

Paolo Veglio
committed

Paolo Veglio
committed
# tmp = np.ones((dim1, dim2))
# tmp[day == 1] = day
# tmp[day == 0] = night

Paolo Veglio
committed

Paolo Veglio
committed
scene_flag = {flg: np.zeros((dim1, dim2)) for flg in _flags}

Paolo Veglio
committed
scene_flag['day'][sza <= 85] = 1
scene_flag['visusd'][sza <= 85] = 1
scene_flag['night'][sza > 85] = 1

Paolo Veglio
committed
scene_flag['polar'][np.abs(lat) > 60] = 1
# ################# need to pass refang (once I figure out what it is) and sunglint_angle. The latter

Paolo Veglio
committed
# comes from the thresholds file. In the C code is snglnt_bounds[3]
idx = np.nonzero((scene_flag['day'] == 1) & (refang <= sunglint_angle))
scene_flag['sunglint'][idx] = 1
# Force consistency between lsf and ecosystem type for water
idx = np.nonzero((lsf == 0) | (lsf >= 5) & (lsf < 7))
eco[idx] = 14
# start by defining anythings as land

Paolo Veglio
committed
scene_flag['land'] = np.ones((dim1, dim2))
scene_flag['water'] = np.zeros((dim1, dim2))
# Fix-up for missing ecosystem data in eastern Greenland and north-eastern Siberia.
# Without this, these regions become completely "coast".
idx = np.nonzero((lsf != 255) & (lsf == 1) | (lsf == 4))
scene_flag['land'][idx] = 1

Paolo Veglio
committed
# idx = np.nonzero((lsf != 255) & (eco == 14))

Paolo Veglio
committed
idx = np.nonzero((lsf != 255) & (eco == 14) & (lsf == 1) | (lsf == 4) & (lat < 64.0))
scene_flag['coast'][idx] = 1

Paolo Veglio
committed
idx = np.nonzero((lsf != 255) & (eco == 14) & (lsf == 1) | (lsf == 4) &
(lat >= 67.5) & (lon < -40.0) & (lon > -168.6))
scene_flag['coast'][idx] = 1
idx = np.nonzero((lsf != 255) & (eco == 14) & (lsf == 1) | (lsf == 4) &
(lat >= 67.5) & (lon > -12.5))
scene_flag['coast'][idx] = 1

Paolo Veglio
committed
idx = np.nonzero((lsf != 255) & (eco == 14) & (lsf == 1) | (lsf == 4) &
(lat >= 64.0) & (lat < 67.5) & (lon < -40.0) & (lon > -168.5))
scene_flag['coast'][idx] = 1
idx = np.nonzero((lsf != 255) & (eco == 14) & (lsf == 1) | (lsf == 4) &
(lat >= 64.0) & (lat < 67.5) & (lon > -30.0))
scene_flag['coast'][idx] = 1
idx = np.nonzero(lsf == 2)
scene_flag['coast'][idx] = 1
scene_flag['land'][idx] = 1
idx = np.nonzero(lsf == 3)
scene_flag['land'][idx] = 1
scene_flag['sh_lake'][idx] = 1

Paolo Veglio
committed
idx = np.nonzero((lsf == 0) | (lsf >= 5) & (lsf <= 7))
scene_flag['water'][idx] = 1
scene_flag['land'][idx] = 0
scene_flag['sh_ocean'][lsf == 0] = 1
# Need shallow lakes to be processed as "coast" for day, but not night
idx = np.nonzero((lsf == 3) & (day == 1))
scene_flag['coast'][idx] = 1
# if land/sea flag is missing, then calculate visible ratio to determine if land or water.
idx = np.nonzero((lsf == 255) & (b065 != _bad_data) & (b086 != _bad_data) & (b086/b065 > 0.9))

Paolo Veglio
committed
scene_flag['land'][idx] = 1
idx = np.nonzero((lsf == 255) & (b065 != _bad_data) & (b086 != _bad_data) & (b086/b065 <= 0.9))

Paolo Veglio
committed
scene_flag['land'][idx] = 0
scene_flag['water'][idx] = 1
# Check surface elevation
# First, define "Greenland".
idx = np.nonzero((scene_flag['land'] == 1) &
(lat >= 60.0) & (lat < 67.0) & (lon >= -60.0) & (lon < -30.0))
scene_flag['greenland'][idx] = 1
idx = np.nonzero((scene_flag['land'] == 1) &
(lat >= 67.0) & (lat < 75.0) & (lon >= -60.0) & (lon < -10.0))
scene_flag['greenland'][idx] = 1
idx = np.nonzero((scene_flag['land'] == 1) &
(lat >= 75.0) & (lon >= -70.0) & (lon < -10.0))
scene_flag['greenland'][idx] = 1
scene_flag['high_elevation'][elev > 2000] = 1
idx = np.nonzero((elev > 200) & (scene_flag['greenland'] == 1) & (scene_flag['land'] == 1))
scene_flag['high_elevation'][idx] = 1
idx = np.nonzero((lat >= 75.0) & (lat <= 79.0) & (lon >= -73.0) & (lon <= -50.0) &
(scene_flag['land'] == 1))
scene_flag['high_elevation'][idx] = 1
scene_flag['antarctica'][lat < -60.0] = 1

Paolo Veglio
committed
##################################
# somewhere here I need to add #
# the 11um elevation correction #

Paolo Veglio
committed
##################################
# this is a temporary variable for the 11um elevation correction
elev_correction = elev/1000.0 * 5.0

Paolo Veglio
committed
## Get surface temperature from NWP and SST fields
## if it's land get it from GDAS/GEOS5
#sfctmp[scene_flag['land'] == 1] = sfct
## otherwise use the ReynoldsSST
#sfctmp[scene_flag['land'] == 0] = reynSST

Paolo Veglio
committed
# Use background NDVI to define "desert"
idx = np.nonzero((scene_flag['land'] == 1) & (ndvibk < 0.3))
scene_flag['desert'][idx] = 1
idx = np.nonzero((scene_flag['land'] == 1) & (lat < -69.0))
scene_flag['desert'][idx] = 1

Paolo Veglio
committed
idx = np.nonzero((eco == 2) | (eco == 8) | (eco == 11) | (eco == 40) | (eco == 41) | (eco == 46) |
(eco == 51) | (eco == 52) | (eco == 59) | (eco == 71) | (eco == 50))

Paolo Veglio
committed
scene_flag['vrused'] = np.ones((dim1, dim2))
scene_flag['vrused'][idx] = 0

Paolo Veglio
committed
snow_fraction = data['geos_snowfr']
perm_ice_fraction = data['geos_landicefr']
ice_fraction = data['geos_icefr']
idx = np.nonzero((snow_fraction > 0.10) & (snow_fraction <= 1.0))

Paolo Veglio
committed
scene_flag['map_snow'][idx] = 1
idx = np.nonzero((perm_ice_fraction > 0.10) & (perm_ice_fraction <= 1.0))
scene_flag['map_snow'][idx] = 1
idx = np.nonzero((ice_fraction > 0.10) & (ice_fraction <= 1.0))
scene_flag['map_ice'][idx] = 1
# need to define this function and write this block better

Paolo Veglio
committed
# if day == 1:
# # Run quick version of D. Hall's snow detection algorithm
# # Temporarily disabled because this function does not exist and I need to decide how to implement it
# # scene_flag['ndsi_snow'] = run_snow_mask()
# scene_flag['ndsi_snow'] = np.zeros((dim1, dim2))
idx = np.nonzero((day == 1) & (water == 1) & (lat >= -60.0) & (lat <= 25.0) &
(scene_flag['map_snow'] == 1) & (scene_flag['ndsi_snow'] == 1))
scene_flag['ice'][idx] = 1
idx = np.nonzero((day == 1) & (water == 1) & (lat < -60.0) &
(scene_flag['ndsi_snow'] == 1))
scene_flag['ice'][idx] = 1
idx = np.nonzero((day == 1) & (water == 1) & (lsf == 3) | (lsf == 5) &
(scene_flag['ndsi_snow'] == 1))
scene_flag['ice'][idx] = 1
idx = np.nonzero((day == 1) & (water == 1) &
(scene_flag['map_ice'] == 1) & (scene_flag['ndsi_snow'] == 1))
scene_flag['ice'][idx] = 1
# Define New Zealand region which receives snow but snow map does not show it.
idx = np.nonzero((day == 1) & (land == 1) &
(lat >= 48.0) & (lat <= -34.0) & (lon >= 165.0) & (lon <= 180.0))

Paolo Veglio
committed
scene_flag['new_zealand'][idx] = 1
idx = np.nonzero((day == 1) & (land == 1) & (lat >= -60.0) & (lat <= 25.0) &
(scene_flag['map_snow'] == 1) & (scene_flag['ndsi_snow'] == 1) |
(scene_flag['new_zealand'] == 1))
scene_flag['snow'][idx] = 1
idx = np.nonzero((day == 1) & (land == 1) & (lat < -60.0))

Paolo Veglio
committed
scene_flag['snow'][idx] = 1
idx = np.nonzero((day == 1) & (land == 1) & (scene_flag['ndsi_snow'] == 1))

Paolo Veglio
committed
scene_flag['snow'][idx] = 1
idx = np.nonzero((day == 0) & (scene_flag['map_snow'] == 1) &
(sfctmp > 280.0) & (elev < 500.0))
scene_flag['snow'][idx] = 0
idx = np.nonzero((day == 0) & (scene_flag['map_snow'] == 1) &
(sfctmp > 280.0) & (elev < 500.0))
scene_flag['ice'][idx] = 0
idx = np.nonzero((day == 0) & (lat > 86.0))

Paolo Veglio
committed
scene_flag['ice'][idx] = 1
##################################
# CONTINUE FROM HERE #
##################################

Paolo Veglio
committed
# Check regional uniformity
# Check for data border pixels
# NEED TO UNDERSTAND WHAT THIS PART DOES

Paolo Veglio
committed
# TEMP VALUES FOR DEBUGGING
scene_flag['lat'] = lat
scene_flag['lon'] = lon
return scene_flag

Paolo Veglio
committed
def scene_id(scene_flag):
dim1, dim2 = scene_flag['day'].shape[0], scene_flag['day'].shape[1]
scene = {scn: np.zeros((dim1, dim2)) for scn in _scene_list}

Paolo Veglio
committed
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# Ocean Day
idx = np.nonzero((scene_flag['water'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0) &
(scene_flag['polar'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['coast'] == 0) & (scene_flag['desert'] == 0))
scene['ocean_day'][idx] = 1
# Ocean Night
idx = np.nonzero((scene_flag['water'] == 1) & (scene_flag['night'] == 1) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0) &
(scene_flag['polar'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['coast'] == 0) & (scene_flag['desert'] == 0))
scene['ocean_night'][idx] = 1
# Land Day
idx = np.nonzero((scene_flag['land'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0) &
(scene_flag['polar'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['coast'] == 0) & (scene_flag['desert'] == 0))
scene['land_day'][idx] = 1
# Land Night
idx = np.nonzero((scene_flag['land'] == 1) & (scene_flag['night'] == 1) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0) &
(scene_flag['polar'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['coast'] == 0))
scene['land_night'][idx] = 1
# Snow Day
idx = np.nonzero((scene_flag['day'] == 1) &
((scene_flag['ice'] == 1) | (scene_flag['snow'] == 1)) &
(scene_flag['polar']) & (scene_flag['antarctica']))
scene['snow_day'][idx] = 1
# Snow Night
idx = np.nonzero((scene_flag['night'] == 1) &
((scene_flag['ice'] == 1) | (scene_flag['snow'] == 1)) &
(scene_flag['polar']) & (scene_flag['antarctica']))
scene['snow_night'][idx] = 1
# Land Day Coast
idx = np.nonzero((scene_flag['land'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['coast'] == 1) & (scene_flag['desert'] == 0) &
(scene_flag['polar'] == 0) & (scene_flag['antarctica'] == 0))
scene['land_day_coast'][idx] = 1
# Land Day Desert
idx = np.nonzero((scene_flag['land'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['desert'] == 1) & (scene_flag['coast'] == 0) &
(scene_flag['polar'] == 0) & (scene_flag['antarctica'] == 0))
scene['desert_day'][idx] = 1
# Land Day Desert Coast
idx = np.nonzero((scene_flag['land'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['desert'] == 1) & (scene_flag['coast'] == 1) &
(scene_flag['polar'] == 0) & (scene_flag['antarctica'] == 0))
scene['land_day_desert_coast'][idx] = 1
# Antarctic Day
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['antarctica'] == 1) & (scene_flag['land'] == 1))
scene['antarctic_day'][idx] = 1
# Polar Day Snow
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['day'] == 1) &
((scene_flag['snow'] == 1) | (scene_flag['ice'] == 1)) &
(scene_flag['antarctica'] == 0))
scene['polar_day_snow'][idx] = 1
# Polar Day Desert
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['land'] == 1) & (scene_flag['desert'] == 1) &
(scene_flag['coast'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0))
scene['polar_day_desert'][idx] = 1
# Polar Day Desert Coast
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['land'] == 1) & (scene_flag['desert'] == 1) &
(scene_flag['coast'] == 1) & (scene_flag['antarctica'] == 0) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0))
scene['polar_day_desert_coast'][idx] = 1
# Polar Day Coast
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['land'] == 1) & (scene_flag['coast'] == 1)
(scene_flag['desert'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0))
scene['polar_day_coast'][idx] = 1
# Polar Day Land
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['land'] == 1) & (scene_flag['coast'] == 0)
(scene_flag['desert'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0))
scene['polar_day_land'][idx] = 1
# Polar Day Ocean
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['day'] == 1) &
(scene_flag['water'] == 1) & (scene_flag['coast'] == 0)
(scene_flag['desert'] == 0) & (scene_flag['antarctica'] == 0) &
(scene_flag['ice'] == 0) & (scene_flag['snow'] == 0))
scene['polar_day_land'][idx] = 1
# Polar Night Snow
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['night'] == 1) &
((scene_flag['snow'] == 1) | (scene_flag['ice'] == 1)))
scene['polar_night_snow'][idx] = 1
# Polar Night Land
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['night'] == 1) &
(scene_flag['land'] == 1))
scene['polar_night_land'][idx] = 1
# Polar Night Ocean
idx = np.nonzero((scene_flag['polar'] == 1) & (scene_flag['night'] == 1) &
(scene_flag['water'] == 1))
scene['polar_night_ocean'][idx] = 1
return scene
scene['polar_day_ocean'][idx] = 1