R/FindBottom_updated.R

# Find bottom in backscatter matrix. 
# discrimination level - any ping with a dB greater than this value is likely the bottom; Echoview defualt is -50 dB
# create empty vector to store bottom depth for each ping
# http://support.echoview.com/WebHelp/Echoview.htm

# FindBottom
# Input: A ReadEKRaw_ConvertPower data object (i.e., you must run ReadEKRaw and then ConvertPower first). A list of three objects called data,
# (1) File header, (2) pings, (3) GPS data. These three objects are themselves lists. 

# Output: adds a vector named bot.depth to each object in data$pings. Also generates a new element to data
# called bottom.line  that is a vector of the bottom depths at all indexed value in 1:length(data$pings),
# this vector is created for ease when plotting or other analyses.
 
# nf = near field range in meters, user specified, defines the depth range from 0 - nf to exclude; defaults is 1 m
# d;  discrimination level in dB, pixels below this value are not considered when finding the bottom; default is -30 dB  

# must load zoo package first
library("zoo")

FindBottom2 = function(data, nf = 1, d = -30, smooth = TRUE){
  
  # create empty bottom.line vector
        bottom.vec = c()
        
  # estimate bottom depth based on maximum Sv above discrimination level
        for (i in 1:(length(data$pings))){
              # define depths of interest, excluding nf
                  tmp.nf = (data$ping[[i]]$rangeCorrected <= nf)
                  idx = which(tmp.nf == FALSE)  # finds all indices for rangeCorrected that are within the nf range
                  end = length(data$pings[[i]]$Sv)
              # define the data to use excluding nearfield.
                  tmp = data$pings[[i]]$Sv[idx[1]:end]
              # turn any value with Sv that is smaller than the discrimination level to an NA
                  tmp[tmp < d] <- NA
              # within this data, find the index value of the max Sv value
                  max.value  = which.max(tmp)
              # find the max. depth from rangeCorrected
                  # if there is not pixel within a ping that is above discrimination level - and therefore no bottom the length of max.value = 0  
                      if (length(max.value) == 0 ) { 
                        bot.depth = NA
                        }
                      if(length(max.value)!= 0){
                        # use the index specified by max.value to find the max depth
                        idx.to.add = idx[1]-2 # this corrects for the index value offset
                        bot.depth = data$pings[[i]]$rangeCorrected[max.value + idx.to.add]
                        #bot.depth = data$pings[[i]]$rangeCorrected[max.value]
                        
                        }
             
              # add bot.depth to bottom.line vector for smoothing and easy plotting
                  bottom.vec = c(bottom.vec, bot.depth)
        }


  # now deal with the NA's in bottom line and smooth the bottom line 
      # fill in NA's with linear interpolation 
          bottom.vec = na.fill(na.approx(bottom.vec, na.rm = FALSE), "extend") 
         
      # smooth the bottom line, user can skip the smooth of the bottom line
        if(smooth == TRUE){
          bottom.vec = smooth(bottom.vec)
        }
      
      # at some point will need to be able to deal with cases when the depth of the lake is over the instrument range...
            
      # add bottom line to data as new, 4th list
              data$bottom.line = bottom.vec
       
    ## now add smoothed bottom depth at each ping
     # for loop 
              for (i in 1:(length(data$pings))){
                # add a new list to data that contains the bottom depth at each ping
                data$pings[[i]]$bot.depth = data$bottom.line[i]
              }
              
            return(data)
}
leachth/ReadEKRaw_updated documentation built on May 23, 2019, 9:02 p.m.