Esempio n. 1
0
    def __init__(self):
        ptype = self.getPType()
        # Explicit initialisation of all particle variables
        for v in ptype.variables:
            if isinstance(v.initial, attrgetter):
                initial = v.initial(self)
            elif isinstance(v.initial, Field):
                lon = self.getInitialValue(ptype, name='lon')
                lat = self.getInitialValue(ptype, name='lat')
                depth = self.getInitialValue(ptype, name='depth')
                time = self.getInitialValue(ptype, name='time')
                v.initial.fieldset.computeTimeChunk(time, 1)
                if time is None:
                    logger.error(
                        'Cannot initialise a Variable with a Field if no time provided. '
                        'Add a "time=" to ParticleSet construction')
                    exit(-1)
                initial = v.initial[time, lon, lat, depth]
            else:
                initial = v.initial
            # Enforce type of initial value
            if v.dtype != c_void_p:
                setattr(self, v.name, v.dtype(initial))

        # Placeholder for explicit error handling
        self.exception = None
Esempio n. 2
0
    def write(self, pset, time, sync=True):
        """Write :class:`parcels.particleset.ParticleSet` data to file

        :param pset: ParticleSet object to write
        :param time: Time at which to write ParticleSet
        :param sync: Optional argument whether to write data to disk immediately. Default is True

        """
        if isinstance(time, delta):
            time = time.total_seconds()
        if self.lasttime_written != time:  # only write if 'time' hasn't been written yet
            self.lasttime_written = time
            if self.type is 'array':
                # Check if largest particle ID is smaller than the last ID in ParticleFile.
                # Otherwise, new particles have been added and netcdf will fail
                if pset.size > 0:
                    if max([p.id for p in pset]) > self.id[-1]:
                        logger.error(
                            "Number of particles appears to increase. Use type='indexed' for ParticleFile"
                        )

                    # Finds the indices (inds) of the particle IDs in the ParticleFile,
                    # because particles can have been deleted
                    pids = [p.id for p in pset]
                    inds = np.in1d(self.id[:], pids, assume_unique=True)
                    inds = np.arange(len(self.id[:]))[inds]

                    self.time[inds, self.idx] = time
                    self.lat[inds, self.idx] = np.array([p.lat for p in pset])
                    self.lon[inds, self.idx] = np.array([p.lon for p in pset])
                    self.z[inds, self.idx] = np.array([p.depth for p in pset])
                    for var in self.user_vars:
                        getattr(self, var)[inds, self.idx] = np.array(
                            [getattr(p, var) for p in pset])
                else:
                    logger.warning("ParticleSet is empty on writing as array")

                self.idx += 1
            elif self.type is 'indexed':
                ind = np.arange(pset.size) + self.idx
                self.id[ind] = np.array([p.id for p in pset])
                self.time[ind] = time
                self.lat[ind] = np.array([p.lat for p in pset])
                self.lon[ind] = np.array([p.lon for p in pset])
                self.z[ind] = np.array([p.depth for p in pset])
                for var in self.user_vars:
                    getattr(self, var)[ind] = np.array(
                        [getattr(p, var) for p in pset])

                self.idx += pset.size

        if sync:
            self.sync()