In [3]:
from math import pi
import math
import datetime
from config import AMP_heading
from config import M3_swath
from config import M3_avgeraging_time
from targets import TargetSpace
from targets import Target
import rules
import comms
import classification as classif
In [4]:
ts = TargetSpace()
In [13]:
ts.tables = {'adcp': [[datetime.datetime(2016, 3, 8, 23, 47, 16, 600000),1.2,4.5],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 600000),5.6,2.5]],
'camera': [],
'classifier_classifications': [1],
'classifier_features': [],
'nims': [[datetime.datetime(2016, 3, 8, 23, 47, 16, 606170),
213,
1225,
26648,
3.255762865359059,
1.009538904487781,
0.33651296816259363,
0.3397229332247963,
1,
0,
0,
120,
50,
81.59374223255094,
38.3912730413624,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 606170),
221,
764,
27109,
2.6585455797134,
0.9990226307834469,
0.3330075435944823,
0.3326820722724931,
4.749735623188873e-05,
0,
0,
120,
50,
46.89115349587096,
36.90071673015692,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 606170),
230,
662,
27211,
-1.4252885390060634,
3.144248887280707,
1.0480829624269024,
3.2954336883886546,
1,
0,
0,
120,
50,
64.45498648235723,
45.6643834242734,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 606170),
232,
532,
27341,
2.890572359393626,
3.632297183140556,
1.2107657277135186,
4.397860942216939,
1,
0,
0,
120,
50,
62.32347596039271,
36.98009428240289,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 606170),
233,
243,
27630,
0.765336539780397,
2.0736340537675213,
0.6912113512558404,
1.4333193963147746,
0.006207837847612895,
0,
0,
120,
50,
49.21580297831671,
23.907033796827886,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 18, 880554),
213,
1226,
26648,
3.327882881606094,
1.009538904487781,
0.33651296816259363,
0.3397229332247963,
0.04768479173654866,
0,
0,
120,
50,
82.17312165722745,
38.70562258528113,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 880554),
221,
765,
27109,
2.561834802661609,
0.9990226307834469,
0.3330075435944823,
0.3326820722724931,
4.2568959617736036e-06,
0,
0,
120,
50,
46.89112643708125,
36.90070054109199,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 880554),
230,
663,
27211,
-1.347039165042165,
3.144248887280707,
1.0480829624269024,
3.2954336883886546,
1,
0,
0,
120,
50,
65.05607597023428,
45.51592097830661,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 880554),
232,
533,
27341,
2.844387888261456,
3.632297183140556,
1.2107657277135186,
4.397860942216939,
0.06967176481633819,
0,
0,
120,
50,
61.548294381352996,
36.95444344388781,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 880554),
233,
244,
27630,
0.7439338175799398,
2.0736340537675213,
0.6912113512558404,
1.4333193963147746,
1,
0,
0,
120,
50,
49.22192287980031,
23.90526033283612,
None],
[datetime.datetime(2016, 3, 8, 23, 47, 16, 880554),
218,
244,
27630,
0.7439338175799398,
2.0736340537675213,
0.6912113512558404,
1.4333193963147746,
1,
0,
0,
120,
50,
49.22192287980031,
23.90526033283612,
[0, 5]]],
'pamguard': [datetime.datetime(2016, 3, 8, 23, 47, 16, 800000),"Dolphin"]}
In [14]:
target1 = Target(target_space=ts,
source="MSL_auto",
date=datetime.datetime(2016, 3, 8, 23, 47, 16, 880554),
indices={'nims': 10, 'adcp': 0, 'classifier_features':[], 'classifier_classifications':0})
In [19]:
def target_velocity(target):
"""
Calculates "delta_v" for classification given a target.
Delta_v is the norm of the difference between the current velocity
and the target velocity. This function returns the maximum delta_v
calculated for the target. Target velocity is calculated at intervals
of M3_averaging_time
i.e. if M3_averaging_time is 1 second, and a target was detected every
ping at 10 Hz for 5 seconds, the velocity would be calculated 5 times.
The most recent ADCP data at the time of target detection is used to
calculate delta_v.
"""
# extract target data
nims_indices = target.get_entry('nims')['aggregate_indices']
adcp = target.get_entry('adcp')
# sort nims data by timestamp
sorted(nims_indices,
key = lambda x: target_space.get_entry_by_index('nims', x)['timestamp'])
# extract all targets from nims data
targets = extract_targets(target, nims_indices)
points_to_avg = []
index = 0
# determine points between which to calculate velocity (must have at least
# M3_averaging_time between the timestamps)
while index < (len(targets)-1):
start_time = targets[index]['timestamp']
for i, target in enumerate(targets):
# add to points_to_avg if the difference in time between
# target sightings is greater than the M3_averaging_time
diff = delta_t_in_seconds(target['timestamp'], start_time)
if diff >= M3_avgeraging_time:
points_to_avg.append(targets[i])
index = i
break
if i >= (len(targets)-1):
# if the target was less than the M3_averaging_time, use first
# and last points
index = i
points_to_avg.append(targets[0])
points_to_avg.append(targets[-1])
break
delta_v = calc_delta_v(points_to_avg, adcp)
return max(delta_v)
def velocity_between_two_points(point1, point2):
"""
Determines magnitude and direction of target trajectory (from point 1 to point 2)
Inputs:
point 1, point 2 = points where target was detected, in list format [range, bearing in degrees]
AMP_heading = heading of AMP, in radians from due north
M3_swath = list containing minimum and maximum angle ( in degrees) for M3 target
detection. Default is 0 --> 120 degrees
Outputs:
vel = [velocity magnitude, velocity direction]
"""
point1_cartesian = transform_NIMS_to_vector(point1)
point2_cartesian = transform_NIMS_to_vector(point2)
dt = delta_t_in_seconds(point1['timestamp'], point2['timestamp'])
# subtract 2-1 to get velocity
vel = [(point2_cartesian[0] - point1_cartesian[0])/dt,
(point2_cartesian[1] - point1_cartesian[1])/dt]
return(vel)
def transform_NIMS_to_vector(point):
"""
Transform NIMS detection (in format [range, bearing in degrees]) to earth coordinates (East-North)
Returns X-Y coordinates of point after transformation.
"""
# convert target heading to radians, and shift such that zero degrees is center of swath
point_heading = (point['last_pos_angle'] - (M3_swath[1] - M3_swath[0])/2) * pi/180
# convert bearing to angle from due N by subtracting AMP angle
point_heading = point_heading - AMP_heading
# get vector components for point 1 and 2
point_cartesian = [point['last_pos_range'] * math.cos(point_heading),
point['last_pos_range'] * math.sin(point_heading)]
return(point_cartesian)
def delta_t_in_seconds(datetime1, datetime2):
"""
calculate delta t in seconds between two datetime objects
(returns absolute value, so order of dates is insignifigant)
"""
delta_t = datetime1 - datetime2
days_s = delta_t.days*(86400)
microseconds_s = delta_t.microseconds/1000000
delta_t_s = days_s + delta_t.seconds + microseconds_s
return abs(delta_t_s)
def extract_targets(target, nims_indices):
"""
Extract all targets from nims data
"""
targets = []
for index in nims_indices:
targets.append(target.target_space.get_entry_by_index('nims', index))
return targets
def calc_delta_v(points_to_avg, adcp):
"""
returns delta v between all selected points and ADCP
"""
# convert ADCP to cartesian coordinates
velocity_adcp = [adcp['speed'] * math.cos(adcp['heading']),
adcp['speed'] * math.sin(adcp['heading'])]
delta_v = []
for i, target in enumerate(points_to_avg):
# calculate delta_v between two consecutive points
point1 = points_to_avg[i]
try:
point2 = points_to_avg[i+1]
except:
break
# velocity of target between point 1 and point 2
velocity_target = velocity_between_two_points(point1, point2)
# difference between target and adcp velocity
velocity_diff = [velocity_target[0]-velocity_adcp[0],
velocity_target[1]-velocity_adcp[1]]
# "delta_v" is magnitude of velocity difference
delta_v.append((velocity_diff[0]**2 + velocity_diff[1]**2)**0.5)
return(delta_v)
In [20]:
target_velocity(target1)
In [ ]: