def data_interp(self, i, timevar, 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 == True: while self.get_data.value == True: logger.debug("Waiting for DataController to release cache file so I can read from it...") timer.sleep(4) 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 == True: while self.get_data.value == True: logger.debug("Waiting for DataController to update cache with the CURRENT time index") timer.sleep(4) pass # 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 == True: while self.get_data.value == True: logger.debug("Waiting for DataController to update cache with the NEXT time index") timer.sleep(4) 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() # 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 netcdf file on disk from commondataset 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 != None and self.salt_name != 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 != None and self.salt_name != 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 = 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 != None and self.salt_name != 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 #logger.info(self.dataset.get_xyind_from_point('u', self.part.location, num=1)) except StandardError: logger.error("Error in data_interp method on ForceParticle") raise finally: 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
def get_linterp_data(self, i, currenttime): """ Note: self.dataset.opennc() must be called before calling this function. This is because the caching forcer must close it everytime, while a non caching forcer can leave the dataset open. """ try: # 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.particle.location ))), np.mean(np.mean(self.dataset.get_values('u', timeinds=[np.asarray([i+1])], point=self.particle.location )))] v = [np.mean(np.mean(self.dataset.get_values('v', timeinds=[np.asarray([i])], point=self.particle.location ))), np.mean(np.mean(self.dataset.get_values('v', timeinds=[np.asarray([i+1])], point=self.particle.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.particle.location ))), np.mean(np.mean(self.dataset.get_values('w', timeinds=[np.asarray([i+1])], point=self.particle.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.particle.location ))), np.mean(np.mean(self.dataset.get_values('temp', timeinds=[np.asarray([i+1])], point=self.particle.location )))] salt = [np.mean(np.mean(self.dataset.get_values('salt', timeinds=[np.asarray([i])], point=self.particle.location ))), np.mean(np.mean(self.dataset.get_values('salt', timeinds=[np.asarray([i+1])], point=self.particle.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.particle.location, num=2) varray1 = self.dataset.get_values('v', timeinds=[np.asarray([i])], point=self.particle.location, num=2) uarray2 = self.dataset.get_values('u', timeinds=[np.asarray([i+1])], point=self.particle.location, num=2) varray2 = self.dataset.get_values('v', timeinds=[np.asarray([i+1])], point=self.particle.location, num=2) if 'w' in self.dataset.nc.variables: warray1 = self.dataset.get_values('w', timeinds=[np.asarray([i])], point=self.particle.location, num=2) warray2 = self.dataset.get_values('w', timeinds=[np.asarray([i+1])], point=self.particle.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.particle.location, num=2) saltarray1 = self.dataset.get_values('salt', timeinds=[np.asarray([i])], point=self.particle.location, num=2) temparray2 = self.dataset.get_values('temp', timeinds=[np.asarray([i+1])], point=self.particle.location, num=2) saltarray2 = self.dataset.get_values('salt', timeinds=[np.asarray([i+1])], point=self.particle.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 Exception: logger.exception("Could not retrieve data.") raise return u, v, w, temp, salt
def get_linterp_data(self, i, currenttime): """ Note: self.dataset.opennc() must be called before calling this function. This is because the caching forcer must close it everytime, while a non caching forcer can leave the dataset open. """ try: # 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.particle.location))), np.mean( np.mean( self.dataset.get_values('u', timeinds=[np.asarray([i + 1])], point=self.particle.location))) ] v = [ np.mean( np.mean( self.dataset.get_values( 'v', timeinds=[np.asarray([i])], point=self.particle.location))), np.mean( np.mean( self.dataset.get_values('v', timeinds=[np.asarray([i + 1])], point=self.particle.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.particle.location))), np.mean( np.mean( self.dataset.get_values( 'w', timeinds=[np.asarray([i + 1])], point=self.particle.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.particle.location))), np.mean( np.mean( self.dataset.get_values( 'temp', timeinds=[np.asarray([i + 1])], point=self.particle.location))) ] salt = [ np.mean( np.mean( self.dataset.get_values( 'salt', timeinds=[np.asarray([i])], point=self.particle.location))), np.mean( np.mean( self.dataset.get_values( 'salt', timeinds=[np.asarray([i + 1])], point=self.particle.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.particle.location, num=2) varray1 = self.dataset.get_values('v', timeinds=[np.asarray([i])], point=self.particle.location, num=2) uarray2 = self.dataset.get_values( 'u', timeinds=[np.asarray([i + 1])], point=self.particle.location, num=2) varray2 = self.dataset.get_values( 'v', timeinds=[np.asarray([i + 1])], point=self.particle.location, num=2) if 'w' in self.dataset.nc.variables: warray1 = self.dataset.get_values( 'w', timeinds=[np.asarray([i])], point=self.particle.location, num=2) warray2 = self.dataset.get_values( 'w', timeinds=[np.asarray([i + 1])], point=self.particle.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.particle.location, num=2) saltarray1 = self.dataset.get_values( 'salt', timeinds=[np.asarray([i])], point=self.particle.location, num=2) temparray2 = self.dataset.get_values( 'temp', timeinds=[np.asarray([i + 1])], point=self.particle.location, num=2) saltarray2 = self.dataset.get_values( 'salt', timeinds=[np.asarray([i + 1])], point=self.particle.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 Exception: logger.exception("Could not retrieve data.") raise return u, v, w, temp, salt