def getAtlTruthSwath(atlMeasuredData, rotationData, truthHeaderDF, truthFilePaths, buffer, outFilePath, createTruthFile, truthFileType, useExistingTruth, logFileID=False): # Start timer timeStart = runTime.time() # Initialize data atlTruthData = [] # Print message gtNum = atlMeasuredData.gtNum beamNum = atlMeasuredData.beamNum beamStrength = atlMeasuredData.beamStrength writeLog( ' Ground Track Number: %s (Beam #%s, Beam Strength: %s)\n' % (gtNum, beamNum, beamStrength), logFileID) if (useExistingTruth): # Get truth swath .las file truthFilePath = truthFilePaths[0] # Get truth file header info writeLog(' Reading in reference buffer file: %s\n' % truthFilePath, logFileID) atlTruthData = loadTruthFile(truthFilePath, atlMeasuredData, rotationData, truthFileType, outFilePath, logFileID) else: # Reproject unmatching ESPG files to match ICESat-2 EPSG code truthHeaderNewDF = reprojectHeaderData(truthHeaderDF, atlMeasuredData, logFileID) # Find truth files that intersect ICESat-2 track writeLog( ' Determining which reference files intersect ground track...', logFileID) matchingTruthFiles = findMatchingTruthFiles(truthHeaderNewDF, atlMeasuredData, rotationData, buffer) # Read truth files that intersect ICESat-2 track if (len(matchingTruthFiles) > 0): # Print messages writeLog( ' Ground track crosses over %d (out of %d) reference files' % (len(matchingTruthFiles), len(truthHeaderDF)), logFileID) writeLog( ' Reading from directory: %s' % ntpath.dirname(matchingTruthFiles[0]), logFileID) writeLog('', logFileID) writeLog(' Reading File:', logFileID) writeLog(' -------------', logFileID) # Initialize parameters fileNum = 1 atlTruthData = atlTruthStruct([], [], [], [], [], [], [], [], [], [], []) # Loop over matching files for i in range(0, len(matchingTruthFiles)): # Get truth file to read truthFilePath = matchingTruthFiles[i] # Get truth base file name baseName = ntpath.basename(truthFilePath) # Read truth file writeLog(' %d) %s' % (fileNum, baseName), logFileID) atlTruthDataSingle = loadTruthFile(truthFilePath, atlMeasuredData, rotationData, truthFileType, outFilePath, logFileID) # Get truth file buffer if (bool(atlTruthDataSingle)): writeLog(' Buffering data...', logFileID) atlTruthDataBuffer = makeBuffer(atlTruthDataSingle, atlMeasuredData, rotationData, buffer) # Append truth files atlTruthData.append(atlTruthDataBuffer) # Increment counter fileNum += 1 # endIf # endFor else: # No data to process atlTruthData = [] writeLog('', logFileID) writeLog( ' WARNING: No matching reference files intersect ground track.', logFileID) # endIf # endIf # Test if atlTruthData is empty atlTruthEmpty = (len(atlTruthData.easting) == 0) and (len( atlTruthData.northing) == 0) # Inform user if data is empty if (atlTruthEmpty): writeLog('ERROR: Reference data is empty.', logFileID) # endIf # Create output file if (createTruthFile and not (atlTruthEmpty)): # Set output file name if (useExistingTruth): outName = os.path.basename(truthFilePath) else: outName = atlMeasuredData.atl03FileName + '_' + \ atlMeasuredData.gtNum + '_REFERENCE_' + str(buffer) + \ 'L' + str(buffer) + 'Rm_buffer.las' # endIf # Set full output file name and path outPath = os.path.normpath(outFilePath + '/' + outName) # If output directory does not exist, create it if (not os.path.exists(os.path.normpath(outFilePath))): os.mkdir(os.path.normpath(outFilePath)) # EndIf # Write to file writeLog('', logFileID) writeLog(' Writing reference .las file...', logFileID) writeLas(np.ravel(atlTruthData.easting), np.ravel(atlTruthData.northing), np.ravel(atlTruthData.z), 'utm', outPath, np.ravel(atlTruthData.classification), np.ravel(atlTruthData.intensity), None, atlTruthData.hemi, atlTruthData.zone) # endIf # End timer timeEnd = runTime.time() timeElapsedTotal = timeEnd - timeStart timeElapsedMin = np.floor(timeElapsedTotal / 60) timeElapsedSec = timeElapsedTotal % 60 # Print completion message writeLog('', logFileID) writeLog( ' Module Completed in %d min %d sec.' % (timeElapsedMin, timeElapsedSec), logFileID) writeLog('\n', logFileID) # Return object return atlTruthData
def getAtlMeasuredSwath(atl03FilePath=False, atl08FilePath=False, outFilePath=False, gtNum='gt1r', trimInfo='auto', createAtl03LasFile=False, createAtl03KmlFile=False, createAtl08KmlFile=False, createAtl03CsvFile=False, createAtl08CsvFile=False, logFileID=False): # pklHeaderFile = None, LAS_DIR = None): # Initialize outputs atl03Data = [] headerData = False rotationData = False # Initialize ATL08 data atl08Data = [] atl08_lat = [] atl08_lon = [] atl08_maxCanopy = [] atl08_teBestFit = [] atl08_teMedian = [] atl08_time = [] atl08_easting = [] atl08_northing = [] atl08_crossTrack = [] atl08_alongTrack = [] atl08_classification = [] atl08_intensity = [] # pklHeader = False # if type(pklHeaderFile) != type(None): # pklHeader = True # if type(LAS_DIR) == type(None): # raise ValueError('LAS_DIR == None, please input LAS_DIR argument') # Only execute code if input ATL03 .h5 file and output path declared if (atl03FilePath and outFilePath): # Start timer timeStart = runTime.time() # Get beam # and S/W beamNum = GtToBeamNum(atl03FilePath, gtNum) beamStrength = GtToBeamSW(atl03FilePath, gtNum) # Print message writeLog( ' Ground Track Number: %s (Beam #%s, Beam Strength: %s)\n' % (gtNum, beamNum, beamStrength), logFileID) # Get ATL03 file path/name atl03FilePath = os.path.normpath(os.path.abspath(atl03FilePath)) atl03FileName = os.path.splitext(os.path.basename(atl03FilePath))[0] # Read ATL03 data from h5 file writeLog(' Reading ATL03 .h5 file: %s' % atl03FilePath, logFileID) lat_all = readAtl03H5(atl03FilePath, '/heights/lat_ph', gtNum) lon_all = readAtl03H5(atl03FilePath, '/heights/lon_ph', gtNum) z_all = readAtl03H5(atl03FilePath, '/heights/h_ph', gtNum) deltaTime_all = readAtl03H5(atl03FilePath, '/heights/delta_time', gtNum) signalConf_all = readAtl03H5(atl03FilePath, '/heights/signal_conf_ph', gtNum) zGeoidal = readAtl03H5(atl03FilePath, '/geophys_corr/geoid', gtNum) zGeoidal_deltaTime = readAtl03H5(atl03FilePath, '/geophys_corr/delta_time', gtNum) zGeoidal_all = interp_vals(zGeoidal_deltaTime, zGeoidal, deltaTime_all, removeThresh=True) zMsl_all = z_all - zGeoidal_all atl03_ph_index_beg, atl03_segment_id = readAtl03DataMapping( atl03FilePath, gtNum) badVars = [] if (len(lat_all) == 0): badVar = 'Latitude (lat_ph)' badVars.append(badVar) # endIf if (len(lon_all) == 0): badVar = 'Longitude (lon_ph)' badVars.append(badVar) # endIf if (len(z_all) == 0): badVar = 'Height (h_ph)' badVars.append(badVar) # endIf if (len(deltaTime_all) == 0): badVar = 'Delta Time (delta_time)' badVars.append(badVar) # endIf if (len(signalConf_all) == 0): badVar = 'Signal Confidence (signal_conf_ph)' badVars.append(badVar) # endIf if (len(badVars) == 0): # Get time from delta time min_delta_time = np.min(deltaTime_all) time_all = deltaTime_all - min_delta_time # Get track direction if (np.abs(lat_all[-1]) >= np.abs(lat_all[0])): trackDirection = 'Ascending' else: trackDirection = 'Descending' # endIf writeLog(' Track Direction: %s' % trackDirection, logFileID) # Extract metadata from ATL03 file name atl03h5Info = getNameParts(atl03FileName) # Map ATL08 to ATL03 ground photons if (atl08FilePath): # Get ATL08 file path/name atl08FilePath = os.path.normpath( os.path.abspath(atl08FilePath)) atl08FileName = os.path.splitext( os.path.basename(atl08FilePath))[0] atl08h5Info = getNameParts(atl08FileName) # Read ATL08 data from .h5 file writeLog(' Reading ATL08 .h5 file: %s' % atl08FilePath, logFileID) atl08_lat = readAtl08H5(atl08FilePath, '/land_segments/latitude', gtNum) atl08_lon = readAtl08H5(atl08FilePath, '/land_segments/longitude', gtNum) atl08_maxCanopy = readAtl08H5( atl08FilePath, '/land_segments/canopy/h_max_canopy_abs', gtNum) atl08_teBestFit = readAtl08H5( atl08FilePath, '/land_segments/terrain/h_te_best_fit', gtNum) atl08_teMedian = readAtl08H5( atl08FilePath, '/land_segments/terrain/h_te_median', gtNum) atl08_deltaTime = readAtl08H5(atl08FilePath, '/land_segments/delta_time', gtNum) atl08_zGeoidal = interp_vals(zGeoidal_deltaTime, zGeoidal, atl08_deltaTime, removeThresh=True) atl08_maxCanopyMsl = atl08_maxCanopy - atl08_zGeoidal atl08_teBestFitMsl = atl08_teBestFit - atl08_zGeoidal atl08_teMedianMsl = atl08_teMedian - atl08_zGeoidal atl08_classed_pc_indx, atl08_classed_pc_flag, atl08_segment_id = readAtl08DataMapping( atl08FilePath, gtNum) atl08_signalConf = np.zeros(np.size(atl08_lat)) atl08_classification = np.zeros(np.size(atl08_lat)) atl08_intensity = np.zeros(np.size(atl08_lat)) if ((len(atl08_lat) > 0) and (len(atl08_lon) > 0)): # Get time from delta time atl08_time = atl08_deltaTime - min_delta_time # Do ATL08 to ATL03 mapping writeLog(' Mapping ATL08 to ATL03 Ground Photons...', logFileID) try: classification_all = getAtl08Mapping( atl03_ph_index_beg, atl03_segment_id, atl08_classed_pc_indx, atl08_classed_pc_flag, atl08_segment_id) except: writeLog( ' WARNING: Could not map ATL08 to ATL03 Ground Photons.', logFileID) classification_all = atl08_classification # endTry # Get length to trim data by class_length = len(classification_all) lat_length = len(lat_all) data_length = np.min([class_length, lat_length]) # Trim ATL03 data down to size of classification array atl03_lat = lat_all[0:data_length] atl03_lon = lon_all[0:data_length] atl03_z = z_all[0:data_length] atl03_zMsl = zMsl_all[0:data_length] atl03_time = time_all[0:data_length] atl03_deltaTime = deltaTime_all[0:data_length] atl03_signalConf = signalConf_all[0:data_length] atl03_classification = classification_all[0:data_length] atl03_intensity = np.zeros(np.size(atl03_lat)) dataIsMapped = True else: writeLog( ' WARNING: ATL08 file does not contain usable data.', logFileID) atl08FilePath = False # Store data atl03_lat = lat_all atl03_lon = lon_all atl03_z = z_all atl03_zMsl = zMsl_all atl03_time = time_all atl03_deltaTime = deltaTime_all atl03_signalConf = signalConf_all atl03_classification = np.zeros(np.size(atl03_lat)) atl03_intensity = np.zeros(np.size(atl03_lat)) dataIsMapped = False # endIf else: # Message to screen writeLog(' Not Mapping ATL08 to ATL03 Ground Photons', logFileID) # Store data atl03_lat = lat_all atl03_lon = lon_all atl03_z = z_all atl03_zMsl = zMsl_all atl03_time = time_all atl03_deltaTime = deltaTime_all atl03_signalConf = signalConf_all atl03_classification = np.zeros(np.size(atl03_lat)) atl03_intensity = np.zeros(np.size(atl03_lat)) dataIsMapped = False # endIf # Get trim options trimParts = trimInfo.split(',') trimMode = trimParts[0] trimType = 'None' if (('manual' in trimMode.lower()) and (len(trimParts) > 1)): trimType = trimParts[1] trimMin = float(trimParts[2]) trimMax = float(trimParts[3]) # endIf # If selected to manually trim data, do this first if ('manual' in trimMode.lower()): # Trim by lat or time if ('lonlat' in trimType.lower()): lonMin, lonMax = float(trimParts[2]), float(trimParts[3]) latMin, latMax = float(trimParts[4]), float(trimParts[5]) writeLog( ' Manual Trim Mode (Min Lon: %s, Max Lon: %s)' % (lonMin, lonMax), logFileID) writeLog( ' Manual Trim Mode (Min Lat: %s, Max Lat: %s)' % (latMin, latMax), logFileID) atl03IndsToKeepLon = (atl03_lon >= lonMin) & (atl03_lon <= lonMax) atl03IndsToKeepLat = (atl03_lat >= latMin) & (atl03_lat <= latMax) atl03IndsToKeep = atl03IndsToKeepLon & atl03IndsToKeepLat if (atl08FilePath): atl08IndsToKeepLon = (atl08_lon >= lonMin) & (atl08_lon <= lonMax) atl08IndsToKeepLat = (atl08_lat >= latMin) & (atl08_lat <= latMax) atl08IndsToKeep = atl08IndsToKeepLon & atl08IndsToKeepLat elif ('lat' in trimType.lower()): writeLog( ' Manual Trim Mode (Min Lat: %s, Max Lat: %s)' % (trimMin, trimMax), logFileID) atl03IndsToKeep = (atl03_lat >= trimMin) & (atl03_lat <= trimMax) if (atl08FilePath): atl08IndsToKeep = (atl08_lat >= trimMin) & (atl08_lat <= trimMax) # endIf elif ('lon' in trimType.lower()): writeLog( ' Manual Trim Mode (Min Lon: %s, Max Lon: %s)' % (trimMin, trimMax), logFileID) atl03IndsToKeep = (atl03_lon >= trimMin) & (atl03_lon <= trimMax) if (atl08FilePath): atl08IndsToKeep = (atl03_lon >= trimMin) & (atl03_lon <= trimMax) # endIf elif ('time' in trimType.lower()): writeLog( ' Manual Trim Mode (Min Time: %s, Max Time: %s)' % (trimMin, trimMax), logFileID) atl03IndsToKeep = (atl03_time >= trimMin) & (atl03_time <= trimMax) if (atl08FilePath): atl08IndsToKeep = (atl08_time >= trimMin) & (atl08_time <= trimMax) # endIf else: writeLog( ' Manual Trim Mode is Missing Args, Not Trimming Data', logFileID) atl03IndsToKeep = np.ones(np.shape(atl03_lat), dtype=bool) if (atl08FilePath): atl08IndsToKeep = np.ones(np.shape(atl08_lat), dtype=bool) # endIf # endif # Trim ATL03 data if atl03IndsToKeep.sum() == 0: # no data left given manual constraints return atl03Data, atl08Data, headerData, rotationData # endIf atl03_lat = atl03_lat[atl03IndsToKeep] atl03_lon = atl03_lon[atl03IndsToKeep] atl03_z = atl03_z[atl03IndsToKeep] atl03_zMsl = atl03_zMsl[atl03IndsToKeep] atl03_time = atl03_time[atl03IndsToKeep] atl03_deltaTime = atl03_deltaTime[atl03IndsToKeep] atl03_signalConf = atl03_signalConf[atl03IndsToKeep] atl03_classification = atl03_classification[atl03IndsToKeep] atl03_intensity = atl03_intensity[atl03IndsToKeep] # Trim ATL08 data if (atl08FilePath): atl08_lat = atl08_lat[atl08IndsToKeep] atl08_lon = atl08_lon[atl08IndsToKeep] atl08_maxCanopy = atl08_maxCanopy[atl08IndsToKeep] atl08_teBestFit = atl08_teBestFit[atl08IndsToKeep] atl08_teMedian = atl08_teMedian[atl08IndsToKeep] atl08_maxCanopyMsl = atl08_maxCanopyMsl[atl08IndsToKeep] atl08_teBestFitMsl = atl08_teBestFitMsl[atl08IndsToKeep] atl08_teMedianMsl = atl08_teMedianMsl[atl08IndsToKeep] atl08_time = atl08_time[atl08IndsToKeep] atl08_deltaTime = atl08_deltaTime[atl08IndsToKeep] atl08_signalConf = atl08_signalConf[atl08IndsToKeep] atl08_classification = atl08_classification[ atl08IndsToKeep] atl08_intensity = atl08_intensity[atl08IndsToKeep] # endIf elif ('none' in trimMode.lower()): writeLog(' Trim Mode: None', logFileID) # endIf # Remove ATL08 points above 1e30 if (atl08FilePath): indsBelowThresh = (atl08_maxCanopy <= 1e30) | ( atl08_teBestFit <= 1e30) | (atl08_teMedian <= 1e30) atl08_lat = atl08_lat[indsBelowThresh] atl08_lon = atl08_lon[indsBelowThresh] atl08_maxCanopy = atl08_maxCanopy[indsBelowThresh] atl08_teBestFit = atl08_teBestFit[indsBelowThresh] atl08_teMedian = atl08_teMedian[indsBelowThresh] atl08_maxCanopyMsl = atl08_maxCanopyMsl[indsBelowThresh] atl08_teBestFitMsl = atl08_teBestFitMsl[indsBelowThresh] atl08_teMedianMsl = atl08_teMedianMsl[indsBelowThresh] atl08_time = atl08_time[indsBelowThresh] atl08_deltaTime = atl08_deltaTime[indsBelowThresh] atl08_signalConf = atl08_signalConf[indsBelowThresh] atl08_classification = atl08_classification[indsBelowThresh] atl08_intensity = atl08_intensity[indsBelowThresh] # endIf # If selected to auto trim data, then trim if truth region exists if ('auto' in trimMode.lower()): # Message to user writeLog(' Trim Mode: Auto', logFileID) # Read kmlBounds.txt file to get min/max extents to auto trim kmlBoundsTextFile = 'kmlBounds.txt' kmlRegionName = False if (os.path.exists(kmlBoundsTextFile)): # and not pklHeader: # Message to user writeLog(' Finding Reference Region...', logFileID) try: # Read kmlBounds.txt file and get contents kmlInfo = readTruthRegionsTxtFile(kmlBoundsTextFile) # Loop through kmlBounds.txt and find matching TRUTH area maxCounter = len(kmlInfo.regionName) counter = 0 while (not kmlRegionName): latInFile = ( atl03_lat >= kmlInfo.latMin[counter]) & ( atl03_lat <= kmlInfo.latMax[counter]) lonInFile = ( atl03_lon >= kmlInfo.lonMin[counter]) & ( atl03_lon <= kmlInfo.lonMax[counter]) trackInRegion = any(latInFile & lonInFile) if (trackInRegion): # Get truth region info kmlRegionName = kmlInfo.regionName[counter] kmlLatMin = kmlInfo.latMin[counter] kmlLatMax = kmlInfo.latMax[counter] kmlLonMin = kmlInfo.lonMin[counter] kmlLonMax = kmlInfo.lonMax[counter] # Print truth region writeLog( ' Reference File Region: %s' % kmlRegionName, logFileID) # endIf if (counter >= maxCounter): # Send message to user writeLog( ' No Reference File Region Found in kmlBounds.txt', logFileID) break # endIf # Increment counter counter += 1 # endWhile except: pass # endTry # endIf if (kmlRegionName): # Trim ATL03 data based on TRUTH region writeLog( ' Auto-Trimming Data Based on Reference Region...', logFileID) atl03IndsInRegion = (atl03_lat >= kmlLatMin) & ( atl03_lat <= kmlLatMax) & (atl03_lon >= kmlLonMin) & ( atl03_lon <= kmlLonMax) atl03_lat = atl03_lat[atl03IndsInRegion] atl03_lon = atl03_lon[atl03IndsInRegion] atl03_z = atl03_z[atl03IndsInRegion] atl03_zMsl = atl03_zMsl[atl03IndsInRegion] atl03_time = atl03_time[atl03IndsInRegion] atl03_deltaTime = atl03_deltaTime[atl03IndsInRegion] atl03_signalConf = atl03_signalConf[atl03IndsInRegion] atl03_classification = atl03_classification[ atl03IndsInRegion] atl03_intensity = atl03_intensity[atl03IndsInRegion] # Trim ATL08 data based on TRUTH region if (atl08FilePath): atl08IndsInRegion = (atl08_lat >= kmlLatMin) & ( atl08_lat <= kmlLatMax ) & (atl08_lon >= kmlLonMin) & (atl08_lon <= kmlLonMax) atl08_lat = atl08_lat[atl08IndsInRegion] atl08_lon = atl08_lon[atl08IndsInRegion] atl08_maxCanopy = atl08_maxCanopy[atl08IndsInRegion] atl08_teBestFit = atl08_teBestFit[atl08IndsInRegion] atl08_teMedian = atl08_teMedian[atl08IndsInRegion] atl08_maxCanopyMsl = atl08_maxCanopyMsl[ atl08IndsInRegion] atl08_teBestFitMsl = atl08_teBestFitMsl[ atl08IndsInRegion] atl08_teMedianMsl = atl08_teMedianMsl[ atl08IndsInRegion] atl08_time = atl08_time[atl08IndsInRegion] atl08_deltaTime = atl08_deltaTime[atl08IndsInRegion] atl08_signalConf = atl08_signalConf[atl08IndsInRegion] atl08_classification = atl08_classification[ atl08IndsInRegion] atl08_intensity = atl08_intensity[atl08IndsInRegion] #endIf # endIf # endIf # Convert lat/lon coordinates to UTM writeLog(' Converting Lat/Lon to UTM...', logFileID) # Allow function to determine UTM zone for ATL03 atl03_easting, atl03_northing, zone, hemi = getLatLon2UTM( atl03_lon, atl03_lat) # Allow function to determine UTM zone for ATL03 if (atl08FilePath): atl08_easting, atl08_northing, atl08_zone, atl08_hemi = getLatLon2UTM( atl08_lon, atl08_lat) # endIf # Print UTM zone writeLog(' UTM Zone: %s %s' % (zone, hemi), logFileID) # Transform MEASURED data to CT/AT plane writeLog(' Computing CT/AT Frame Rotation...', logFileID) desiredAngle = 90 atl03_crossTrack, atl03_alongTrack, R_mat, xRotPt, yRotPt, phi = getCoordRotFwd( atl03_easting, atl03_northing, [], [], [], desiredAngle) if (atl08FilePath): atl08_crossTrack, atl08_alongTrack, _, _, _, _ = getCoordRotFwd( atl08_easting, atl08_northing, R_mat, xRotPt, yRotPt, []) # endIf # Store rotation object rotationData = atlRotationStruct(R_mat, xRotPt, yRotPt, desiredAngle, phi) # Reassign class -1 to 0 (NOTE: this may need to change later) inds_eq_neg1 = atl03_classification == -1 atl03_classification[inds_eq_neg1] = 0 # Store data in class structure atl03Data = atl03Struct(atl03_lat, atl03_lon, \ atl03_easting, atl03_northing, \ atl03_crossTrack, atl03_alongTrack, \ atl03_z, \ atl03_zMsl, atl03_time, \ atl03_deltaTime, \ atl03_signalConf, atl03_classification, atl03_intensity, \ gtNum, beamNum, beamStrength, zone, hemi, \ atl03FilePath, atl03FileName, \ trackDirection, \ atl03h5Info, \ dataIsMapped) # Store data in class structure if (atl08FilePath): atl08Data = atl08Struct(atl08_lat, atl08_lon, \ atl08_easting, atl08_northing, \ atl08_crossTrack, atl08_alongTrack, \ atl08_maxCanopy, atl08_teBestFit, atl08_teMedian, \ atl08_maxCanopyMsl, atl08_teBestFitMsl, atl08_teMedianMsl, \ atl08_time, \ atl08_deltaTime, \ atl08_signalConf, atl08_classification, atl08_intensity, \ gtNum, atl08_zone, atl08_hemi, \ atl08FilePath, atl08FileName, \ trackDirection, \ atl08h5Info, \ dataIsMapped) # endIf # Create output ATL03 .las file if (createAtl03LasFile): writeLog(' Writing ATL03 .las file...', logFileID) outName = atl03Data.atl03FileName + '_' + atl03Data.gtNum + '.las' outPath = os.path.normpath(outFilePath + '/' + outName) # If output directory does not exist, create it if (not os.path.exists(os.path.normpath(outFilePath))): os.mkdir(os.path.normpath(outFilePath)) # EndIf # Get projection if (atl03Data.zone == '3413' or atl03Data.zone == '3976'): # NSIDC Polar Stereographic North/South cases (3413 = Arctic, 3976 = Antarctic) lasProjection = atl03Data.hemi # Write .las file writeLas(np.ravel(atl03Data.easting), np.ravel(atl03Data.northing), np.ravel(atl03Data.z), lasProjection, outPath, np.ravel(atl03Data.classification), np.ravel(atl03Data.intensity), np.ravel(atl03Data.signalConf)) else: # Write .las file for UTM projection case writeLas(np.ravel(atl03Data.easting), np.ravel(atl03Data.northing), np.ravel(atl03Data.z), 'utm', outPath, np.ravel(atl03Data.classification), np.ravel(atl03Data.intensity), np.ravel(atl03Data.signalConf), atl03Data.hemi, atl03Data.zone) # endIf # endIf # Create output ATL03 .kml file if (createAtl03KmlFile): writeLog(' Writing ATL03 .kml file...', logFileID) outName = atl03Data.atl03FileName + '_' + atl03Data.gtNum + '.kml' outPath = os.path.normpath(outFilePath + '/' + outName) # If output directory does not exist, create it if (not os.path.exists(os.path.normpath(outFilePath))): os.mkdir(os.path.normpath(outFilePath)) # EndIf # Get array of input time values timeStep = 1 # seconds timeVals = np.arange(np.min(atl03Data.time), np.max(atl03Data.time) + 1, timeStep) # Get closest time values from IceSat MEASURED data timeIn, indsToUse = getClosest(atl03Data.time, timeVals) # Reduce lat/lon values to user-specified time scale lonsIn = atl03Data.lon[indsToUse] latsIn = atl03Data.lat[indsToUse] # Write .kml file writeKml(latsIn, lonsIn, timeIn, outPath) # endIf # Create output ATL08 .kml file if (createAtl08KmlFile): if (atl08FilePath): writeLog(' Writing ATL08 .kml file...', logFileID) outName = atl08Data.atl08FileName + '_' + atl08Data.gtNum + '.kml' outPath = os.path.normpath(outFilePath + '/' + outName) # If output directory does not exist, create it if (not os.path.exists(os.path.normpath(outFilePath))): os.mkdir(os.path.normpath(outFilePath)) # EndIf # Get array of input time values timeStep = 1 # seconds timeVals = np.arange(np.min(atl08Data.time), np.max(atl08Data.time) + 1, timeStep) # Get closest time values from IceSat MEASURED data timeIn, indsToUse = getClosest(atl08Data.time, timeVals) # Reduce lat/lon values to user-specified time scale lonsIn = atl08Data.lon[indsToUse] latsIn = atl08Data.lat[indsToUse] # Write .kml file writeKml(latsIn, lonsIn, timeIn, outPath) # endIf # endIf # Create output ATL03 .csv file if (createAtl03CsvFile): writeLog(' Writing ATL03 .csv file...', logFileID) outName = atl03Data.atl03FileName + '_' + atl03Data.gtNum + '.csv' outPath = os.path.normpath(outFilePath + '/' + outName) # If output directory does not exist, create it if (not os.path.exists(os.path.normpath(outFilePath))): os.mkdir(os.path.normpath(outFilePath)) # EndIf # Write .csv file if (atl03Data.zone == '3413' or atl03Data.zone == '3976'): namelist = ['Time (sec)', 'Delta Time (sec)', \ 'Latitude (deg)', 'Longitude (deg)', \ 'Polar Stereo X (m)', 'Polar Stereo Y (m)', \ 'Cross-Track (m)', 'Along-Track (m)', \ 'Height (m HAE)', 'Height (m MSL)', \ 'Classification', 'Signal Confidence'] else: namelist = ['Time (sec)', 'Delta Time (sec)', \ 'Latitude (deg)', 'Longitude (deg)', \ 'Easting (m)', 'Northing (m)', \ 'Cross-Track (m)', 'Along-Track (m)', \ 'Height (m HAE)', 'Height (m MSL)', \ 'Classification', 'Signal Confidence'] # endIf datalist = [atl03Data.time, atl03Data.deltaTime, \ atl03Data.lat, atl03Data.lon, \ atl03Data.easting, atl03Data.northing, \ atl03Data.crossTrack, atl03Data.alongTrack,\ atl03Data.z, atl03Data.zMsl, \ atl03Data.classification, atl03Data.signalConf] writeArrayToCSV(outPath, namelist, datalist) # endIf # Create output ATL08 .csv file if (createAtl08CsvFile): if (atl08FilePath): writeLog(' Writing ATL08 .csv file...', logFileID) outName = atl08Data.atl08FileName + '_' + atl08Data.gtNum + '.csv' outPath = os.path.normpath(outFilePath + '/' + outName) # If output directory does not exist, create it if (not os.path.exists(os.path.normpath(outFilePath))): os.mkdir(os.path.normpath(outFilePath)) # EndIf # Write .csv file if (atl03Data.zone == '3413' or atl03Data.zone == '3976'): namelist = ['Time (sec)', 'Delta Time (sec)', \ 'Latitude (deg)', 'Longitude (deg)', \ 'Polar Stereo X (m)', 'Polar Stereo Y (m)', \ 'Cross-Track (m)', 'Along-Track (m)', \ 'Max Canopy (m)', \ 'Terrain Best Fit (m)', 'Terrain Median (m)'] else: namelist = ['Time (sec)', 'Delta Time (sec)', \ 'Latitude (deg)', 'Longitude (deg)', \ 'Easting (m)', 'Northing (m)', \ 'Cross-Track (m)', 'Along-Track (m)', \ 'Max Canopy (m)', \ 'Terrain Best Fit (m)', 'Terrain Median (m)'] # endIf datalist = [atl08Data.time, atl08Data.deltaTime, \ atl08Data.lat, atl08Data.lon, \ atl08Data.easting, atl08Data.northing, \ atl08Data.crossTrack, atl08Data.alongTrack,\ atl08Data.maxCanopy, \ atl08Data.teBestFit, atl08Data.teMedian] writeArrayToCSV(outPath, namelist, datalist) # endIf # endIf # End timer timeEnd = runTime.time() timeElapsedTotal = timeEnd - timeStart timeElapsedMin = np.floor(timeElapsedTotal / 60) timeElapsedSec = timeElapsedTotal % 60 # Print completion message writeLog('', logFileID) writeLog( ' Module Completed in %d min %d sec.' % (timeElapsedMin, timeElapsedSec), logFileID) writeLog('\n', logFileID) else: writeLog('\n', logFileID) writeLog(' *** Could not process data.', logFileID) writeLog(' *** ATL03 .h5 file missing these fields:', logFileID) for i in range(0, len(badVars)): writeLog(' %s) %s' % (i + 1, badVars[i]), logFileID) writeLog('\n', logFileID) # endIf else: # Message to user writeLog('Input correct ATL03 input .h5 file and/or output path.', logFileID) # endIf # Return object return atl03Data, atl08Data, rotationData
writeLog('', logFileID) writeLog( ' Module Completed in %d min %d sec.' % (timeElapsedMin, timeElapsedSec), logFileID) writeLog('\n', logFileID) # Return object return atlTruthData # endDef # Unit test if __name__ == "__main__": writeLog('GET ATL TRUTH SWATH (UNIT TEST):\n') ##### Start Inputs for getAtlMeasuredSwath # Path to ATL03 Input File # atl03FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL03_20181126114738_08990103_001_01.h5' # FINLAND # atl03FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL03_20181030110205_04860106_001_01.h5' # SONONMA # atl03FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL03_20190101195003_00670202_001_01_sreq_2696.h5' # SONOMA # atl03FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL03_20190228170214_09510202_001_02_sreq_2696.h5' # SONOMA # atl03FilePath = '//bigtex/laserpewpew/data/release/001/ATL03_r001/ATL03_20190426213703_04370308_001_01.h5' # Brazil # Path to ATL08 Input File # atl08FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL08_20181126114738_08990103_952_01.h5' # FINLAND # atl08FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL08_20181030110205_04860106_952_01.h5' # SONOMA # atl08FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL08_20190101195003_00670202_952_01.h5' # SONOMA # atl08FilePath = '//lidar-server/lidar/USERS/eric/benjelly_atl08/ATL08_20190228170214_09510202_952_02.h5' # SONOMA
# Only uses data between time 3 and 4 seconds createAtl03LasFile = False # Option to create output measured ATL03 .las file createAtl03KmlFile = False # Option to create output measured ATL03 .kml file createAtl08KmlFile = False # Option to create output measured ATL08 .kml file createAtl03CsvFile = False # Option to create output measured ATL03 .csv file createAtl08CsvFile = False # Option to create output measured ATL08 .csv file ##### End Inputs for getAtlMeasuredSwath ##### CODE BELOW -- DO NOT EDIT ############################################### timeStart = runTime.time() # Call getAtlMeasuredSwath writeLog('RUNNING getAtlMeasuredSwath...\n') atl03Data, atl08Data, rotationData = getAtlMeasuredSwath( atl03FilePath, atl08FilePath, outFilePath, gtNum, trimInfo, createAtl03LasFile, createAtl03KmlFile, createAtl08KmlFile, createAtl03CsvFile, createAtl08CsvFile) # End timer timeEnd = runTime.time() timeElapsedTotal = timeEnd - timeStart timeElapsedMin = np.floor(timeElapsedTotal / 60) timeElapsedSec = timeElapsedTotal % 60 # Print completion message writeLog(' Script Completed in %d min %d sec.' % (timeElapsedMin, timeElapsedSec)) writeLog('\n')