PRO read_lvis2, data, file=file, header=header, quiet=quiet ; ; IDL code to read in all LVIS Level-2 release files: ; v1.04, v1.05, v2.0.1, v2.0.2, v2.0.3, v2.0.4, v2.0.5 ; ; INPUT: ; ====== ; FILE: LVIS Level-2 .TXT file to read in; if this parameter is not present, a popup box ; will appear and offer to select a file with a .TXT extension ; ; OUTPUT: ; ======= ; DATA: data returned as a structure ; HEADER: header lines returned (text) ; ; 2026-03-19 HGC ; Land, Vegetation, and Ice Sensor (LVIS) Team ; http://lvis.gsfc.nasa.gov/ ; ; EXAMPLE USAGE: ; read_lvis2, data, file=lvis2_file, /quiet ; ; Ice surfaces 2009-2015 (IceBridge) lvis_level2_v104 = { $ lvis_lfid: 0ul, $ ; LVIS file identification shotnumber: 0ul, $ ; Laser shot assigned during collection time: 0.0d, $ ; UTC decimal seconds of the day longitude_centroid: 0.0d, $ ; Centroid longitude of the corresponding Level-1B waveform latitude_centroid: 0.0d, $ ; Centroid latitude of the corresponding Level-1B waveform elevation_centroid: 0.0d, $ ; Centroid elevation of the corresponding Level-1B waveform longitude_low: 0.0d, $ ; Longitude of the lowest detected mode within the waveform latitude_low: 0.0d, $ ; Latitude of the lowest detected mode within the waveform elevation_low: 0.0d, $ ; Mean elevation of the lowest detected mode within the waveform longitude_high: 0.0d, $ ; Longitude of the center of the highest mode in the waveform latitude_high: 0.0d, $ ; Latitude of the center of the highest mode in the waveform elevation_high: 0.0d} ; Elevation of the center of the highest mode in the waveform ; Land surfaces 1997-2009 rereleased lvis_level2_v105 = { $ lfid: 0UL, $ shotnumber: 0UL, $ date: 0L, $ time: 0.0D, $ glon: 0.0D, $ glat: 0.0D, $ zg: 0.0, $ tlon: 0.0D, $ tlat: 0.0D, $ zt: 0.0, $ rh25: 0.0, $ rh50: 0.0, $ rh75: 0.0, $ rh100: 0.0, $ azimuth: 0.0, $ incidentangle: 0.0, $ range: 0.0 $ } ; Land surfaces 2018+ lvis_level2_v203 = { $ lfid: 0UL, $ shotnumber: 0UL, $ time: 0.0D, $ glon: 0.0D, $ glat: 0.0D, $ zg: 0.0, $ hlon: 0.0D, $ hlat: 0.0D, $ zh: 0.0, $ tlon: 0.0D, $ tlat: 0.0D, $ zt: 0.0, $ rh10: 0.0, $ rh15: 0.0, $ rh20: 0.0, $ rh25: 0.0, $ rh30: 0.0, $ rh35: 0.0, $ rh40: 0.0, $ rh45: 0.0, $ rh50: 0.0, $ rh55: 0.0, $ rh60: 0.0, $ rh65: 0.0, $ rh70: 0.0, $ rh75: 0.0, $ rh80: 0.0, $ rh85: 0.0, $ rh90: 0.0, $ rh95: 0.0, $ rh96: 0.0, $ rh97: 0.0, $ rh98: 0.0, $ rh99: 0.0, $ rh100: 0.0, $ azimuth: 0.0, $ incidentangle: 0.0, $ range: 0.0, $ complexity: 0.0, $ sensitivity: 0.0, $ channel_zt: 0, $ channel_zg: 0, $ channel_rh: 0 $ } ; Ice surfaces 2022+ lvis_level2_v204 = { $ lfid: 0UL, $ shotnumber: 0UL, $ time: 0.0D, $ lonlo: 0.0D, $ latlo: 0.0D, $ zlo: 0.0, $ lonmx: 0.0D, $ latmx: 0.0D, $ zmx: 0.0, $ lonhi: 0.0D, $ lathi: 0.0D, $ zhi: 0.0, $ lonlo_alt: 0.0D, $ latlo_alt: 0.0D, $ zlo_alt: 0.0, $ azimuth: 0.0, $ incidentangle: 0.0, $ range: 0.0, $ complexity: 0.0, $ sensitivity: 0.0, $ energy1: 0.0, $ energy2: 0.0, $ energy3: 0.0, $ bestwave: 0 $ } ; BioSCape 2023 lvis_level2_v205 = { $ lfid: 0UL, $ shotnumber: 0UL, $ time: 0.0D, $ glon: 0.0D, $ glat: 0.0D, $ zg: 0.0, $ zg_alt1: 0.0, $ ; v2.0.5 zg_alt2: 0.0, $ ; v2.0.5 hlon: 0.0D, $ hlat: 0.0D, $ zh: 0.0, $ tlon: 0.0D, $ tlat: 0.0D, $ zt: 0.0, $ rh10: 0.0, $ rh15: 0.0, $ rh20: 0.0, $ rh25: 0.0, $ rh30: 0.0, $ rh35: 0.0, $ rh40: 0.0, $ rh45: 0.0, $ rh50: 0.0, $ rh55: 0.0, $ rh60: 0.0, $ rh65: 0.0, $ rh70: 0.0, $ rh75: 0.0, $ rh80: 0.0, $ rh85: 0.0, $ rh90: 0.0, $ rh95: 0.0, $ rh96: 0.0, $ rh97: 0.0, $ rh98: 0.0, $ rh99: 0.0, $ rh100: 0.0, $ azimuth: 0.0, $ incidentangle: 0.0, $ range: 0.0, $ complexity: 0.0, $ sensitivity: 0.0, $ channel_zt: 0, $ channel_zg: 0, $ channel_rh: 0 $ } ; Gabon 2016, first release, defunct format lvis_level2_defunct = { $ lfid: 0UL, $ shotnumber: 0UL, $ time: 0.0D, $ glon: 0.0D, $ glat: 0.0D, $ zg: 0.0, $ tlon: 0.0D, $ tlat: 0.0D, $ zt: 0.0, $ rh10: 0.0, $ rh15: 0.0, $ rh20: 0.0, $ rh25: 0.0, $ rh30: 0.0, $ rh35: 0.0, $ rh40: 0.0, $ rh45: 0.0, $ rh50: 0.0, $ rh55: 0.0, $ rh60: 0.0, $ rh65: 0.0, $ rh70: 0.0, $ rh75: 0.0, $ rh80: 0.0, $ rh85: 0.0, $ rh90: 0.0, $ rh95: 0.0, $ rh96: 0.0, $ rh97: 0.0, $ rh98: 0.0, $ rh99: 0.0, $ rh100: 0.0, $ azimuth: 0.0, $ incidentangle: 0.0, $ range: 0.0, $ channel_zt: 0, $ channel_zg: 0, $ channel_rh: 0 $ } ; Gabon 2016 (2nd release 2018) & Greenland 2017 lvis_level2_v201 = { $ lfid: 0UL, $ shotnumber: 0UL, $ time: 0.0D, $ glon: 0.0D, $ glat: 0.0D, $ zg: 0.0, $ hlon: 0.0D, $ ; removed for v2.0.2 hlat: 0.0D, $ ; removed for v2.0.2 zh: 0.0, $ ; removed for v2.0.2 tlon: 0.0D, $ tlat: 0.0D, $ zt: 0.0, $ rh10: 0.0, $ rh15: 0.0, $ rh20: 0.0, $ rh25: 0.0, $ rh30: 0.0, $ rh35: 0.0, $ rh40: 0.0, $ rh45: 0.0, $ rh50: 0.0, $ rh55: 0.0, $ rh60: 0.0, $ rh65: 0.0, $ rh70: 0.0, $ rh75: 0.0, $ rh80: 0.0, $ rh85: 0.0, $ rh90: 0.0, $ rh95: 0.0, $ rh96: 0.0, $ rh97: 0.0, $ rh98: 0.0, $ rh99: 0.0, $ rh100: 0.0, $ azimuth: 0.0, $ incidentangle: 0.0, $ range: 0.0, $ complexity: 0.0, $ channel_zt: 0, $ channel_zg: 0, $ channel_rh: 0 $ } ; ABoVE 2017 lvis_level2_v202 = { $ lfid: 0UL, $ shotnumber: 0UL, $ time: 0.0D, $ glon: 0.0D, $ glat: 0.0D, $ zg: 0.0, $ tlon: 0.0D, $ tlat: 0.0D, $ zt: 0.0, $ rh10: 0.0, $ rh15: 0.0, $ rh20: 0.0, $ rh25: 0.0, $ rh30: 0.0, $ rh35: 0.0, $ rh40: 0.0, $ rh45: 0.0, $ rh50: 0.0, $ rh55: 0.0, $ rh60: 0.0, $ rh65: 0.0, $ rh70: 0.0, $ rh75: 0.0, $ rh80: 0.0, $ rh85: 0.0, $ rh90: 0.0, $ rh95: 0.0, $ rh96: 0.0, $ rh97: 0.0, $ rh98: 0.0, $ rh99: 0.0, $ rh100: 0.0, $ azimuth: 0.0, $ incidentangle: 0.0, $ range: 0.0, $ complexity: 0.0, $ channel_zt: 0, $ channel_zg: 0, $ channel_rh: 0 $ } ; select input file if keyword_set(file) then begin if (file_test(file) eq 1) then begin infile = file endif else begin infile = dialog_pickfile(/read, filter='*.TXT') if (infile eq '') then begin print, 'File not found' RETURN endif endelse endif else begin infile = dialog_pickfile(/read, filter='*.TXT') if (infile eq '') then begin print, 'File not found' RETURN endif endelse if not keyword_set(quiet) then print, 'Reading in LVIS LEVEL-2 file: ', infile nline = file_lines(infile) ndata = nline strline='' lflag=0 openr, lun, infile, /get_lun ; count the number of header lines while ((lflag eq 0) and (eof(lun) eq 0)) do begin readf, lun, strline test = byte(strmid(strline, 0, 1)) if (test ge 48 and test le 57) then begin ; line starts with a number (data) lflag = 1 ntags=n_elements(strsplit(strline,/extract)) endif else begin ; line does not start with a number (header) ndata = ndata - 1L endelse endwhile close, lun if (ndata eq 0) then begin print, 'This is not an LVIS Level2 release file: ',infile RETURN endif case 1 of ; v104: IceBridge 2009-2015 ntags eq 12: begin lvis_level2_data=lvis_level2_v104 if not keyword_set(quiet) then print, 'LDS v1.04: Ice surfaces 2009-2015 (IceBridge)' end ; v105: Rereleases of 1998-2009 ntags eq 17: begin lvis_level2_data=lvis_level2_v105 if not keyword_set(quiet) then print, 'LDS v1.05: Land surfaces 1997-2009 rereleased' end ; DEFUNCT: Gabon first release ntags eq 38: begin lvis_level2_data=lvis_level2_defunct print, '*********************************************************' print, '*****' print, '***** WARNING: THIS IS AN OLD RELEASE OF GABON 2016 *****' print, '*****' print, '***** Please download the lastest release here:' print, '***** https://search.earthdata.nasa.gov/search?q=AFLVIS2' print, '*****' print, '*********************************************************' end ; v201: Gabon 2016 (2nd release 2018) & Greenland 2017 ntags eq 42: begin lvis_level2_data=lvis_level2_v201 if not keyword_set(quiet) then print, 'LDS v2.0.1: Gabon 2016 (2nd release 2018) & Greenland 2017' end ; v202: ABoVE 2017 ntags eq 39: begin lvis_level2_data=lvis_level2_v202 if not keyword_set(quiet) then print, 'LDS v2.0.2: ABoVE 2017' end ; v203: Land surfaces 2019+ ntags eq 43: begin lvis_level2_data=lvis_level2_v203 if not keyword_set(quiet) then print, 'LDS v2.0.3: Land surfaces 2019+' end ; v204: Ice surfaces 2019+ ntags eq 24: begin lvis_level2_data=lvis_level2_v204 if not keyword_set(quiet) then print, 'LDS v2.0.4: Ice surfaces 2022+' end ; v205: BioSCape 2023 ntags eq 45: begin lvis_level2_data=lvis_level2_v205 if not keyword_set(quiet) then print, 'LDS v2.0.5: BioSCape 2023' end else: begin print, 'This file does not have the standard number of columns for any current LVIS Level-2 release: ', infile print, 'First line of data: ', strline print, 'Number of columns: ', strtrim(ntags,2) return end endcase openr, lun, infile nhdr = nline - ndata if (nhdr gt 0) then begin header = strarr(nhdr) readf, lun, header endif data = replicate(lvis_level2_data, ndata) readf, lun, data close, lun free_lun, lun END