From 3335cc66ce2adc68aedfc8b088bf837e1f65157e Mon Sep 17 00:00:00 2001 From: bhass-neon Date: Fri, 26 Jan 2024 11:39:00 -0700 Subject: [PATCH] minor updates --- .../Plot-Hyperspectral-Spectra.Rmd | 19 +- .../Plot-Hyperspectral-Spectra.html | 768 ++++++++++++------ .../Plot-Hyperspectral-Spectra.md | 186 ++--- 3 files changed, 599 insertions(+), 374 deletions(-) diff --git a/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.Rmd b/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.Rmd index 2aaca0e63..c0e308adf 100755 --- a/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.Rmd +++ b/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.Rmd @@ -8,7 +8,7 @@ description: Extract a single pixel's worth of spectra from a hyperspectral data estimatedTime: 1.0 - 1.5 Hours languagesTool: R dataProduct: DP3.30006.001 -packagesLibraries: rhdf5, raster, rgdal, plyr +packagesLibraries: rhdf5, terra, plyr authors: Leah A. Wasser, Donal O'Leary topics: hyperspectral, HDF5, remote-sensing tutorialSeries: null @@ -93,18 +93,17 @@ before moving on to this tutorial. Everything on our planet reflects electromagnetic radiation from the Sun, and different types of land cover often have dramatically different refelectance properties across the spectrum. One of the most powerful aspects of the NEON -Imaging Spectrometer (a.k.a. NEON's hyperspectral imager) is that it can +Imaging Spectrometer (NIS, or hyperspectral sensor) is that it can accurately measure these reflectance properties at a very high spectral resolution. When you plot the reflectance values across the observed spectrum, you will see that different land cover types (vegetation, pavement, bare soils, etc.) have -distinct patterns in their reflectance values, a feature that we call the +distinct patterns in their reflectance values, a property that we call the 'spectral signature' of a particular land cover class. -In this tutorial, we will extract a single pixel's worth of reflectance -values to plot a spectral signature for that pixel. In order to plot the -spectral signature for a given pixel in this hyperspectral dataset, we will -need to extract the reflectance values for that pixel, and pair those with the -wavelengths that are represented in those measurements. We will also need to +In this tutorial, we will extract the reflectance values for all bands of a +single pixel to plot a spectral signature for that pixel. In order to do this, +we need to pair the reflectance values for that pixel with the wavelength values +of the bands that are represented in those measurements. We will also need to adjust the reflectance values by the scaling factor that is saved as an 'attribute' in the HDF5 file. First, let's start by defining the working directory and reading in the example dataset. @@ -118,12 +117,12 @@ library(ggplot2) # set working directory to ensure R can find the file we wish to import and where # we want to save our files. Be sure to move the download into your working directory! -wd <- "~/Documents/data/" #This will depend on your local environment +wd <- "~/data/" #This will depend on your local environment setwd(wd) ``` -Now, we need to access the H5 file. +Now, we can look at the contents of the H5 file as follows: ```{r open-H5-file } diff --git a/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.html b/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.html index 1aed1f983..6e92adc82 100644 --- a/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.html +++ b/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.html @@ -1,270 +1,493 @@ + + - -Read Wavelength Values + + + - + + + + + + + + + + -body { - max-width: 800px; - margin: auto; - padding: 1em; - line-height: 20px; + + -tt, code, pre { - font-family: 'DejaVu Sans Mono', 'Droid Sans Mono', 'Lucida Console', Consolas, Monaco, monospace; -} -h1 { - font-size:2.2em; -} -h2 { - font-size:1.8em; -} -h3 { - font-size:1.4em; -} -h4 { - font-size:1.0em; -} -h5 { - font-size:0.9em; -} -h6 { - font-size:0.8em; -} -a:visited { - color: rgb(50%, 0%, 50%); -} -pre, img { - max-width: 100%; + -code { - font-size: 92%; - border: 1px solid #ccc; -} -code[class] { - background-color: #F8F8F8; -} -table, td, th { - border: none; -} + -blockquote { - color:#666666; - margin:0; - padding-left: 1em; - border-left: 0.5em #EEE solid; + + - - - -
- -## Learning Objectives -After completing this tutorial, you will be able to: -* Extract and plot a single spectral signature from an HDF5 file. -* Work with groups and datasets within an HDF5 file. + -## Things You’ll Need To Complete This Tutorial -To complete this tutorial you will need the most current version of R and, -preferably, RStudio loaded on your computer. + -### R Libraries to Install: -* **rhdf5**: install.packages(“BiocManager”), BiocManager::install(“rhdf5”) -* **plyr**: install.packages(‘plyr’) -* **ggplot2**: install.packages(‘ggplot2’) +
- More on Packages in - R - Adapted from Software Carpentry. -### Data to Download -{% include/dataSubsets/_data_Imaging-Spec-Data-H5-2020.html %} -*** -{% include/_greyBox-wd-rscript.html %} + +

Plot Spectral Signatures Derived from +Hyperspectral Remote Sensing Data in HDF5 Format in R

-

Everything on our planet reflects electromagnetic radiation from the Sun, and -different types of land cover often have dramatically different refelectance -properties across the spectrum. One of the most powerful aspects of the NEON -Imaging Spectrometer (a.k.a. NEON's hyperspectral imager) is that it can -accurately measure these reflectance properties at a very high spectral resolution. -When you plot the reflectance values across the observed spectrum, you will see -that different land cover types (vegetation, pavement, bare soils, etc.) have -distinct patterns in their reflectance values, a feature that we call the -'spectral signature' of a particular land cover class.

+
-

In this tutorial, we will extract a single pixel's worth of reflectance -values to plot a spectral signature for that pixel. In order to plot the -spectral signature for a given pixel in this hyperspectral dataset, we will -need to extract the reflectance values for that pixel, and pair those with the -wavelengths that are represented in those measurements. We will also need to -adjust the reflectance values by the scaling factor that is saved as an -'attribute' in the HDF5 file. First, let's start by defining the working -directory and reading in the example dataset.

-
# Call required packages
+
+
+

Learning Objectives

+

After completing this tutorial, you will be able to:

+
    +
  • Extract and plot a single spectral signature from an HDF5 file.
  • +
  • Work with groups and datasets within an HDF5 file.
  • +
+
+
+

Things You’ll Need To Complete This Tutorial

+

To complete this tutorial you will need the most current version of R +and, preferably, RStudio loaded on your computer.

+
+

R Libraries to Install:

+
    +
  • rhdf5: +install.packages("BiocManager"), +BiocManager::install("rhdf5")
  • +
  • plyr: install.packages('plyr')
  • +
  • ggplot2: +install.packages('ggplot2')
  • +
+

+More on Packages in R - Adapted from Software Carpentry.

+
+
+

Data to Download

+

+ Download NEON +Teaching Data Subset: Imaging Spectrometer Data - HDF5 +

+

These hyperspectral remote sensing data provide information on the + National +Ecological Observatory Network’s + +San Joaquin Exerimental Range field site in March of 2019. The data +were collected over the San Joaquin field site located in California +(Domain 17) and processed at NEON headquarters. This data subset is +derived from the mosaic tile named +NEON_D17_SJER_DP3_257000_4112000_reflectance.h5. The entire dataset can +be accessed by request from the + NEON Data +Portal.

+

+Download Dataset

+

Remember that the example dataset linked here only +has 1 out of every 4 bands included in a full NEON hyperspectral dataset +(this substantially reduces the file size!). When we refer to bands in +this tutorial, we will note the band numbers for this example dataset, +which are different from NEON production data. To convert a band number +(b) from this example data subset to the equivalent band in a full NEON +hyperspectral file (b’), use the following equation: b’ = 1+4*(b-1).

+
+

Set Working Directory: This lesson assumes that you +have set your working directory to the location of the downloaded and +unzipped data subsets.

+

+An overview of setting the working directory in R can be found +here.

+

R Script & Challenge Code: NEON data lessons +often contain challenges that reinforce learned skills. If available, +the code for challenge solutions is found in the downloadable R script +of the entire lesson, available in the footer of each lesson page.

+
+
+ +
+
+

Everything on our planet reflects electromagnetic radiation from the +Sun, and different types of land cover often have dramatically different +refelectance properties across the spectrum. One of the most powerful +aspects of the NEON Imaging Spectrometer (NIS, or hyperspectral sensor) +is that it can accurately measure these reflectance properties at a very +high spectral resolution. When you plot the reflectance values across +the observed spectrum, you will see that different land cover types +(vegetation, pavement, bare soils, etc.) have distinct patterns in their +reflectance values, a property that we call the ‘spectral signature’ of +a particular land cover class.

+

In this tutorial, we will extract the reflectance values for all +bands of a single pixel to plot a spectral signature for that pixel. In +order to do this, we need to pair the reflectance values for that pixel +with the wavelength values of the bands that are represented in those +measurements. We will also need to adjust the reflectance values by the +scaling factor that is saved as an ‘attribute’ in the HDF5 file. First, +let’s start by defining the working directory and reading in the example +dataset.

+
# Call required packages
 library(rhdf5)
 library(plyr)
 library(ggplot2)
 
 # set working directory to ensure R can find the file we wish to import and where
 # we want to save our files. Be sure to move the download into your working directory!
-wd <- "~/Documents/data/" #This will depend on your local environment
-setwd(wd)
-
- -

Now, we need to access the H5 file.

- -
# Define the file name to be opened
+wd <- "~/data/" #This will depend on your local environment
+setwd(wd)
+

Now, we can look at the contents of the H5 file as follows:

+
# Define the file name to be opened
 f <- paste0(wd,"NEON_hyperspectral_tutorial_example_subset.h5")
 # look at the HDF5 file structure 
-h5ls(f,all=T) 
-
-##                                           group                     name         ltype
-## 0                                             /                     SJER H5L_TYPE_HARD
-## 1                                         /SJER              Reflectance H5L_TYPE_HARD
-## 2                             /SJER/Reflectance                 Metadata H5L_TYPE_HARD
-## 3                    /SJER/Reflectance/Metadata        Coordinate_System H5L_TYPE_HARD
-## 4  /SJER/Reflectance/Metadata/Coordinate_System Coordinate_System_String H5L_TYPE_HARD
-## 5  /SJER/Reflectance/Metadata/Coordinate_System                EPSG Code H5L_TYPE_HARD
-## 6  /SJER/Reflectance/Metadata/Coordinate_System                 Map_Info H5L_TYPE_HARD
-## 7  /SJER/Reflectance/Metadata/Coordinate_System                    Proj4 H5L_TYPE_HARD
-## 8                    /SJER/Reflectance/Metadata            Spectral_Data H5L_TYPE_HARD
-## 9      /SJER/Reflectance/Metadata/Spectral_Data               Wavelength H5L_TYPE_HARD
-## 10                            /SJER/Reflectance         Reflectance_Data H5L_TYPE_HARD
-##    corder_valid corder cset       otype num_attrs  dclass          dtype  stype rank
-## 0         FALSE      0    0   H5I_GROUP         0                                  0
-## 1         FALSE      0    0   H5I_GROUP         5                                  0
-## 2         FALSE      0    0   H5I_GROUP         0                                  0
-## 3         FALSE      0    0   H5I_GROUP         0                                  0
-## 4         FALSE      0    0 H5I_DATASET         0  STRING     H5T_STRING SIMPLE    1
-## 5         FALSE      0    0 H5I_DATASET         0  STRING     H5T_STRING SIMPLE    1
-## 6         FALSE      0    0 H5I_DATASET         1  STRING     H5T_STRING SIMPLE    1
-## 7         FALSE      0    0 H5I_DATASET         0  STRING     H5T_STRING SIMPLE    1
-## 8         FALSE      0    0   H5I_GROUP         0                                  0
-## 9         FALSE      0    0 H5I_DATASET         3   FLOAT H5T_IEEE_F64LE SIMPLE    1
-## 10        FALSE      0    0 H5I_DATASET        13 INTEGER  H5T_STD_I32LE SIMPLE    3
+h5ls(f,all=T) 
+
##                                           group                     name
+## 0                                             /                     SJER
+## 1                                         /SJER              Reflectance
+## 2                             /SJER/Reflectance                 Metadata
+## 3                    /SJER/Reflectance/Metadata        Coordinate_System
+## 4  /SJER/Reflectance/Metadata/Coordinate_System Coordinate_System_String
+## 5  /SJER/Reflectance/Metadata/Coordinate_System                EPSG Code
+## 6  /SJER/Reflectance/Metadata/Coordinate_System                 Map_Info
+## 7  /SJER/Reflectance/Metadata/Coordinate_System                    Proj4
+## 8                    /SJER/Reflectance/Metadata            Spectral_Data
+## 9      /SJER/Reflectance/Metadata/Spectral_Data               Wavelength
+## 10                            /SJER/Reflectance         Reflectance_Data
+##            ltype cset       otype num_attrs  dclass          dtype  stype rank
+## 0  H5L_TYPE_HARD    0   H5I_GROUP         0                                  0
+## 1  H5L_TYPE_HARD    0   H5I_GROUP         5                                  0
+## 2  H5L_TYPE_HARD    0   H5I_GROUP         0                                  0
+## 3  H5L_TYPE_HARD    0   H5I_GROUP         0                                  0
+## 4  H5L_TYPE_HARD    0 H5I_DATASET         0  STRING     H5T_STRING SIMPLE    1
+## 5  H5L_TYPE_HARD    0 H5I_DATASET         0  STRING     H5T_STRING SIMPLE    1
+## 6  H5L_TYPE_HARD    0 H5I_DATASET         1  STRING     H5T_STRING SIMPLE    1
+## 7  H5L_TYPE_HARD    0 H5I_DATASET         0  STRING     H5T_STRING SIMPLE    1
+## 8  H5L_TYPE_HARD    0   H5I_GROUP         0                                  0
+## 9  H5L_TYPE_HARD    0 H5I_DATASET         2   FLOAT H5T_IEEE_F64LE SIMPLE    1
+## 10 H5L_TYPE_HARD    0 H5I_DATASET        13 INTEGER  H5T_STD_I32LE SIMPLE    3
 ##                dim          maxdim
 ## 0                                 
 ## 1                                 
@@ -276,27 +499,23 @@
 ## 7                1               1
 ## 8                                 
 ## 9              107             107
-## 10 107 x 500 x 500 107 x 500 x 500
-
- +## 10 107 x 500 x 500 107 x 500 x 500
+

Read Wavelength Values

- -

Next, let's read in the wavelength center associated with each band in the HDF5 -file. We will later match these with the reflectance values and show both in -our final spectral signature plot.

- -
# read in the wavelength information from the HDF5 file
-wavelengths <- h5read(f,"/SJER/Reflectance/Metadata/Spectral_Data/Wavelength")
-
- +

Next, let’s read in the wavelength center associated with each band +in the HDF5 file. We will later match these with the reflectance values +and show both in our final spectral signature plot.

+
# read in the wavelength information from the HDF5 file
+wavelengths <- h5read(f,"/SJER/Reflectance/Metadata/Spectral_Data/Wavelength")
+
+

Extract Z-dimension data slice

- -

Next, we will extract all reflectance values for one pixel. This makes up the -spectral signature or profile of the pixel. To do that, we'll use the h5read() -function. Here we pick an arbitrary pixel at (100,35), and use the NULL -value to select all bands from that location.

- -
# extract all bands from a single pixel
+

Next, we will extract all reflectance values for one pixel. This +makes up the spectral signature or profile of the pixel. To do that, +we’ll use the h5read() function. Here we pick an arbitrary +pixel at (100,35), and use the NULL value to +select all bands from that location.

+
# extract all bands from a single pixel
 aPixel <- h5read(f,"/SJER/Reflectance/Reflectance_Data",index=list(NULL,100,35))
 
 # The line above generates a vector of reflectance values.
@@ -309,26 +528,25 @@ 

Extract Z-dimension data slice

# add wavelength data to matrix aPixeldf$Wavelength <- wavelengths -head(aPixeldf) - -## V1 Wavelength +head(aPixeldf)
+
##    V1 Wavelength
 ## 1 720   381.5437
 ## 2 337   401.5756
 ## 3 336   421.6075
 ## 4 399   441.6394
 ## 5 406   461.6713
-## 6 426   481.7032
-
- +## 6 426 481.7032
+
+

Scale Factor

- -

Then, we can pull the spatial attributes that we'll need to adjust the reflectance -values. Often, large raster data contain floating point (values with decimals) information. -However, floating point data consume more space (yield a larger file size) compared -to integer values. Thus, to keep the file sizes smaller, the data will be scaled -by a factor of 10, 100, 10000, etc. This scale factor will be noted in the data attributes.

- -
# grab scale factor from the Reflectance attributes
+

Then, we can pull the spatial attributes that we’ll need to adjust +the reflectance values. Often, large raster data contain floating point +(values with decimals) information. However, floating point data consume +more space (yield a larger file size) compared to integer values. Thus, +to keep the file sizes smaller, the data will be scaled by a factor of +10, 100, 10000, etc. This scale factor will be noted in the +data attributes.

+
# grab scale factor from the Reflectance attributes
 reflectanceAttr <- h5readAttributes(f,"/SJER/Reflectance/Reflectance_Data" )
 
 scaleFact <- reflectanceAttr$Scale_Factor
@@ -338,29 +556,75 @@ 

Scale Factor

# make nice column names names(aPixeldf) <- c('Reflectance','Wavelength','ScaledReflectance') -head(aPixeldf) - -## Reflectance Wavelength ScaledReflectance +head(aPixeldf)
+
##   Reflectance Wavelength ScaledReflectance
 ## 1         720   381.5437            0.0720
 ## 2         337   401.5756            0.0337
 ## 3         336   421.6075            0.0336
 ## 4         399   441.6394            0.0399
 ## 5         406   461.6713            0.0406
-## 6         426   481.7032            0.0426
-
- +## 6 426 481.7032 0.0426
+
+

Plot Spectral Signature

- -

Now we're ready to plot our spectral signature!

- -
ggplot(data=aPixeldf)+
+

Now we’re ready to plot our spectral signature!

+
ggplot(data=aPixeldf)+
    geom_line(aes(x=Wavelength, y=ScaledReflectance))+
    xlab("Wavelength (nm)")+
-   ylab("Reflectance")
-
+ ylab("Reflectance")
+
+Spectral signature plot with wavelength in nanometers on the x-axis and reflectance on the y-axis. +

+Spectral signature plot with wavelength in nanometers on the x-axis and +reflectance on the y-axis. +

+
+
-

- + +
+ + + + + + + + + + + + + + diff --git a/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.md b/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.md index 0f352656f..c0e308adf 100644 --- a/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.md +++ b/tutorials/R/AOP/Hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.md @@ -2,13 +2,13 @@ syncID: 79f902f6c0264f16a9be13f50560860a title: "Plot Spectral Signatures Derived from Hyperspectral Remote Sensing Data in HDF5 Format in R" code1: https://raw.githubusercontent.com/NEONScience/NEON-Data-Skills/main/tutorials/R/Hyperspectral/Intro-hyperspectral/Plot-Hyperspectral-Spectra/Plot-Hyperspectral-Spectra.R -contributors: null +contributors: Felipe Sanchez dateCreated: 2015-08-08 20:49:52 description: Extract a single pixel's worth of spectra from a hyperspectral dataset stored in HDF5 format in R. Visualize the spectral signature. estimatedTime: 1.0 - 1.5 Hours languagesTool: R -dataProduct: null -packagesLibraries: rhdf5, raster, rgdal, plyr +dataProduct: DP3.30006.001 +packagesLibraries: rhdf5, terra, plyr authors: Leah A. Wasser, Donal O'Leary topics: hyperspectral, HDF5, remote-sensing tutorialSeries: null @@ -93,77 +93,45 @@ before moving on to this tutorial. Everything on our planet reflects electromagnetic radiation from the Sun, and different types of land cover often have dramatically different refelectance properties across the spectrum. One of the most powerful aspects of the NEON -Imaging Spectrometer (a.k.a. NEON's hyperspectral imager) is that it can +Imaging Spectrometer (NIS, or hyperspectral sensor) is that it can accurately measure these reflectance properties at a very high spectral resolution. When you plot the reflectance values across the observed spectrum, you will see that different land cover types (vegetation, pavement, bare soils, etc.) have -distinct patterns in their reflectance values, a feature that we call the +distinct patterns in their reflectance values, a property that we call the 'spectral signature' of a particular land cover class. -In this tutorial, we will extract a single pixel's worth of reflectance -values to plot a spectral signature for that pixel. In order to plot the -spectral signature for a given pixel in this hyperspectral dataset, we will -need to extract the reflectance values for that pixel, and pair those with the -wavelengths that are represented in those measurements. We will also need to +In this tutorial, we will extract the reflectance values for all bands of a +single pixel to plot a spectral signature for that pixel. In order to do this, +we need to pair the reflectance values for that pixel with the wavelength values +of the bands that are represented in those measurements. We will also need to adjust the reflectance values by the scaling factor that is saved as an 'attribute' in the HDF5 file. First, let's start by defining the working directory and reading in the example dataset. +```{r call-libraries, results="hide" } - # Call required packages - library(rhdf5) - library(plyr) - library(ggplot2) - - # set working directory to ensure R can find the file we wish to import and where - # we want to save our files. Be sure to move the download into your working directory! - wd <- "~/Documents/data/" #This will depend on your local environment - setwd(wd) - -Now, we need to access the H5 file. - - - # Define the file name to be opened - f <- paste0(wd,"NEON_hyperspectral_tutorial_example_subset.h5") - # look at the HDF5 file structure - h5ls(f,all=T) - - ## group name ltype - ## 0 / SJER H5L_TYPE_HARD - ## 1 /SJER Reflectance H5L_TYPE_HARD - ## 2 /SJER/Reflectance Metadata H5L_TYPE_HARD - ## 3 /SJER/Reflectance/Metadata Coordinate_System H5L_TYPE_HARD - ## 4 /SJER/Reflectance/Metadata/Coordinate_System Coordinate_System_String H5L_TYPE_HARD - ## 5 /SJER/Reflectance/Metadata/Coordinate_System EPSG Code H5L_TYPE_HARD - ## 6 /SJER/Reflectance/Metadata/Coordinate_System Map_Info H5L_TYPE_HARD - ## 7 /SJER/Reflectance/Metadata/Coordinate_System Proj4 H5L_TYPE_HARD - ## 8 /SJER/Reflectance/Metadata Spectral_Data H5L_TYPE_HARD - ## 9 /SJER/Reflectance/Metadata/Spectral_Data Wavelength H5L_TYPE_HARD - ## 10 /SJER/Reflectance Reflectance_Data H5L_TYPE_HARD - ## corder_valid corder cset otype num_attrs dclass dtype stype rank - ## 0 FALSE 0 0 H5I_GROUP 0 0 - ## 1 FALSE 0 0 H5I_GROUP 5 0 - ## 2 FALSE 0 0 H5I_GROUP 0 0 - ## 3 FALSE 0 0 H5I_GROUP 0 0 - ## 4 FALSE 0 0 H5I_DATASET 0 STRING H5T_STRING SIMPLE 1 - ## 5 FALSE 0 0 H5I_DATASET 0 STRING H5T_STRING SIMPLE 1 - ## 6 FALSE 0 0 H5I_DATASET 1 STRING H5T_STRING SIMPLE 1 - ## 7 FALSE 0 0 H5I_DATASET 0 STRING H5T_STRING SIMPLE 1 - ## 8 FALSE 0 0 H5I_GROUP 0 0 - ## 9 FALSE 0 0 H5I_DATASET 3 FLOAT H5T_IEEE_F64LE SIMPLE 1 - ## 10 FALSE 0 0 H5I_DATASET 13 INTEGER H5T_STD_I32LE SIMPLE 3 - ## dim maxdim - ## 0 - ## 1 - ## 2 - ## 3 - ## 4 1 1 - ## 5 1 1 - ## 6 1 1 - ## 7 1 1 - ## 8 - ## 9 107 107 - ## 10 107 x 500 x 500 107 x 500 x 500 +# Call required packages +library(rhdf5) +library(plyr) +library(ggplot2) + +# set working directory to ensure R can find the file we wish to import and where +# we want to save our files. Be sure to move the download into your working directory! +wd <- "~/data/" #This will depend on your local environment +setwd(wd) + +``` + +Now, we can look at the contents of the H5 file as follows: + +```{r open-H5-file } + +# Define the file name to be opened +f <- paste0(wd,"NEON_hyperspectral_tutorial_example_subset.h5") +# look at the HDF5 file structure +h5ls(f,all=T) + +``` ## Read Wavelength Values @@ -172,9 +140,12 @@ Next, let's read in the wavelength center associated with each band in the HDF5 file. We will later match these with the reflectance values and show both in our final spectral signature plot. +```{r read-band-wavelengths } - # read in the wavelength information from the HDF5 file - wavelengths <- h5read(f,"/SJER/Reflectance/Metadata/Spectral_Data/Wavelength") +# read in the wavelength information from the HDF5 file +wavelengths <- h5read(f,"/SJER/Reflectance/Metadata/Spectral_Data/Wavelength") + +``` ## Extract Z-dimension data slice @@ -184,29 +155,24 @@ spectral signature or profile of the pixel. To do that, we'll use the `h5read()` function. Here we pick an arbitrary pixel at `(100,35)`, and use the `NULL` value to select *all* bands from that location. +```{r extract-spectra } + +# extract all bands from a single pixel +aPixel <- h5read(f,"/SJER/Reflectance/Reflectance_Data",index=list(NULL,100,35)) - # extract all bands from a single pixel - aPixel <- h5read(f,"/SJER/Reflectance/Reflectance_Data",index=list(NULL,100,35)) - - # The line above generates a vector of reflectance values. - # Next, we reshape the data and turn them into a dataframe - b <- adply(aPixel,c(1)) - - # create clean data frame - aPixeldf <- b[2] - - # add wavelength data to matrix - aPixeldf$Wavelength <- wavelengths - - head(aPixeldf) - - ## V1 Wavelength - ## 1 720 381.5437 - ## 2 337 401.5756 - ## 3 336 421.6075 - ## 4 399 441.6394 - ## 5 406 461.6713 - ## 6 426 481.7032 +# The line above generates a vector of reflectance values. +# Next, we reshape the data and turn them into a dataframe +b <- adply(aPixel,c(1)) + +# create clean data frame +aPixeldf <- b[2] + +# add wavelength data to matrix +aPixeldf$Wavelength <- wavelengths + +head(aPixeldf) + +``` ## Scale Factor @@ -216,36 +182,32 @@ However, floating point data consume more space (yield a larger file size) compa to integer values. Thus, to keep the file sizes smaller, the data will be scaled by a factor of 10, 100, 10000, etc. This `scale factor` will be noted in the data attributes. +```{r pull-scale-factor } + +# grab scale factor from the Reflectance attributes +reflectanceAttr <- h5readAttributes(f,"/SJER/Reflectance/Reflectance_Data" ) + +scaleFact <- reflectanceAttr$Scale_Factor + +# add scaled data column to DF +aPixeldf$scaled <- (aPixeldf$V1/as.vector(scaleFact)) + +# make nice column names +names(aPixeldf) <- c('Reflectance','Wavelength','ScaledReflectance') +head(aPixeldf) - # grab scale factor from the Reflectance attributes - reflectanceAttr <- h5readAttributes(f,"/SJER/Reflectance/Reflectance_Data" ) - - scaleFact <- reflectanceAttr$Scale_Factor - - # add scaled data column to DF - aPixeldf$scaled <- (aPixeldf$V1/as.vector(scaleFact)) - - # make nice column names - names(aPixeldf) <- c('Reflectance','Wavelength','ScaledReflectance') - head(aPixeldf) - - ## Reflectance Wavelength ScaledReflectance - ## 1 720 381.5437 0.0720 - ## 2 337 401.5756 0.0337 - ## 3 336 421.6075 0.0336 - ## 4 399 441.6394 0.0399 - ## 5 406 461.6713 0.0406 - ## 6 426 481.7032 0.0426 +``` ## Plot Spectral Signature Now we're ready to plot our spectral signature! +```{r plot-spectra, fig.width=9, fig.height=6, fig.cap="Spectral signature plot with wavelength in nanometers on the x-axis and reflectance on the y-axis."} - ggplot(data=aPixeldf)+ - geom_line(aes(x=Wavelength, y=ScaledReflectance))+ - xlab("Wavelength (nm)")+ - ylab("Reflectance") +ggplot(data=aPixeldf)+ + geom_line(aes(x=Wavelength, y=ScaledReflectance))+ + xlab("Wavelength (nm)")+ + ylab("Reflectance") -![ ](https://raw.githubusercontent.com/NEONScience/NEON-Data-Skills/main/tutorials/R/Hyperspectral/Intro-hyperspectral/Plot-Hyperspectral-Spectra/rfigs/plot-spectra-1.png) +```