docs: def data_interp(self, i, currenttime):
          """
              Method to streamline request for data from cache,
              Uses linear interpolation bewtween timesteps to
              get u,v,w,temp,salt
          """
          if self.active.value is True:
              while self.get_data.value is True:
                  logger.debug("Waiting for DataController to release cache file so I can read from it...")
                  timer.sleep(2)
                  pass
  
          if self.need_data(i+1):
              # Acquire lock for asking for data
              self.data_request_lock.acquire()
              self.has_data_request_lock.value = os.getpid()
              try:
                  # Do I still need data?
                  if self.need_data(i+1):
  
                      # Tell the DataController that we are going to be reading from the file
                      with self.read_lock:
                          self.read_count.value += 1
                          self.has_read_lock.append(os.getpid())
  
                      # Open netcdf file on disk from commondataset
                      self.dataset.opennc()
                      # Get the indices for the current particle location
                      indices = self.dataset.get_indices('u', timeinds=[np.asarray([i-1])], point=self.part.location )
                      self.dataset.closenc()
  
                      with self.read_lock:
                          self.read_count.value -= 1
                          self.has_read_lock.remove(os.getpid())
  
                      # Override the time
                      # get the current time index data
                      self.point_get.value = [indices[0] + 1, indices[-2], indices[-1]]
                      # Request that the data controller update the cache
                      self.get_data.value = True
                      # Wait until the data controller is done
                      if self.active.value is True:
                          while self.get_data.value is True:
                              logger.debug("Waiting for DataController to update cache with the CURRENT time index")
                              timer.sleep(2)
                              pass
  
                      # Do we still need to get the next timestep?
                      if self.need_data(i+1):
                          # get the next time index data
                          self.point_get.value = [indices[0] + 2, indices[-2], indices[-1]]
                          # Request that the data controller update the cache
                          self.get_data.value = True
                          # Wait until the data controller is done
                          if self.active.value is True:
                              while self.get_data.value is True:
                                  logger.debug("Waiting for DataController to update cache with the NEXT time index")
                                  timer.sleep(2)
                                  pass
              except StandardError:
                  logger.warn("Particle failed to request data correctly")
                  raise
              finally:
                  # Release lock for asking for data
                  self.has_data_request_lock.value = -1
                  self.data_request_lock.release()
  
          if self.caching is True:
              # Tell the DataController that we are going to be reading from the file
              with self.read_lock:
                  self.read_count.value += 1
                  self.has_read_lock.append(os.getpid())
  
          try:
              # Open the Cache netCDF file on disk
              self.dataset.opennc()
  
              # Grab data at time index closest to particle location
              u = [np.mean(np.mean(self.dataset.get_values('u', timeinds=[np.asarray([i])], point=self.part.location ))),
                   np.mean(np.mean(self.dataset.get_values('u', timeinds=[np.asarray([i+1])], point=self.part.location )))]
              v = [np.mean(np.mean(self.dataset.get_values('v', timeinds=[np.asarray([i])], point=self.part.location ))),
                   np.mean(np.mean(self.dataset.get_values('v', timeinds=[np.asarray([i+1])], point=self.part.location )))]
              # if there is vertical velocity inthe dataset, get it
              if 'w' in self.dataset.nc.variables:
                  w = [np.mean(np.mean(self.dataset.get_values('w', timeinds=[np.asarray([i])], point=self.part.location ))),
                       np.mean(np.mean(self.dataset.get_values('w', timeinds=[np.asarray([i+1])], point=self.part.location )))]
              else:
                  w = [0.0, 0.0]
              # If there is salt and temp in the dataset, get it
              if self.temp_name is not None and self.salt_name is not None:
                  temp = [np.mean(np.mean(self.dataset.get_values('temp', timeinds=[np.asarray([i])], point=self.part.location ))),
                          np.mean(np.mean(self.dataset.get_values('temp', timeinds=[np.asarray([i+1])], point=self.part.location )))]
                  salt = [np.mean(np.mean(self.dataset.get_values('salt', timeinds=[np.asarray([i])], point=self.part.location ))),
                          np.mean(np.mean(self.dataset.get_values('salt', timeinds=[np.asarray([i+1])], point=self.part.location )))]
  
              # Check for nans that occur in the ocean (happens because
              # of model and coastline resolution mismatches)
              if np.isnan(u).any() or np.isnan(v).any() or np.isnan(w).any():
                  # Take the mean of the closest 4 points
                  # If this includes nan which it will, result is nan
                  uarray1 = self.dataset.get_values('u', timeinds=[np.asarray([i])], point=self.part.location, num=2)
                  varray1 = self.dataset.get_values('v', timeinds=[np.asarray([i])], point=self.part.location, num=2)
                  uarray2 = self.dataset.get_values('u', timeinds=[np.asarray([i+1])], point=self.part.location, num=2)
                  varray2 = self.dataset.get_values('v', timeinds=[np.asarray([i+1])], point=self.part.location, num=2)
                  if 'w' in self.dataset.nc.variables:
                      warray1 = self.dataset.get_values('w', timeinds=[np.asarray([i])], point=self.part.location, num=2)
                      warray2 = self.dataset.get_values('w', timeinds=[np.asarray([i+1])], point=self.part.location, num=2)
                      w = [warray1.mean(), warray2.mean()]
                  else:
                      w = [0.0, 0.0]
  
                  if self.temp_name is not None and self.salt_name is not None:
                      temparray1 = self.dataset.get_values('temp', timeinds=[np.asarray([i])], point=self.part.location, num=2)
                      saltarray1 = self.dataset.get_values('salt', timeinds=[np.asarray([i])], point=self.part.location, num=2)
                      temparray2 = self.dataset.get_values('temp', timeinds=[np.asarray([i+1])], point=self.part.location, num=2)
                      saltarray2 = self.dataset.get_values('salt', timeinds=[np.asarray([i+1])], point=self.part.location, num=2)
                      temp = [temparray1.mean(), temparray2.mean()]
                      salt = [saltarray1.mean(), saltarray2.mean()]
                  u = [uarray1.mean(), uarray2.mean()]
                  v = [varray1.mean(), varray2.mean()]
  
              # Linear interp of data between timesteps
              currenttime = date2num(currenttime)
              timevar = self.timevar.datenum
              u = self.linterp(timevar[i:i+2], u, currenttime)
              v = self.linterp(timevar[i:i+2], v, currenttime)
              w = self.linterp(timevar[i:i+2], w, currenttime)
              if self.temp_name is not None and self.salt_name is not None:
                  temp = self.linterp(timevar[i:i+2], temp, currenttime)
                  salt = self.linterp(timevar[i:i+2], salt, currenttime)
  
              if self.temp_name is None:
                  temp = np.nan
              if self.salt_name is None:
                  salt = np.nan
  
          except StandardError:
              logger.error("Error in data_interp method on ForceParticle")
              raise
          finally:
              # If caching is False, we don't have to close the dataset.  We can stay in read-only mode.
              if self.caching is True:
                  self.dataset.closenc()
                  with self.read_lock:
                      self.read_count.value -= 1
                      self.has_read_lock.remove(os.getpid())
  
          return u, v, w, temp, salt