Skip to content

Commit 8c607fe

Browse files
committed
added QC-plotting
1 parent 2152a12 commit 8c607fe

3 files changed

Lines changed: 336 additions & 3 deletions

File tree

lib/visualization/pypolly_display_all.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ def main():
455455
try:
456456
nc_profiles = readout.get_nc_filename(date, device, inputfolder, param='profiles')
457457
nc_profiles_NR = readout.get_nc_filename(date, device, inputfolder, param='NR_profiles')
458+
nc_profiles_QC = readout.get_nc_filename(date, device, inputfolder, param='profiles_QC')
458459
print(f'plotting profile summary to {outputfolder}')
459460
#for prof in nc_profiles:
460461
# nc_dict_profile = readout.read_nc_file(prof)
@@ -469,12 +470,23 @@ def main():
469470
nc_dict_profile_NR = readout.read_nc_file(nc_profiles_NR[n_prof],date,device,location)
470471
else:
471472
nc_dict_profile_NR = {}
473+
if len(nc_profiles_QC) > 0:
474+
nc_dict_profile_QC = readout.read_nc_file(nc_profiles_QC[n_prof],date,device,location)
475+
nc_dict_profile_QC = readout.calc_ANGEXP(nc_dict_profile_QC)
476+
else:
477+
nc_dict_profile_QC = {}
478+
472479
starttime=datetime.utcfromtimestamp(int(nc_dict_profile['start_time'])).strftime('%H:%M')
473480
endtime=datetime.utcfromtimestamp(int(nc_dict_profile['end_time'])).strftime('%H:%M')
474481
print(f"profile: {starttime} - {endtime}")
475482
nc_dict_profile = readout.calc_ANGEXP(nc_dict_profile)
483+
print(f"QC-profiles")
484+
display_profiles.pollyDisplay_profile_summary_QC(nc_dict_profile=nc_dict_profile_QC,config_dict=config_dict,polly_conf_dict=polly_conf_dict,outdir=outputfolder,ymax='high_range',donefilelist_dict=donefilelist_dict)
485+
display_profiles.pollyDisplay_profile_summary_QC(nc_dict_profile=nc_dict_profile_QC,config_dict=config_dict,polly_conf_dict=polly_conf_dict,outdir=outputfolder,ymax='low_range',donefilelist_dict=donefilelist_dict)
486+
print(f"Raman-profiles")
476487
display_profiles.pollyDisplay_profile_summary(nc_dict_profile=nc_dict_profile,nc_dict_profile_NR=nc_dict_profile_NR,config_dict=config_dict,polly_conf_dict=polly_conf_dict,outdir=outputfolder,method='raman',ymax='high_range',donefilelist_dict=donefilelist_dict)
477488
display_profiles.pollyDisplay_profile_summary(nc_dict_profile=nc_dict_profile,nc_dict_profile_NR=nc_dict_profile_NR,config_dict=config_dict,polly_conf_dict=polly_conf_dict,outdir=outputfolder,method='raman',ymax='low_range',donefilelist_dict=donefilelist_dict)
489+
print(f"Klett-profiles")
478490
display_profiles.pollyDisplay_profile_summary(nc_dict_profile=nc_dict_profile,nc_dict_profile_NR=nc_dict_profile_NR,config_dict=config_dict,polly_conf_dict=polly_conf_dict,outdir=outputfolder,method='klett',ymax='high_range',donefilelist_dict=donefilelist_dict)
479491
display_profiles.pollyDisplay_profile_summary(nc_dict_profile=nc_dict_profile,nc_dict_profile_NR=nc_dict_profile_NR,config_dict=config_dict,polly_conf_dict=polly_conf_dict,outdir=outputfolder,method='klett',ymax='low_range',donefilelist_dict=donefilelist_dict)
480492
except Exception as e:

lib/visualization/pypolly_display_profiles.py

Lines changed: 323 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,9 @@ def plotting_procedure(col,param_dict,parameter,xlabel,xlim=[0,1],ylim=[0,1],sca
10191019
length=3.5, right=True, top=True)
10201020

10211021
for n,p in enumerate(param_dict[parameter]["FR"]):
1022-
label = p
1022+
if p == None:
1023+
continue
1024+
label=f'{p}_FR'
10231025
if parameter == 'angstroem':
10241026
color_ls = ['orange','magenta','black']
10251027
else:
@@ -1070,16 +1072,19 @@ def plotting_procedure(col,param_dict,parameter,xlabel,xlim=[0,1],ylim=[0,1],sca
10701072

10711073

10721074
for n,p in enumerate(param_dict[parameter]["NR"]):
1075+
if p == None:
1076+
continue
10731077
color_ls = ['cyan','lime']
10741078

10751079
line_style = '-'
10761080
nc_dict_profile_NR_shortened = nc_dict_profile_NR[p][0:h_index]
1081+
label = f'{p}_NR'
10771082
p_NR = ax[col].plot(nc_dict_profile_NR_shortened*scaling_factor, height_NR_shortened/1000,\
10781083
linestyle=line_style,\
10791084
color=color_ls[n],\
10801085
zorder=1,\
10811086
alpha=0.5,\
1082-
label=f'{p}_NR')
1087+
label=label)
10831088
ax[col].set_xlim(xlim[0],xlim[1])
10841089
ax[col].set_ylim(ylim[0],ylim[1]/1000)
10851090
ax[col].legend(loc='upper right',fontsize=14)
@@ -1237,4 +1242,320 @@ def plotting_procedure(col,param_dict,parameter,xlabel,xlim=[0,1],ylim=[0,1],sca
12371242
)
12381243

12391244

1245+
def pollyDisplay_profile_summary_QC(nc_dict_profile,config_dict,polly_conf_dict,outdir,ymax,donefilelist_dict):
1246+
"""
1247+
Description
1248+
-----------
1249+
Display the water vapor mixing ratio WVMR from level1 polly nc-file.
1250+
1251+
Parameters
1252+
----------
1253+
nc_dict_profile: dict
1254+
dict wich stores the WV data.
1255+
1256+
Usage
1257+
-----
1258+
pollyDisplayWVMR_profile(nc_dict_profile,config_dict,polly_conf_dict)
1259+
1260+
History
1261+
-------
1262+
2022-09-01. First edition by Andi
1263+
"""
1264+
1265+
## read from config file
1266+
figDPI = config_dict['figDPI']
1267+
flagWatermarkOn = config_dict['flagWatermarkOn']
1268+
fontname = config_dict['fontname']
1269+
1270+
1271+
partnerLabel = polly_conf_dict['partnerLabel']
1272+
imgFormat = polly_conf_dict['imgFormat']
1273+
1274+
## read from nc-file
1275+
starttime = nc_dict_profile['start_time']
1276+
endtime = nc_dict_profile['end_time']
1277+
# var_err_ls = [ nc_dict_profile[parameter_err] for parameter_err in profile_translator[profilename]['var_err_name_ls'] ]
1278+
height_FR = nc_dict_profile['height']
1279+
# LCUsed = np.array([nc_dict_profile[f'LCUsed{wavelength}']])
1280+
1281+
# flagLC = nc_dict_profile[f'flagLC{wavelength}']
1282+
pollyVersion = nc_dict_profile['PollyVersion']
1283+
location = nc_dict_profile['location']
1284+
version = nc_dict_profile['PicassoVersion']
1285+
dataFilename = re.split(r'_profiles',nc_dict_profile['PollyDataFile'])[0]
1286+
# set the default font
1287+
matplotlib.rcParams['font.sans-serif'] = fontname
1288+
matplotlib.rcParams['font.family'] = "sans-serif"
1289+
1290+
1291+
if ymax == 'high_range':
1292+
y_max_FR = 18000
1293+
ymax_prod_type = ymax
1294+
xmax_depol = [0,0.6]
1295+
elif ymax == 'low_range':
1296+
y_max_FR = 5000
1297+
ymax_prod_type = ymax
1298+
xmax_depol = polly_conf_dict['zLim_VolDepol_1064']
1299+
else:
1300+
y_max_FR = 18000
1301+
ymax_prod_type = 'high_range'
1302+
xmax_depol = [0,0.6]
1303+
1304+
plotfile = f"{dataFilename}_profile_summary_QC_{ymax_prod_type}.{imgFormat}"
1305+
saveFolder = outdir
1306+
saveFilename = os.path.join(saveFolder,plotfile)
1307+
1308+
cols = 6
1309+
# height_NR = nc_dict_profile_NR['height']
1310+
# h_index = np.where(height_NR > 5000)[0][0]
1311+
# height_NR_shortened = height_NR[0:h_index]
1312+
1313+
param_dict = {
1314+
"backscatter":
1315+
{"Klett": ['aerBsc_klett_355','aerBsc_klett_532','aerBsc_klett_1064'],
1316+
"Raman":['aerBsc_raman_355','aerBsc_raman_532','aerBsc_raman_1064']
1317+
},
1318+
"extinction": {"Klett": ['aerBsc_klett_355','aerBsc_klett_532','aerBsc_klett_1064'],
1319+
"Raman": ['aerExt_raman_355','aerExt_raman_532','aerExt_raman_1064']
1320+
},
1321+
"lidarratio": {"Klett": [],
1322+
"Raman": ['aerLR_raman_355','aerLR_raman_532','aerLR_raman_1064']
1323+
},
1324+
"angstroem": {"Klett": [],
1325+
"Raman": ['AE_beta_355_532_Raman','AE_beta_532_1064_Raman','AE_parExt_355_532_Raman']
1326+
},
1327+
"depolarization": {"Klett": ['parDepol_klett_355','parDepol_klett_532','parDepol_klett_1064'],
1328+
"Raman": ['parDepol_raman_355','parDepol_raman_532','parDepol_raman_1064']
1329+
},
1330+
"wvmr": {"Klett": [],
1331+
"Raman": ['WVMR']
1332+
}
1333+
}
1334+
1335+
1336+
fixed_LR_ls = []
1337+
1338+
def plotting_procedure_QC(col,param_dict,parameter,xlabel,xlim=[0,1],ylim=[0,1],scaling_factor=1):
1339+
fixed_LR = 1
1340+
1341+
ax[col].set_xlabel(xlabel, fontsize=axes_fontsize)
1342+
ax[col].grid(True)
1343+
ax[col].tick_params(axis='both', which='major', labelsize=15,
1344+
right=True, top=True, width=2, length=5)
1345+
ax[col].tick_params(axis='both', which='minor', width=1.5,
1346+
length=3.5, right=True, top=True)
1347+
1348+
for n,p in enumerate(param_dict[parameter]["Raman"]):
1349+
label = p
1350+
if parameter == 'angstroem':
1351+
color_ls = ['orange','magenta','black']
1352+
else:
1353+
color_ls = ['blue','green','red']
1354+
1355+
line_style = '-'
1356+
1357+
if parameter == 'wvmr':
1358+
# ax2 = ax[col].secondary_xaxis('top')
1359+
ax2 = ax[col].twiny()
1360+
ax2.set_xlabel('Rel.Humidity [%]', fontsize=axes_fontsize)
1361+
ax2.set_xlim(0,100)
1362+
ax2.tick_params(axis='both', which='major', labelsize=15,
1363+
right=True, top=True, width=2, length=5)
1364+
ax2.tick_params(axis='both', which='minor', width=1.5,
1365+
length=3.5, right=True, top=True)
1366+
p_Raman = ax[col].plot(nc_dict_profile['WVMR']*scaling_factor, height_FR/1000,\
1367+
linestyle=line_style,\
1368+
color=color_ls[n],\
1369+
zorder=2,\
1370+
alpha=1,\
1371+
label='WVMR')
1372+
p_RH = ax2.plot(nc_dict_profile['RH']*scaling_factor, height_FR/1000,\
1373+
linestyle=line_style,\
1374+
#color=color_ls[n],\
1375+
color='green',
1376+
zorder=2,\
1377+
alpha=1,\
1378+
label='RH')
1379+
ax2.legend(fontsize=14, loc='upper right', bbox_to_anchor=(0.9, 0.95))
1380+
else:
1381+
p_Raman = ax[col].plot(nc_dict_profile[p]*scaling_factor*fixed_LR, height_FR/1000,\
1382+
linestyle=line_style,\
1383+
color=color_ls[n],\
1384+
zorder=2,\
1385+
label=label)
1386+
1387+
1388+
for n,p in enumerate(param_dict[parameter]["Klett"]):
1389+
color_ls = ['cyan','lime','salmon']
1390+
label = p
1391+
line_style = '-'
1392+
1393+
if parameter == 'extinction':
1394+
label = f'{p} x LR'
1395+
try:
1396+
fixed_LR = nc_dict_profile[f'{p}___retrieving_info']
1397+
fixed_LR = re.split(r'Fixed lidar ratio:',fixed_LR)[-1]
1398+
fixed_LR = float(re.split(r'\[Sr\]',fixed_LR)[0])
1399+
fixed_LR_ls.append(fixed_LR)
1400+
except:
1401+
fixed_LR = 50
1402+
else:
1403+
fixed_LR = 1
1404+
1405+
p_Klett = ax[col].plot(nc_dict_profile[p]*scaling_factor*fixed_LR, height_FR/1000,\
1406+
linestyle=line_style,\
1407+
color=color_ls[n],\
1408+
zorder=1,\
1409+
label=label)
1410+
ax[col].set_xlim(xlim[0],xlim[1])
1411+
ax[col].set_ylim(ylim[0],ylim[1]/1000)
1412+
ax[col].legend(loc='upper right',fontsize=14)
1413+
1414+
1415+
fig, ax = plt.subplots(1,cols, figsize=(25, 17))
1416+
1417+
axes_fontsize = 18
1418+
1419+
## ref.Height
1420+
if np.any(nc_dict_profile['reference_height_355'].mask):
1421+
refH355_0 = np.nan
1422+
refH355_1 = np.nan
1423+
else:
1424+
refH355_0 = nc_dict_profile['reference_height_355'][0]/1000
1425+
refH355_1 = nc_dict_profile['reference_height_355'][1]/1000
1426+
if np.any(nc_dict_profile['reference_height_532'].mask):
1427+
refH532_0 = np.nan
1428+
refH532_1 = np.nan
1429+
else:
1430+
refH532_0 = nc_dict_profile['reference_height_532'][0]/1000
1431+
refH532_1 = nc_dict_profile['reference_height_532'][1]/1000
1432+
if np.any(nc_dict_profile['reference_height_1064'].mask):
1433+
refH1064_0 = np.nan
1434+
refH1064_1 = np.nan
1435+
else:
1436+
refH1064_0 = nc_dict_profile['reference_height_1064'][0]/1000
1437+
refH1064_1 = nc_dict_profile['reference_height_1064'][1]/1000
1438+
fig.text(
1439+
0.1, 0.02,
1440+
'ref.H_355: '+f'{refH355_0:.2f}-{refH355_1:.2f} km\n'+\
1441+
'ref.H_532: '+f'{refH532_0:.2f}-{refH532_1:.2f} km\n'+\
1442+
'ref.H_1064: '+f'{refH1064_0:.2f}-{refH1064_1:.2f} km',fontsize=14, backgroundcolor=[0.94, 0.95, 0.96, 0.8], alpha=1)
1443+
1444+
## eta
1445+
try:
1446+
eta355 = float(re.split(r'eta:',nc_dict_profile['volDepol_klett_355___retrieving_info'])[-1])
1447+
except:
1448+
eta355 = np.nan
1449+
try:
1450+
eta532 = float(re.split(r'eta:',nc_dict_profile['volDepol_klett_532___retrieving_info'])[-1])
1451+
except:
1452+
eta532 = np.nan
1453+
try:
1454+
eta1064 = float(re.split(r'eta:',nc_dict_profile['volDepol_klett_1064___retrieving_info'])[-1])
1455+
except:
1456+
eta1064 = np.nan
1457+
ax[4].text(
1458+
0.45, 0.75,
1459+
r'$\eta_{355}$: '+f'{eta355:.2f}\n'+\
1460+
r'$\eta_{532}$: '+f'{eta532:.2f}\n'+\
1461+
r'$\eta_{1064}$: '+f'{eta1064:.2f}',fontsize=14, backgroundcolor=[0.94, 0.95, 0.96, 0.8], alpha=1,transform=ax[4].transAxes)
1462+
1463+
## water-vapor calib-constant
1464+
try:
1465+
wv_calib = float(nc_dict_profile['WVMR___wv_calibration_constant_used'])
1466+
except:
1467+
wv_calib = np.nan
1468+
fig.text(
1469+
0.85, 0.05,
1470+
f'WV-calib.const.: {wv_calib:.1f}',fontsize=14, backgroundcolor=[0.94, 0.95, 0.96, 0.8], alpha=1)
1471+
1472+
1473+
1474+
plotting_procedure_QC(col=0,param_dict=param_dict,parameter="backscatter",xlabel="Backsc. coeff. [Msr$^{-1}$ m$^{-1}$]",xlim = polly_conf_dict['xLim_Profi_Bsc'],ylim=[0,y_max_FR],scaling_factor=10**6)
1475+
1476+
plotting_procedure_QC(col=1,param_dict=param_dict,parameter="extinction",xlabel="Extinct. coeff. [Mm$^{-1}$]",xlim = polly_conf_dict['xLim_Profi_Ext'],ylim=[0,y_max_FR],scaling_factor=10**6)
1477+
1478+
plotting_procedure_QC(col=2,param_dict=param_dict,parameter="lidarratio",xlabel="Lidar ratio [Sr]",xlim = polly_conf_dict['xLim_Profi_LR'],ylim=[0,y_max_FR])
1479+
1480+
plotting_procedure_QC(col=3,param_dict=param_dict,parameter="angstroem",xlabel="$\AA$ngström Exp.",xlim = polly_conf_dict['xLim_Profi_AE'],ylim=[0,y_max_FR])
1481+
1482+
plotting_procedure_QC(col=4,param_dict=param_dict,parameter="depolarization",xlabel="Depol. ratio",xlim = xmax_depol,ylim=[0,y_max_FR])
1483+
plotting_procedure_QC(col=5,param_dict=param_dict,parameter="wvmr",xlabel="WVMR [$g*kg^{-1}$]",xlim = polly_conf_dict['xLim_Profi_WVMR'],ylim=[0,y_max_FR])
1484+
1485+
if len(fixed_LR_ls) > 0:
1486+
ax[1].text(
1487+
0.6, 0.85,
1488+
r'LR$_{355}$: '+f'{fixed_LR_ls[0]:.2f}\n'+\
1489+
r'LR$_{532}$: '+f'{fixed_LR_ls[1]:.2f}\n'+\
1490+
r'LR$_{1064}$: '+f'{fixed_LR_ls[2]:.2f}',fontsize=11, backgroundcolor=[0.94, 0.95, 0.96, 0.8], alpha=1,transform=ax[1].transAxes)
1491+
1492+
1493+
plt.tight_layout(rect=[0.05, 0.07, 0.98, 0.95])
1494+
1495+
ax[0].set_ylabel("Height [km]",fontsize=18)
1496+
1497+
fig.suptitle(
1498+
'Summary of QC profile plots for {instrument} at {location} {starttime}-{endtime}'.format(
1499+
instrument=pollyVersion,
1500+
location=location,
1501+
starttime=datetime.utcfromtimestamp(int(starttime)).strftime('%Y%m%d %H:%M'),
1502+
endtime=datetime.utcfromtimestamp(int(endtime)).strftime('%H:%M'),
1503+
# starttime=starttime.strftime('%Y%m%d %H:%M'),
1504+
# endtime=endtime.strftime('%H:%M')
1505+
),
1506+
fontsize=20
1507+
)
1508+
1509+
# plt.legend(loc='upper right')
1510+
1511+
# add watermark
1512+
if flagWatermarkOn:
1513+
rootDir = os.path.dirname(
1514+
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
1515+
#rootDir = os.getcwd()
1516+
im_license = matplotlib.image.imread(
1517+
os.path.join(rootDir, 'img', 'by-sa.png'))
1518+
1519+
newax_license = fig.add_axes([0.33, 0.006, 0.08, 0.04], zorder=10)
1520+
newax_license.imshow(im_license, alpha=0.8, aspect='equal')
1521+
newax_license.axis('off')
1522+
1523+
fig.text(0.5, 0.01, 'Preliminary\nResults.',
1524+
fontweight='bold', fontsize=12, color='red',
1525+
ha='left', va='bottom', alpha=0.8, zorder=10)
1526+
1527+
fig.text(
1528+
0.75, 0.01,
1529+
u"\u00A9 {1} {0}.\nCC BY SA 4.0 License.".format(
1530+
datetime.now().strftime('%Y'), partnerLabel),
1531+
fontweight='bold', fontsize=10, color='black', ha='left',
1532+
va='bottom', alpha=1, zorder=10)
1533+
1534+
1535+
fig.savefig(saveFilename, dpi=figDPI)
1536+
1537+
plt.close()
1538+
1539+
## write2donefilelist
1540+
readout.write2donefilelist_dict(donefilelist_dict = donefilelist_dict,
1541+
lidar = pollyVersion,
1542+
location = nc_dict_profile['location'],
1543+
starttime = datetime.utcfromtimestamp(int(nc_dict_profile['start_time'])).strftime('%Y%m%d %H:%M:%S'),
1544+
stoptime = datetime.utcfromtimestamp(int(nc_dict_profile['end_time'])).strftime('%Y%m%d %H:%M:%S'),
1545+
last_update = datetime.now(timezone.utc).strftime("%Y%m%d %H:%M:%S"),
1546+
wavelength = 355,
1547+
filename = saveFilename,
1548+
level = 0,
1549+
info = "overview of all relevant polly profile-products",
1550+
nc_zip_file = nc_dict_profile['PollyDataFile'],
1551+
nc_zip_file_size = 9000000,
1552+
active = 1,
1553+
GDAS = 0,
1554+
GDAS_timestamp = f"{datetime.utcfromtimestamp(int(nc_dict_profile['start_time'])).strftime('%Y%m%d')} 12:00:00",
1555+
lidar_ratio = 50,
1556+
software_version = version,
1557+
product_type = f'Profile_summary_QC_{ymax_prod_type}',
1558+
product_starttime = datetime.utcfromtimestamp(int(nc_dict_profile['start_time'])).strftime('%Y%m%d %H:%M:%S'),
1559+
product_stoptime = datetime.utcfromtimestamp(int(nc_dict_profile['end_time'])).strftime('%Y%m%d %H:%M:%S')
1560+
)
12401561

lib/visualization/pypolly_readout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def get_nc_filename(date, device, inputfolder, param=""):
4343
'''
4444
param: str
4545
att-param with possible values: "att_bsc", "NR_att_bsc", "OC_att_bsc", "vol_depol", "WVMR_RH", "quasi_results",
46-
"quasi_results_V2" "target_classification", "target_classification_V2", "profiles", "OC_profiles",
46+
"quasi_results_V2" "target_classification", "target_classification_V2", "profiles", "OC_profiles", "profiles_QC"
4747
"NR_profiles", "cloudinfo","POLIPHON_1", "RCS"
4848
'''
4949

0 commit comments

Comments
 (0)