def amsub_hdf(fnames, metadata_only=False, chans=None): ''' Read AMSU-B hdf data products. All GeoIPS 2.0 readers read data into xarray Datasets - a separate dataset for each shape/resolution of data - and contain standard metadata information. Args: fnames (list): List of strings, full paths to files metadata_only (Optional[bool]): * DEFAULT False * return before actually reading data if True chans (Optional[list of str]): * NOT IMPLEMENTED * DEFAULT None (include all channels) * List of desired channels (skip unneeded variables as needed) Returns: list of xarray.Datasets: list of xarray.Dataset objects with required Variables and Attributes: * See geoips2/docs :doc:`xarray_standards` ''' import os from datetime import datetime import numpy as np import pandas as pd import xarray as xr #from IPython import embed as shell #fname='NPR.MHOP.NP.D20154.S1406.E1553.B5833031.NS' fname = fnames[0] LOG.info('Reading file %s', fname) # check for right input AMSU-B/MHS data file data_name = os.path.basename(fname).split('_')[-1].split('.')[-1] if data_name != 'NS': print('Warning: wrong AMSU-B/MHS data type: data_type=', data_name) raise if ('NRP' and 'MHOP') in os.path.basename(fname): print('found a AMSU-B/MHS hdf file') else: print('not a AMSU-B/MHS hdf file: skip it') raise ''' ------ Notes ------ Read AMSU-B hdf files for 5 chan antenna temperature (AT) and asscoaited EDRs Then, transform these ATs and fields into xarray framework for GEOIPS2 ( AT will be corrected into brightness temperature (TB) later) Input Parameters: fname (str): input file name. require a full path Returns: xarray.Dataset with required Variables and Attributes: Variables: AMSUB vars: 'latitude', 'longitude', 'Ch1', 'Ch2', 'Ch3', 'Ch4','Ch4', 'RR', 'Snow','SWE','IWP','SFR' 'sfcType', 'time_scan' Attibutes: 'source_name', 'platform_name', 'data_provider', 'interpolation_radius_of_influence','start_datetime', 'end_datetime' ''' SData_ID = SD(fname, SDC.READ) VData_ID = HDF(fname, HC.READ).vstart() # get scan time info year = VData_ID.attach('ScanTime_year')[:] month = VData_ID.attach('ScanTime_month')[:] day = VData_ID.attach('ScanTime_dom')[:] hour = VData_ID.attach('ScanTime_hour')[:] minute = VData_ID.attach('ScanTime_minute')[:] second = VData_ID.attach('ScanTime_second')[:] jday = VData_ID.attach('ScanTime_doy')[:] # get EDRs lat = SData_ID.select('Latitude').get() lon = SData_ID.select('Longitude').get() RR = SData_ID.select('RR').get() Snow = SData_ID.select('Snow').get() IWP = SData_ID.select('IWP').get() SWE = SData_ID.select('SWE').get() SFR = SData_ID.select('SFR').get() Sfc_type = SData_ID.select('Sfc_type').get() Chan1_AT = SData_ID.select('Chan1_AT').get() Chan2_AT = SData_ID.select('Chan2_AT').get() Chan3_AT = SData_ID.select('Chan3_AT').get() Chan4_AT = SData_ID.select('Chan4_AT').get() Chan5_AT = SData_ID.select('Chan5_AT').get() SZ_angle = SData_ID.select('SZ_angle').get() LZ_angle = SData_ID.select('LZ_angle').get() # Min, Max, and scale factors (using hdfview) AT_min = 75.0 AT_max = 325.0 RR_min = 0.0 RR_max = 30.0 Snow_min = 0.0 Snow_max = 100.0 IWP_min = 0.0 IWP_max = 3.0 SWE_min = 0.0 SWE_max = 30.0 SFR_min = 0.03 SFR_max = 5.0 AT_scale = 100.0 RR_scale = 10.0 Snow_scale = 1.0 IWP_scale = 100.0 SWE_scale = 100.0 SFR_scale = 100.0 # Adjust the values with scale factors RR = RR * RR_scale Snow = Snow / Snow_scale IWP = IWP / IWP_scale SWE = SWE / SWE_scale SFR = SFR / SFR_scale Chan1_AT = Chan1_AT / AT_scale Chan2_AT = Chan2_AT / AT_scale Chan3_AT = Chan3_AT / AT_scale Chan4_AT = Chan4_AT / AT_scale Chan5_AT = Chan5_AT / AT_scale SData_ID.end() # close input file VData_ID.end() # close input file # -------- Apply the GEOIPS2 framework in XARRAY data frame ---------- LOG.info('Making full dataframe') # setup the timestamp in datetime64 format npix = RR.shape[1] # pixels per scan nscan = RR.shape[0] # total scans of this file time_scan = np.zeros((nscan, npix)) for i in range(nscan): time_scan[i:] = '%04d%03d%02d%02d' % (year[i][0], jday[i][0], hour[i][0], minute[i][0]) # ------ setup xarray variables ------ #namelist_amsub = ['latitude', 'longitude', 'Chan1_AT', 'Chan2_AT', 'Chan3_AT','Chan4_AT','Chan5_AT', # 'RR','Snow','IWP','SWE','SFR','Sfc_type','timestamp'] # setup amsub xarray xarray_amsub = xr.Dataset() xarray_amsub['latitude'] = xr.DataArray(lat) xarray_amsub['longitude'] = xr.DataArray(lon) xarray_amsub['Chan1_AT'] = xr.DataArray(Chan1_AT) xarray_amsub['Chan2_AT'] = xr.DataArray(Chan2_AT) xarray_amsub['Chan3_AT'] = xr.DataArray(Chan3_AT) xarray_amsub['Chan4_AT'] = xr.DataArray(Chan4_AT) xarray_amsub['Chan5_AT'] = xr.DataArray(Chan5_AT) xarray_amsub['RR'] = xr.DataArray(RR) xarray_amsub['Snow'] = xr.DataArray(Snow) xarray_amsub['IWP'] = xr.DataArray(IWP) xarray_amsub['SWE'] = xr.DataArray(SWE) xarray_amsub['SFR'] = xr.DataArray(SFR) xarray_amsub['sfcType'] = xr.DataArray(Sfc_type) xarray_amsub['timestamp'] = xr.DataArray( pd.DataFrame(time_scan).astype(int).apply(pd.to_datetime, format='%Y%j%H%M')) # setup attributes # satID and start_end time from input filename (M3 --> METOP-3 ???) sat_id = os.path.basename(fname).split('.')[2] if sat_id == 'NP': satid = 'NOAA-19' elif sat_id == 'NN': satid = 'NOAA-18' elif sat_id == 'M1': satid = 'METOP-B' elif sat_id == 'M2': satid = 'METOP-A' elif sat_id == 'M3': satid = 'METOP-C' yr = os.path.basename(fname).split('.')[3][1:3] jd = os.path.basename(fname).split('.')[3][3:6] hr = os.path.basename(fname).split('.')[4][1:3] mi = os.path.basename(fname).split('.')[4][3:6] start_time = '%02d%03d%02d%02d' % (int(yr), int(jd), int(hr), int(mi)) hr = os.path.basename(fname).split('.')[5][1:3] mi = os.path.basename(fname).split('.')[5][3:6] end_time = '%02d%03d%02d%02d' % (int(yr), int(jd), int(hr), int(mi)) # add attributes to xarray xarray_amsub.attrs['start_datetime'] = datetime.strptime( start_time, '%y%j%H%M') xarray_amsub.attrs['end_datetime'] = datetime.strptime( end_time, '%y%j%H%M') xarray_amsub.attrs['source_name'] = 'amsub' xarray_amsub.attrs['platform_name'] = satid xarray_amsub.attrs['data_provider'] = 'NESDIS' # MTIFs need to be "prettier" for PMW products, so 2km resolution for final image # xarray_amsub.attrs['sample_distance_km'] = 15 xarray_amsub.attrs['sample_distance_km'] = 2 xarray_amsub.attrs['interpolation_radius_of_influence'] = 30000 return [xarray_amsub]