|
1 | | -from datetime import timedelta as delta |
2 | 1 | from operator import attrgetter |
3 | 2 | from ctypes import Structure, POINTER |
4 | 3 | from bisect import bisect_left |
|
26 | 25 | 'See http://oceanparcels.org/#parallel_install for more information') |
27 | 26 |
|
28 | 27 |
|
29 | | -def _to_write_particles(pd, time): |
30 | | - """We don't want to write a particle that is not started yet. |
31 | | - Particle will be written if particle.time is between time-dt/2 and time+dt (/2) |
32 | | - """ |
33 | | - return ((np.less_equal(time - np.abs(pd['dt']/2), pd['time'], where=np.isfinite(pd['time'])) |
34 | | - & np.greater_equal(time + np.abs(pd['dt'] / 2), pd['time'], where=np.isfinite(pd['time'])) |
35 | | - | ((np.isnan(pd['dt'])) & np.equal(time, pd['time'], where=np.isfinite(pd['time'])))) |
36 | | - & (np.isfinite(pd['id'])) |
37 | | - & (np.isfinite(pd['time']))) |
38 | | - |
39 | | - |
40 | | -def _is_particle_started_yet(pd, time): |
41 | | - """We don't want to write a particle that is not started yet. |
42 | | - Particle will be written if: |
43 | | - * particle.time is equal to time argument of pfile.write() |
44 | | - * particle.time is before time (in case particle was deleted between previous export and current one) |
45 | | - """ |
46 | | - return np.less_equal(pd['dt']*pd['time'], pd['dt']*time) | np.isclose(pd['time'], time) |
47 | | - |
48 | | - |
49 | 28 | def _convert_to_flat_array(var): |
50 | 29 | """Convert lists and single integers/floats to one-dimensional numpy arrays |
51 | 30 |
|
@@ -153,7 +132,7 @@ def __init__(self, pclass, lon, lat, depth, time, lonlatdepth_dtype, pid_orig, p |
153 | 132 | self._data['depth'][:] = depth |
154 | 133 | self._data['time'][:] = time |
155 | 134 | self._data['id'][:] = pid |
156 | | - self._data['fileid'][:] = -1 |
| 135 | + self._data['once_written'][:] = 0 |
157 | 136 |
|
158 | 137 | # special case for exceptions which can only be handled from scipy |
159 | 138 | self._data['exception'] = np.empty(self.ncount, dtype=object) |
@@ -815,58 +794,30 @@ def flatten_dense_data_array(vname): |
815 | 794 | cstruct = CParticles(*cdata) |
816 | 795 | return cstruct |
817 | 796 |
|
818 | | - def toDictionary(self, pfile, time, deleted_only=False): |
| 797 | + def _to_write_particles(self, pd, time): |
| 798 | + """We don't want to write a particle that is not started yet. |
| 799 | + Particle will be written if particle.time is between time-dt/2 and time+dt (/2) |
819 | 800 | """ |
820 | | - Convert all Particle data from one time step to a python dictionary. |
821 | | - :param pfile: ParticleFile object requesting the conversion |
822 | | - :param time: Time at which to write ParticleSet |
823 | | - :param deleted_only: Flag to write only the deleted Particles |
824 | | - returns two dictionaries: one for all variables to be written each outputdt, |
825 | | - and one for all variables to be written once |
| 801 | + return np.where((np.less_equal(time - np.abs(pd['dt'] / 2), pd['time'], where=np.isfinite(pd['time'])) |
| 802 | + & np.greater_equal(time + np.abs(pd['dt'] / 2), pd['time'], where=np.isfinite(pd['time'])) |
| 803 | + | ((np.isnan(pd['dt'])) & np.equal(time, pd['time'], where=np.isfinite(pd['time'])))) |
| 804 | + & (np.isfinite(pd['id'])) |
| 805 | + & (np.isfinite(pd['time'])))[0] |
826 | 806 |
|
827 | | - This function depends on the specific collection in question and thus needs to be specified in specific |
828 | | - derivative classes. |
829 | | - """ |
830 | | - |
831 | | - data_dict = {} |
832 | | - data_dict_once = {} |
| 807 | + def getvardata(self, var, indices=None): |
| 808 | + if indices is None: |
| 809 | + return self._data[var] |
| 810 | + else: |
| 811 | + try: |
| 812 | + return self._data[var][indices] |
| 813 | + except: # Can occur for zero-length ParticleSets |
| 814 | + return None |
833 | 815 |
|
834 | | - time = time.total_seconds() if isinstance(time, delta) else time |
| 816 | + def setvardata(self, var, index, val): |
| 817 | + self._data[var][index] = val |
835 | 818 |
|
836 | | - indices_to_write = [] |
837 | | - if pfile.lasttime_written != time and \ |
838 | | - (pfile.write_ondelete is False or deleted_only is not False): |
839 | | - if self._data['id'].size == 0: |
840 | | - logger.warning("ParticleSet is empty on writing as array at time %g" % time) |
841 | | - else: |
842 | | - if deleted_only is not False: |
843 | | - if type(deleted_only) not in [list, np.ndarray] and deleted_only in [True, 1]: |
844 | | - indices_to_write = np.where(np.isin(self._data['state'], |
845 | | - [OperationCode.Delete]))[0] |
846 | | - elif type(deleted_only) in [list, np.ndarray]: |
847 | | - indices_to_write = deleted_only |
848 | | - else: |
849 | | - indices_to_write = _to_write_particles(self._data, time) |
850 | | - if np.any(indices_to_write): |
851 | | - for var in pfile.var_names: |
852 | | - data_dict[var] = self._data[var][indices_to_write] |
853 | | - |
854 | | - pset_errs = ((self._data['state'][indices_to_write] != OperationCode.Delete) & np.greater(np.abs(time - self._data['time'][indices_to_write]), 1e-3, where=np.isfinite(self._data['time'][indices_to_write]))) |
855 | | - if np.count_nonzero(pset_errs) > 0: |
856 | | - logger.warning_once('time argument in pfile.write() is {}, but particles have time {}'.format(time, self._data['time'][pset_errs])) |
857 | | - |
858 | | - if len(pfile.var_names_once) > 0: |
859 | | - first_write = (_to_write_particles(self._data, time) & _is_particle_started_yet(self._data, time) & np.isin(self._data['id'], pfile.written_once, invert=True)) |
860 | | - if np.any(first_write): |
861 | | - data_dict_once['id'] = np.array(self._data['id'][first_write]).astype(dtype=np.int64) |
862 | | - for var in pfile.var_names_once: |
863 | | - data_dict_once[var] = self._data[var][first_write] |
864 | | - pfile.written_once.extend(np.array(self._data['id'][first_write]).astype(dtype=np.int64).tolist()) |
865 | | - |
866 | | - if deleted_only is False: |
867 | | - pfile.lasttime_written = time |
868 | | - |
869 | | - return data_dict, data_dict_once |
| 819 | + def setallvardata(self, var, val): |
| 820 | + self._data[var][:] = val |
870 | 821 |
|
871 | 822 | def toArray(self): |
872 | 823 | """ |
|
0 commit comments