#!/usr/bin/env python3
############################################################################################
# Satellite: Feng-Yun 3D Sensor: MERSI-2
#------------------------------------------------------------------------
#
# Hilversum , 2022/04/09 License GPL3 (c) Rob Alblas (Ernst Lobsiger)
#
#************************************************************************
############################################################################################
import sys
import os
import argparse
from glob import glob
from satpy import Scene, MultiScene
from pyorbital.orbital import Orbital
from datetime import datetime, timedelta
from satpy_ecast_rts import toodrp,datdrp,pos,sat
from satpy_ecast_rts import collect_files,get_files,select_files,create_scene
from satpy_ecast_rts import Set_Gen,Set_Overlay,ofile_name
from satpy_ecast_rts import set_lonlat,create_pic,magick_string,list_areas
from satpy_ecast_rts import set_orbit
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# ********** ADAPT THESE PARAMETERS TO YOUR PERSONAL NEEDS ***********
def def_segdir(Date):
Yea=Date[:4]
Mon=Date[4:6]
Day=Date[6:8]
segdir = '/srv/rec_1/E1H-RDS-2' + '/' + Yea + '/' + Mon + '/' + Day
return segdir
# ******** TOUCH THE CODE BELOW ONLY IF YOU KNOW WHAT YOU DO *********
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
############################################################################################
# Files: like FY3D_20220301_151300_151400_22247_MERSI_GEO1K_L1B.HDF
# FY3D_20220301_152700_152800_22247_MERSI_1000M_L1B.HDF
# 0123456789012345678901234
def load_filetbl(files1,files2,ext1,ext2):
ofiles=[]
for fn in files1:
gn = fn[:-1*len(ext1)] + ext2
if gn in files2: # file with both extensions should exist
fpos=fn.rindex('/')+1
dpos=fpos+5
date=str(fn[dpos:dpos+8])
tpos=fpos+14
time=str(fn[tpos:tpos+6])
row=[]
row.append(date)
row.append(time)
row.append(fn)
row.append(gn)
ofiles.append(row)
else:
print('Missing: ' + gn + ', skipped')
return ofiles
############################################################################################
# pos=position center area
# dat=requested date (YYYYmmDD)
# day_pass=requested pass: day(True) or night(False)
# segdir is location raw files
# tlefil=location and name tle file
def Set_Sat_FY3D(pos,dat,day_pass,segdir,satid):
isat=sat
extended_day=True
isat.satname='FY-3D'
isat.satname_st='FENGYUN 3D'
isat.lenseg=60 # length of a segment (in seconds)
isat.sensor='mersi-2'
pre_filename='FY3D'
isat.d1 = int(13. + 29./60. - pos.lon/15. - 5.5) # east time w.r.t. center area longitude
isat.d2 = int(13. + 29./60. - pos.lon/15. + 6.5) # west time w.r.t. center area longitude
isat.tsrvc = 'HVS-1'
isat.rchan = 'E1H-RDS-2'
isat.day_pass=day_pass
isat.pos=pos
isat.paired_files=True
file1_ext = '1000M_L1B.HDF'
file2_ext = 'GEO1K_L1B.HDF'
# Collect files (2 sets)
if (fn_list):
(cf1,pf1,nf1)=get_files(fn_list,file1_ext)
(cf2,pf2,nf2)=get_files(fn_list,file2_ext)
else:
sfrmt=segdir + '/' + pre_filename + '_'
efrmt='*'+file1_ext
tfrmt='_'
(cf1,pf1,nf1)=collect_files(sfrmt,dat,tfrmt,efrmt,False,extended_day)
efrmt='*'+file2_ext
(cf2,pf2,nf2)=collect_files(sfrmt,dat,tfrmt,efrmt,False,extended_day)
isat.cfiles=load_filetbl(cf1,cf2,file1_ext,file2_ext)
isat.pfiles=load_filetbl(pf1,pf2,file1_ext,file2_ext)
isat.nfiles=load_filetbl(nf1,nf2,file1_ext,file2_ext)
isat.reader='mersi2_l1b'
isat.segdir=segdir
isat.logo='CMA_1000x1000.png'
return isat
# Set temporary directory and image directory
def set_dirs(basename,datdrp,destdir):
tmpdir = datdrp + '/EMCdata/tmpdirs/xfy3d'
if (dst==''):
imgdir = datdrp + '/EMCdata/images/'+basename
else:
imgdir = destdir
if (imgdir[len(imgdir)-1]=='/'):
imgdir = imgdir[:-1]
return tmpdir,imgdir
# Command line parsing
usage1 = 'Usage: ' + sys.argv[0] + ' -t YYYYmmDDHHMM [-sat RSS|IOC|1|2|3|4] [-src sourcedir] [-dst destinationdir] [-area ] -composite [-e ]'
parser = argparse.ArgumentParser('FY3D')
parser.add_argument('-t' ,default='', help="time: YYYYmmDDHHMM")
parser.add_argument('-sat' ,default='FY3DD', help="FY3D [D|N]]: D=Day, N=Night")
parser.add_argument('-src' ,default='', help="source dir., MUST be absolute path!")
parser.add_argument('-dst' ,default='', help="destination dir., MUST be absolute path!")
parser.add_argument('-sp' ,nargs='?',const=True,default=False, help="stacked pass")
parser.add_argument('-fl' ,default='', help="file with list of files")
parser.add_argument('-o' ,default='', help="output file")
parser.add_argument('-area' ,default='', help="area, 'list' gives a list")
parser.add_argument('-composite',default='', help="composite, 'list' gives a list")
parser.add_argument('-tle' ,default='', help="tle file, must contain tle elements of used satellite")
parser.add_argument('-histtle' ,nargs='?',const=True,default=False, help="get historical tle from spacetrack")
parser.add_argument('-v' ,nargs='?',const=1,default=0, help="start viewer; -v : specify viewer")
parser.add_argument('-dry' ,nargs='?',const=1,default=0, help="dry run; -dry f: show used files only")
args = parser.parse_args()
Dat=args.t
asat=args.sat
src=args.src
dst=args.dst
fn_list=args.fl
ofile=args.o
area=args.area
composite=args.composite
do_stack=args.sp
tlefil=args.tle
view=args.v
dry=args.dry
use_histtle=args.histtle
if (area=='list'):
list_areas()
sys.exit()
if (Dat=='') and (fn_list==''):
sys.exit('Error: No -t or -fl specified.')
# asat=FY3DD, FY3DN
if ((len(asat) > 4) and (asat[4]=='N')):
day_pass=False
else:
day_pass=True
satid='F'
if (tlefil == ''):
if not use_histtle:
tlefil = toodrp + '/EMCtools/pppconfig/my_TLE_file.txt'
print("Used tle="+tlefil)
if (composite==''):
if (day_pass):
composite = 'true_color'
else:
composite = 'overview'
# Choose your area
# Area definition must consider above coords and range for best results
if (area==''):
area='westminster'
# Center coords (° North and ° East) and range ° of interest
center_area=set_lonlat(area)
genpar=Set_Gen(day_pass,composite,area,dry,view)
Set_Overlay(genpar,ADDgrid=True,ADDcoasts=True,ADDborders=True,ADDrivers=True,ADDpoints=True)
if ((src!='') and (src[len(src)-1]=='/')):
src = src[:-1]
if (src==''):
segdir=def_segdir(Dat)
else:
segdir = src
curdir=os.getcwd()
satpar=Set_Sat_FY3D(center_area,Dat,day_pass,segdir,satid)
if not dry:
satpar.orb=set_orbit(satpar,Dat,use_histtle,tlefil)
(tmpdir,imgdir)=set_dirs(satpar.satname,datdrp,dst)
#######################################################################################
# Dir must exist.
# Goto tmpdir, so tmp-files will be dropped there
try:
os.chdir(tmpdir)
except:
sys.exit('Cannot change to tmp directory ' + str(tmpdir))
if (dry!=1):
(gf,gt)=select_files(satpar)
ofile=ofile_name(satpar,genpar,ofile,Dat)
if dry:
print('---------------Dry run---------------')
print("Satellite : " + asat)
print("Date : " + Dat)
print("Area : " + area)
print("Composite : " + composite)
print("Source loc. : " + segdir)
print("Destination loc.: " + imgdir)
print("temp. loc. : " + tmpdir)
print("TLE file : " + tlefil)
print("Use hist. tle : " + str(use_histtle))
print("File list : " + fn_list)
print("Stacking : " + str(do_stack))
print("Output file : " + ofile)
print("Viewer : " + genpar.viewer)
if (dry!='f'):
sys.exit('Stop, dry mode')
print("Area : " + area)
print("Composite: " + composite)
if (len(gf)==0):
sys.exit('No files in area range')
print('Files in area range: ' + str(len(gf)))
#Next must be done in tmpdir to put temp. pic there (still in tmpdir, but anyway...)
os.chdir(tmpdir)
new_scn=create_scene(satpar,genpar,gf,gt,composite,area,do_stack,datdrp)
try: # This is for real (multichannel) composites
layers, height, width = new_scn[composite].shape
except: # In case of a single channel 'composite'
height, width = new_scn[composite].shape
os.chdir(curdir)
os.system(magick_string(satpar,genpar,tmpdir,datdrp+'/EMCdata/logos',height,imgdir+'/'+ofile))
print('Generated: ' + imgdir+'/'+ofile)
if (view):
os.system(genpar.viewer + ' ' + imgdir+'/'+ofile)