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
Esempio n. 3
0
    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