forked from tuyetnam/AOD-Handling
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathread_mod_aerosol_and_dump_ascii.py
134 lines (126 loc) · 5.16 KB
/
read_mod_aerosol_and_dump_ascii.py
1
#!/usr/bin/python'''Module: read_mod_aerosol_and_dump_ascii.py==========================================================================================Disclaimer: The code is for demonstration purposes only. Users are responsible to check for accuracy and revise to fit their objective.Author: Justin Roberts-Pierel, 2015 Organization: NASA ARSETPurpose: To save a MODIS HDF4 file (or series of files) in ASCII format, saving time, lat, lon, and other SDS dependent on file typeSee the README associated with this module for more information.=========================================================================================='''#import necessary modulesfrom pyhdf import SDimport numpy as npimport timeimport calendarimport sys#This uses the file "fileList.txt", containing the list of files, in order to read the filestry: fileList=open('fileList.txt','r')except: print('Did not find a text file containing file names (perhaps name does not match)') sys.exit()#loops through all files listed in the text filefor FILE_NAME in fileList: FILE_NAME=FILE_NAME.strip() user_input=input('\nWould you like to process\n' + FILE_NAME + '\n\n(Y/N)') if(user_input == 'N' or user_input == 'n'): continue else: if '3K' in FILE_NAME: #then this is a 3km MODIS file print('This is a 3km MODIS file. Saving... ') #saves all the SDS to be outputted to ASCII in a dictionary dataFields=dict([(1,'Optical_Depth_Land_And_Ocean'),(2,'Image_Optical_Depth_Land_And_Ocean'),(3,'Land_sea_Flag'),(4,'Land_Ocean_Quality_Flag')]) # The name of the SDS to read elif 'L2' in FILE_NAME: #Same as above but for 10km MODIS file print('This is a 10km MODIS file. Saving... ') dataFields=dict([(1,'Deep_Blue_Aerosol_Optical_Depth_550_Land'),(2,'AOD_550_Dark_Target_Deep_Blue_Combined'),(3,'AOD_550_Dark_Target_Deep_Blue_Combined_QA_Flag')]) else: print('The file :',FILE_NAME, ' is not a valid MODIS file (or is named incorrectly). \n') continue try: # open the hdf file for reading hdf=SD.SD(FILE_NAME) except: print('Unable to open file: \n' + FILE_NAME + '\n Skipping...') continue # Get lat and lon info lat = hdf.select('Latitude') lat=(lat.get()).ravel() latitude = np.array(lat[:]) lon = hdf.select('Longitude') lon=(lon.get()).ravel() longitude = np.array(lon[:]) #Get the scan start time from the hdf file. This is in number of seconds since Jan 1, 1993 scan_time=hdf.select('Scan_Start_Time') scan_time=(scan_time.get()).ravel() scan_time=scan_time[:] #get the date info from scan_time year=np.zeros(scan_time.shape[0]) month=np.zeros(scan_time.shape[0]) day=np.zeros(scan_time.shape[0]) hour=np.zeros(scan_time.shape[0]) min=np.zeros(scan_time.shape[0]) sec=np.zeros(scan_time.shape[0]) #Saves date info for each pixel to be saved later for i in range(scan_time.shape[0]): temp=time.gmtime(scan_time[i-1]+calendar.timegm(time.strptime('Dec 31, 1992 @ 23:59:59 UTC', '%b %d, %Y @ %H:%M:%S UTC'))) year[i-1]=temp[0] month[i-1]=temp[1] day[i-1]=temp[2] hour[i-1]=temp[3] min[i-1]=temp[4] sec[i-1]=temp[5] #Begin saving to an output array end=8+len(dataFields)#this is the number of columns needed (based on number of SDS read) output=np.array(np.zeros((year.shape[0],end))) output[0:,0]=year[:] output[0:,1]=month[:] output[0:,2]=day[:] output[0:,3]=hour[:] output[0:,4]=min[:] output[0:,5]=sec[:] output[0:,6]=latitude[:] output[0:,7]=longitude[:] #list for the column titles tempOutput=[] tempOutput.append('Year') tempOutput.append('Month') tempOutput.append('Day') tempOutput.append('Hour') tempOutput.append('Minute') tempOutput.append('Second') tempOutput.append('Latitude') tempOutput.append('Longitude') #This for loop saves all of the SDS in the dictionary at the top (dependent on file type) to the array (with titles) for i in range(8,end): SDS_NAME=dataFields[(i-7)] # The name of the sds to read #get current SDS data, or exit program if the SDS is not found in the file try: sds=hdf.select(SDS_NAME) except: print('Sorry, your MODIS hdf file does not contain the SDS:',SDS_NAME,'. Please try again with the correct file type.') continue #get scale factor for current SDS attributes=sds.attributes() scale_factor=attributes['scale_factor'] fillvalue=attributes['_FillValue'] #get SDS data as a vector data=(sds.get()).ravel() data=np.array(data[:]) #The next few lines change fillvalue to NaN so that we can multiply valid values by the scale factor, then back to fill values data=data.astype(float) data[data==float(fillvalue)]=np.nan data=data*scale_factor data[np.isnan(data)]=fillvalue #the SDS and SDS name are saved to arrays which will be written to the .txt file output[0:,i]=data tempOutput.append(SDS_NAME) #changes list to an array so it can be stacked tempOutput=np.asarray(tempOutput) #This stacks the titles on top of the data output=np.row_stack((tempOutput,output)) #save the new array to a text file, which is the name of the HDF4 file .txt instead of .hdf np.savetxt('{0}.txt'.format(FILE_NAME[:-4]),output,fmt='%s',delimiter=',')print('\nAll valid files have been saved successfully.')