Skip to content

Commit c493810

Browse files
unknownunknown
authored andcommitted
1st upload of completed package
1 parent 668a742 commit c493810

22 files changed

Lines changed: 1453 additions & 22 deletions

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
^.*\.Rproj$
2+
^\.Rproj\.user$

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.Rproj.user
2+
.Rhistory
3+
.RData

DESCRIPTION

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Package: MSScvm
2+
Title: Automated Cloud Masking for Landsat MSS Images
3+
Version: 1.0.0
4+
Date: 2015-07-23
5+
Authors@R: c(person("Justin", "Braaten", email = "jstnbraaten@gmail.com", role = c("aut", "cre")),
6+
person("Warren", "Cohen", email = "warren.cohen@oregonstate.edu", role = "aut"),
7+
person("Zhiqiang", "Yang", email = "zhiqiang.yang@oregonstate.edu", role = "aut"))
8+
Description: An automated cloud and cloud shadow masking system for Landsat MSS imagery. It allows MSS imagery to more easily be used in large-area and time series analysis by providing an efficent way to prevent cloud and cloud shadow pixels from contaminating mosaics, composites, and time series.
9+
Depends: R (>= 3.2.1)
10+
Imports:
11+
gdalUtils,
12+
igraph,
13+
raster,
14+
rgdal,
15+
SDMTools
16+
License: GPL-2
17+
LazyData: true

LICENSE

Lines changed: 0 additions & 22 deletions
This file was deleted.

MSScvm.Rproj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Version: 1.0
2+
3+
RestoreWorkspace: Default
4+
SaveWorkspace: Default
5+
AlwaysSaveHistory: Default
6+
7+
EnableCodeIndexing: Yes
8+
UseSpacesForTab: Yes
9+
NumSpacesForTab: 2
10+
Encoding: UTF-8
11+
12+
RnwWeave: Sweave
13+
LaTeX: pdfLaTeX
14+
15+
BuildType: Package
16+
PackageUseDevtools: Yes
17+
PackageInstallArgs: --no-multiarch --with-keep.source
18+
PackageRoxygenize: rd,collate,namespace,vignette

NAMESPACE

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Generated by roxygen2 (4.1.1): do not edit by hand
2+
3+
export(MSScvm)
4+
export(MSSdn2rad)
5+
export(MSSdn2refl)
6+
export(MSSunpack)
7+
export(eudist)
8+
export(getMetadata)
9+
export(mosaicDEMs)
10+
export(reprojectDEM)

R/MSScvm.r

Lines changed: 324 additions & 0 deletions
Large diffs are not rendered by default.

R/MSSdn2rad.r

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#' Convert MSS DN values to TOA radiance
2+
#'
3+
#' Convert MSS DN values to TOA radiance
4+
#' @param imgFile filename (character). Full path to *dn.tif image file produced by the \code{\link{MSSunpack}} function.
5+
#' @details The equation used to convert DN to TOA radiance can be found \href{http://landsat.usgs.gov/how_is_radiance_calculated.php}{here}.
6+
#' @return A 4-band Landsat MSS GeoTIFF raster image file in units of top-of-atmosphere (TOA) radiance. The file will be placed in
7+
#' same directory as the 'imgFile' with the name equal to the image ID followed by 'toa_radiance'. Note that the values are scaled by 100
8+
#' and rounded to the nearest integer to reduce the file size.
9+
#' @seealso \code{\link{MSSdn2refl}}
10+
#' @examples \dontrun{
11+
#'
12+
#' MSSdn2rad("C:/mss/LM10360321973191AAA04/LM10360321973191AAA04_dn.tif")
13+
#' }
14+
#' @export
15+
16+
MSSdn2rad = function(imgFile){
17+
18+
info = getMetadata(imgFile) #get image metadata
19+
b = raster::brick(imgFile) #load the DN image as a brick
20+
img = as.array(b) #convert the brick to an array
21+
22+
img[,,1] = round(100*((info$b1gain*img[,,1])+info$b1bias)) #convert fro DN to radiance and scale by 100 and round
23+
img[,,2] = round(100*((info$b2gain*img[,,2])+info$b2bias)) #convert fro DN to radiance and scale by 100 and round
24+
img[,,3] = round(100*((info$b3gain*img[,,3])+info$b3bias)) #convert fro DN to radiance and scale by 100 and round
25+
img[,,4] = round(100*((info$b4gain*img[,,4])+info$b4bias)) #convert fro DN to radiance and scale by 100 and round
26+
27+
img[img < 0] = 0 #you can't have negative radiance - set negative values to 0
28+
29+
img = raster::setValues(b,img) #convert the array to a brick
30+
img = as(img, "SpatialGridDataFrame") #convert the brick to SGHF to be written by GDAL
31+
outfile = sub("dn", "toa_radiance", imgFile) #define output filename
32+
rgdal::writeGDAL(img, outfile, drivername = "GTiff", type = "Int16", mvFlag = -32768, options="INTERLEAVE=BAND") #write the file
33+
}
34+

R/MSSdn2refl.r

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#' Convert DN values to TOA reflectance
2+
#'
3+
#' Convert DN values to TOA reflectance
4+
#' @param imgFile filename (character). Full path to *dn.tif image file produced by the \code{\link{MSSunpack}} function.
5+
#' @details DN values are first converted to top-of-atmosphere (TOA) radiance using the equation found \href{http://landsat.usgs.gov/how_is_radiance_calculated.php}{here}.
6+
#' Then TOA radiance is converted to TOA reflectance using the equation found \href{http://landsathandbook.gsfc.nasa.gov/data_prod/prog_sect11_3.html}{here}.
7+
#' The ESUN values used are from the publication 'Chander et al. 2009. Summary of current radiometric calibration coefficients... Remote Sensing of Environment. 113'.
8+
#' @return A 4-band Landsat MSS GeoTIFF raster image file in units of top-of-atmosphere (TOA) reflectance. The file will be placed in the
9+
#' same directory as the 'imgFile' with the name equal to the image ID followed by 'toa_reflectance'. Note that the values are scaled by 10,000
10+
#' and rounded to the nearest integer to reduce the file size.
11+
#' @seealso \code{\link{MSSdn2rad}}
12+
#' @examples \dontrun{
13+
#'
14+
#' MSSdn2refl("C:/mss/LM10360321973191AAA04/LM10360321973191AAA04_dn.tif")
15+
#' }
16+
#' @export
17+
18+
MSSdn2refl = function(imgFile){
19+
20+
#link to the equations to convert DN to TOA and TOA to SR
21+
#http://landsathandbook.gsfc.nasa.gov/data_prod/prog_sect11_3.html
22+
23+
#define the TOA reflectance function
24+
refl = function(imgFile, band, gain, bias, sunzen, d, esun){
25+
orig = raster::raster(imgFile, band) #read in the file
26+
img = as.matrix(orig) #convert from raster to matrix
27+
img = ((gain*img)+bias) #convert from DN to TOA radiance
28+
img[img < 0] = 0 #set all values less than 0 to 0 - negative radiance does not make sense
29+
img = (pi * img * (d^2))/(esun * cos(sunzen)) #convert from TOA radiance to TOA reflectance
30+
img = round(img * 10000) #scale by 10,000 and round to save on file size
31+
img = raster::setValues(orig,img) #convert from matrix to raster
32+
return(img) #return the TOA radiance raster
33+
}
34+
35+
info = getMetadata(imgFile) #read in the image metadata
36+
37+
#define esun values for mss (chander et al 2009 summary of current radiometric calibration coefficients... RSE 113)
38+
if(info$sensor == "LANDSAT_1"){esun = c(1823,1559,1276,880.1)}
39+
if(info$sensor == "LANDSAT_2"){esun = c(1829,1539,1268,886.6)}
40+
if(info$sensor == "LANDSAT_3"){esun = c(1839,1555,1291,887.9)}
41+
if(info$sensor == "LANDSAT_4"){esun = c(1827,1569,1260,866.4)}
42+
if(info$sensor == "LANDSAT_5"){esun = c(1824,1570,1249,853.4)}
43+
44+
d = eudist(info$doy) #define the earth sun distance
45+
sunzen = info$sunzen*(pi/180) #get sun zenith angle in radians for cos
46+
47+
#apply the conversion to reflectance using the 'refl' function
48+
b1 = refl(imgFile,1,info$b1gain, info$b1bias, sunzen, d, esun[1])
49+
b2 = refl(imgFile,2,info$b2gain, info$b2bias, sunzen, d, esun[2])
50+
b3 = refl(imgFile,3,info$b3gain, info$b3bias, sunzen, d, esun[3])
51+
b4 = refl(imgFile,4,info$b4gain, info$b4bias, sunzen, d, esun[4])
52+
53+
img = raster::stack(b1,b2,b3,b4) #stack the bands
54+
55+
img = as(img, "SpatialGridDataFrame") #convert the raster to SGHF so it can be written using GDAL (faster than writing it with the raster package)
56+
outfile = sub("dn", "toa_reflectance", imgFile) #define the outputs file
57+
rgdal::writeGDAL(img, outfile, drivername = "GTiff", type = "Int16", mvFlag = -32768, options="INTERLEAVE=BAND") #write out the TOA reflectance file
58+
}

R/MSSunpack.r

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#' Decompress and stack Landsat LPGS MSS images
2+
#'
3+
#' Decompresses and stacks Landsat LPGS MSS images provided by USGS as *.tar.gz files. Optionally
4+
#' outputs top-of-atmosphere (TOA) radiance and reflectance files.
5+
#' @param imgFile filename (character). Full path to compressed LPGS Landsat MSS image file provided by USGS.
6+
#' @param toaRad logical. If TRUE, a TOA radiance image will be created.
7+
#' @param toaRefl logical. If TRUE, a TOA reflectance image will be created.
8+
#' @param useL1G logical. If TRUE, L1G images will be processed.
9+
#' @details It is important that the 'imgFile' be an unaltered tar.gz-compressed LPGS image file that you receive
10+
#' from USGS through \href{http://rstudio.com}{EarthExplorer}. Note that DN values <= 1 are set to NA across all bands.
11+
#' This mitigates a problem caused by bad columns on the east and west edge of images when mosaicing adjacent images together.
12+
#' @return A 4-band Landsat MSS GeoTIFF raster image file in DN units. If optional 'toaRad' and/or 'toaRefl'
13+
#' parameters are set to TRUE, then similar TOA radiance and reflectance image files will created. The files will be places in
14+
#' directory in the same location as the 'imgFile' with the name equal to the image ID. The files contain the image ID with
15+
#' descriptors 'dn' (digital number), 'toa_radiance' (TOA radiance), and 'toa_reflectance' (TOA reflectance).
16+
#' @seealso \code{\link{MSSdn2rad}}, \code{\link{MSSdn2refl}}
17+
#' @examples
18+
#' \dontrun{
19+
#'
20+
#' MSSunpack(imgFile = "C:/mss/LM10360321973191AAA04.tar.gz")
21+
#' MSSunpack(imgFile = "C:/mss/LM10360321973191AAA04.tar.gz",
22+
#' toaRad = FALSE, toaRefl = TRUE, useL1G = TRUE)
23+
#' }
24+
#' @export
25+
26+
MSSunpack = function(imgFile, toaRad=FALSE, toaRefl=FALSE, useL1G=FALSE){
27+
28+
#figure out if this is an L1G image and stop the function according to the 'useL1G' parameter
29+
tempdir = file.path(dirname(imgFile),"temp")
30+
untar(imgFile, exdir=tempdir)
31+
if(useL1G == F){
32+
mtlfile = list.files(tempdir, pattern = "MTL.txt", full.names = T, recursive = T) #find the mtl metadata file
33+
info = getMetadata(mtlfile)
34+
if(info$datatype == "L1G"){
35+
print(paste("MSS file:",imgFile,"is L1G, if you want to use it, set the 'useL1G' parameter to TRUE"))
36+
stop("Stopping MSSunpack")
37+
}
38+
}
39+
40+
#get file and directory info
41+
allfiles = list.files(tempdir, full.names=T) #find all the decompressed files
42+
tiffiles = allfiles[grep("TIF",allfiles)] #subset the tif image files
43+
ancfiles = allfiles[grep("TIF",allfiles, invert=T)] #subset the other files
44+
filebase = basename(tiffiles[1]) #get the basename
45+
filedir = dirname(imgFile) #get the directory
46+
47+
#create stack output name
48+
name = paste(info$imgid, "_dn.tif", sep = "") #define the new file basename
49+
outdir = file.path(filedir, info$imgid) #define the output directory
50+
finalstack = file.path(outdir, name) #define the new full filename of the output image
51+
52+
#deal with the ancillary file names
53+
baseancfiles = basename(ancfiles) #get the basenames of the ancillary files
54+
newancfiles = file.path(outdir, baseancfiles) #define the new filenames for ancillary files
55+
56+
#start working with the image files - stack and set bad pixels to 0
57+
s = stack(tiffiles[1],tiffiles[2],tiffiles[3],tiffiles[4]) #stack the band files
58+
img = as.array(s) #convert to array for fastering processing
59+
b1bads = img[,,1]>1 #finds bad image edge pixels that cause problems when mosaicing
60+
b2bads = img[,,2]>1 #finds bad image edge pixels that cause problems when mosaicing
61+
b3bads = img[,,3]>1 #finds bad image edge pixels that cause problems when mosaicing
62+
b4bads = img[,,4]>1 #finds bad image edge pixels that cause problems when mosaicing
63+
bads = b1bads*b2bads*b3bads*b4bads #combines all of the bad pixels
64+
65+
img[,,1] = img[,,1]*bads #sets all the bad pixels to value 0
66+
img[,,2] = img[,,2]*bads #sets all the bad pixels to value 0
67+
img[,,3] = img[,,3]*bads #sets all the bad pixels to value 0
68+
img[,,4] = img[,,4]*bads #sets all the bad pixels to value 0
69+
70+
dir.create(outdir, recursive=T, showWarnings=F) #make a new output directory
71+
72+
file.rename(ancfiles,newancfiles) #move the associated files
73+
74+
#write out the dn file
75+
outimg = raster::setValues(s,img) #convert from matrix to raster
76+
outimg = as(outimg, "SpatialGridDataFrame") #convert from rater to SGDF for faster writing
77+
rgdal::writeGDAL(outimg, finalstack, drivername = "GTiff", options="INTERLEAVE=BAND", type = "Byte", mvFlag = 0) #write out the image.
78+
79+
if(toaRad == T){MSSdn2rad(finalstack)} #calculate and write the toa radiance file if flagged
80+
81+
if(toaRefl == T){MSSdn2refl(finalstack)} #calculate and write the toa reflectance file if flagged
82+
83+
unlink(tempdir, recursive=T, force=T) #delete the temp folder and its contents
84+
}

0 commit comments

Comments
 (0)