Skip to content

Commit e7af1ae

Browse files
committed
Various changes:
1) Use of sparse matrix for eddy tracking 2) Improvement to removal of dead eddies from TrackList.tracklist
1 parent 8a865d5 commit e7af1ae

8 files changed

+142
-91
lines changed

eddy_tracker_configuration.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,29 @@
1+
#===========================================================================
2+
#This file is part of py-eddy-tracker.
13

4+
#py-eddy-tracker is free software: you can redistribute it and/or modify
5+
#it under the terms of the GNU General Public License as published by
6+
#the Free Software Foundation, either version 3 of the License, or
7+
#(at your option) any later version.
8+
9+
#py-eddy-tracker is distributed in the hope that it will be useful,
10+
#but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
#GNU General Public License for more details.
13+
14+
#You should have received a copy of the GNU General Public License
15+
#along with py-eddy-tracker. If not, see <http://www.gnu.org/licenses/>.
16+
17+
# Copyright (c) 2014-2015 by Evan Mason
18+
19+
#===========================================================================
20+
21+
# eddy_tracker_configuration.yml
22+
23+
# Version 2.0.0
24+
#===========================================================================
25+
26+
# See <http://yaml.org/> and <http://pyyaml.org/> for rules on editing this file.
227

328
VERBOSE: No
429

haversine.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module haversine
1616
! You should have received a copy of the GNU General Public License
1717
! along with py-eddy-tracker. If not, see <http://www.gnu.org/licenses/>.
1818
!
19-
! Copyright (c) 2014 by Evan Mason
19+
! Copyright (c) 2014-2015 by Evan Mason
2020
2121
!
2222
! ===========================================================================
@@ -27,7 +27,7 @@ module haversine
2727
!
2828
! If you have ifort on your system, change 'gfortran' to 'intelem'!
2929
!
30-
! Version 1.4.2
30+
! Version 2.0.0
3131
!
3232
!===========================================================================
3333
implicit none

make_eddy_track_AVISO.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
You should have received a copy of the GNU General Public License
1919
along with py-eddy-tracker. If not, see <http://www.gnu.org/licenses/>.
2020
21-
Copyright (c) 2014 by Evan Mason
21+
Copyright (c) 2014-2015 by Evan Mason
2222
2323
===============================================================================
2424
2525
make_eddy_track_AVISO.py
2626
27-
Version 1.4.2
27+
Version 2.0.0
2828
2929
3030
Scroll down to line ~640 to get started

make_eddy_track_ROMS.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -*- coding: utf-8 -*-
2-
# %run make_eddy_track.py
2+
# %run make_eddy_track_ROMS.py
33

44
"""
55
===========================================================================
@@ -18,13 +18,13 @@
1818
You should have received a copy of the GNU General Public License
1919
along with py-eddy-tracker. If not, see <http://www.gnu.org/licenses/>.
2020
21-
Copyright (c) 2014 by Evan Mason
21+
Copyright (c) 2014-2015 by Evan Mason
2222
2323
===========================================================================
2424
2525
make_eddy_track_ROMS.py
2626
27-
Version 1.4.1
27+
Version 2.0.0
2828
2929
3030

make_eddy_tracker_list_obj.py

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
You should have received a copy of the GNU General Public License
1919
along with py-eddy-tracker. If not, see <http://www.gnu.org/licenses/>.
2020
21-
Copyright (c) 2014 by Evan Mason
21+
Copyright (c) 2014-2015 by Evan Mason
2222
2323
===========================================================================
2424
2525
2626
make_eddy_tracker_list_obj.py
2727
28-
Version 1.4.2
28+
Version 2.0.0
2929
3030
3131
===========================================================================
@@ -164,23 +164,22 @@ def __init__(self, PRODUCT, lon, lat, time, uavg, teke,
164164
uavg_profile=None, shape_error=None):
165165

166166
#self.eddy_index = eddy_index
167-
self.PRODUCT = PRODUCT
168-
self.lon = [lon]
169-
self.lat = [lat]
167+
self.PRODUCT = PRODUCT
168+
self.lon = [lon]
169+
self.lat = [lat]
170170
self.ocean_time = [time]
171-
self.uavg = [uavg]
172-
self.teke = [teke]
173-
self.radius_s = [radius_s] # speed-based eddy radius
174-
self.radius_e = [radius_e] # effective eddy radius
175-
self.amplitude = [amplitude]
171+
self.uavg = [uavg]
172+
self.teke = [teke]
173+
self.radius_s = [radius_s] # speed-based eddy radius
174+
self.radius_e = [radius_e] # effective eddy radius
175+
self.amplitude = [amplitude]
176176
if 'ROMS' in self.PRODUCT:
177-
#self.temp = [temp]
177+
#self.temp = [temp]
178+
#self.salt = [salt]
178179
pass
179-
#self.salt = [salt]
180-
#self.bounds = np.atleast_2d(bounds)
181-
self.alive = True
182-
self.dayzero = True
183-
self.saved2nc = False
180+
self.alive = True
181+
self.dayzero = True
182+
self.saved2nc = False
184183
self.save_extras = save_extras
185184
if self.save_extras:
186185
self.contour_e = [contour_e]
@@ -222,7 +221,9 @@ def _is_alive(self, rtime):
222221
If not active, kill it
223222
"""
224223
# The eddy...
225-
if self.alive is False: # is already dead
224+
#print not self.alive, self.dayzero, self.ocean_time[-1] == rtime
225+
if not self.alive: # is already dead
226+
#print '--AAA'
226227
return self.alive
227228
elif self.dayzero: # has just been initiated
228229
self.dayzero = False
@@ -367,7 +368,7 @@ def __getstate__(self):
367368
"""pops = ('uspd', 'uspd_coeffs', 'sla_coeffs', 'points',
368369
'circlon', 'circlat', 'sla', 'slacopy', 'swirl',
369370
'mask_eff', 'mask_eff_sum', 'mask_eff_1d')"""
370-
pops = ('uspd', 'uspd_coeffs', 'sla_coeffs', 'points',
371+
pops = ('uspd', 'uspd_coeffs', 'sla_coeffs', 'points',
371372
'sla', 'slacopy', 'swirl',
372373
'mask_eff', 'mask_eff_sum', 'mask_eff_1d')
373374
result = self.__dict__.copy()
@@ -479,8 +480,8 @@ def get_active_tracks(self, rtime):
479480
inactive tracks.
480481
"""
481482
active_tracks = []
482-
for i, item in enumerate(self.tracklist):
483-
if item._is_alive(rtime):
483+
for i, track in enumerate(self.tracklist):
484+
if track._is_alive(rtime):
484485
active_tracks.append(i)
485486
return active_tracks
486487

@@ -491,8 +492,8 @@ def get_inactive_tracks(self, rtime):
491492
inactive tracks
492493
"""
493494
inactive_tracks = []
494-
for i, item in enumerate(self.tracklist):
495-
if not item._is_alive(rtime):
495+
for i, track in enumerate(self.tracklist):
496+
if not track._is_alive(rtime):
496497
inactive_tracks.append(i)
497498
return inactive_tracks
498499

@@ -715,13 +716,11 @@ def _reduce_inactive_tracks(self):
715716
if not track.alive:
716717
track.lon = []
717718
track.lat = []
718-
track.qparameter = []
719719
track.amplitude = []
720720
track.uavg = []
721721
track.teke = []
722722
track.radius_s = []
723723
track.radius_e = []
724-
#track.bounds = []
725724
track.ocean_time = []
726725
if self.TRACK_EXTRA_VARIABLES:
727726
track.contour_e = []
@@ -730,6 +729,21 @@ def _reduce_inactive_tracks(self):
730729
track.shape_error = []
731730
return
732731

732+
def _remove_inactive_tracks(self):
733+
"""
734+
Remove dead tracks from self.tracklist and
735+
return indices to active tracks.
736+
"""
737+
new_tracklist = []
738+
for track in self.tracklist:
739+
new_tracklist.append(track.alive)
740+
#print new_tracklist
741+
alive_inds = np.nonzero(new_tracklist)[0]
742+
#print alive_inds.shape
743+
tracklist = np.array(self.tracklist)[alive_inds]
744+
self.tracklist = tracklist.tolist()
745+
return alive_inds
746+
733747
def write2netcdf(self, rtime):
734748
"""
735749
Write inactive tracks to netcdf file.
@@ -823,27 +837,29 @@ def write2netcdf(self, rtime):
823837
nc.sync()
824838

825839
# Get index to first currently active track
826-
try:
827-
lasti = self.get_active_tracks(rtime)[0]
828-
except Exception:
829-
lasti = None
840+
#try:
841+
#lasti = self.get_active_tracks(rtime)[0]
842+
#except Exception:
843+
#lasti = None
830844

845+
# Remove inactive tracks
846+
# NOTE: line below used to be below clipping lines below
847+
#self._reduce_inactive_tracks()
848+
alive_i = self._remove_inactive_tracks()
831849
# Clip the tracklist,
832850
# removes all dead tracks preceding first currently active track
833-
self.tracklist = self.tracklist[lasti:]
851+
#self.tracklist = self.tracklist[alive_i:]
834852
self.index = len(self.tracklist) # adjust index accordingly
835853

836-
# Remove inactive tracks
837-
self._reduce_inactive_tracks()
838854

839855
# Update old_lon and old_lat...
840-
self.old_lon = self.new_lon[lasti:]
841-
self.old_lat = self.new_lat[lasti:]
842-
self.old_radii_s = self.new_radii_s[lasti:]
843-
self.old_radii_e = self.new_radii_e[lasti:]
844-
self.old_amp = self.new_amp[lasti:]
845-
self.old_uavg = self.new_uavg[lasti:]
846-
self.old_teke = self.new_teke[lasti:]
856+
self.old_lon = np.array(self.new_lon)[alive_i].tolist()
857+
self.old_lat = np.array(self.new_lat)[alive_i].tolist()
858+
self.old_radii_s = np.array(self.new_radii_s)[alive_i].tolist()
859+
self.old_radii_e = np.array(self.new_radii_e)[alive_i].tolist()
860+
self.old_amp = np.array(self.new_amp)[alive_i].tolist()
861+
self.old_uavg = np.array(self.new_uavg)[alive_i].tolist()
862+
self.old_teke = np.array(self.new_teke)[alive_i].tolist()
847863

848864
self.new_lon = []
849865
self.new_lat = []
@@ -855,17 +871,17 @@ def write2netcdf(self, rtime):
855871
self.new_time = []
856872

857873
if 'ROMS' in self.PRODUCT:
858-
#self.old_temp = self.new_temp[lasti:]
859-
#self.old_salt = self.new_salt[lasti:]
874+
#self.old_temp = self.new_temp[alive_i:]
875+
#self.old_salt = self.new_salt[alive_i:]
860876
pass
861877
#self.new_temp = []
862878
#self.new_salt = []
863879

864880
if self.TRACK_EXTRA_VARIABLES:
865-
self.old_contour_e = list(self.new_contour_e[lasti:])
866-
self.old_contour_s = list(self.new_contour_s[lasti:])
867-
self.old_uavg_profile = list(self.new_uavg_profile[lasti:])
868-
self.old_shape_error = self.new_shape_error[lasti:]
881+
self.old_contour_e = list(self.new_contour_e[alive_i])
882+
self.old_contour_s = list(self.new_contour_s[alive_i])
883+
self.old_uavg_profile = list(self.new_uavg_profile[alive_i])
884+
self.old_shape_error = self.new_shape_error[alive_i]
869885

870886
self.new_contour_e = []
871887
self.new_contour_s = []
@@ -968,6 +984,7 @@ def __init__(self, THE_DOMAIN, grd, RW_PATH=None):
968984
self.beta = np.empty(1)
969985
self.r_spd_long = np.empty(1)
970986
self.start = True
987+
self.pio180 = np.pi / 180.
971988

972989
def __getstate__(self):
973990
"""
@@ -1087,7 +1104,7 @@ def _get_rlongwave_spd(self, xpt, ypt):
10871104
self.r_spd_long **= 2
10881105
self.beta[:] = np.average(self._lat[self.i],
10891106
weights=self._weights) # lat
1090-
self.beta[:] = np.cos(np.deg2rad(self.beta))
1107+
self.beta[:] = np.cos(self.pio180 * self.beta)
10911108
self.beta *= 1458e-7 # 1458e-7 ~ (2 * 7.29*10**-5)
10921109
self.beta /= self.EARTH_RADIUS
10931110
self.r_spd_long *= -self.beta

0 commit comments

Comments
 (0)