Beispiel #1
0
 def exclude_zigZag(self, vlimit, angle=None, returnBlocks=None):
     '''
     CAUSED: by tracking errors
     Reasoning why it must be an error:
         -Fish can have at certain speeds a maximal turning ability.
         -Of course, a startle can exceed this maneuvrability but only for 1 frame
         -For 2 frames followed it is not realistic
     IDENTIFIED: (i) the direction changes stronger as an threshold
                     angle twice
                 (ii) all direction changes happen velocities faster
                     than the limiting speed
     TODO: actually it is not checked if the second direction change goes
             in the opposite direction as the first
     '''
     if returnBlocks is None:
         returnBlocks = False
     if angle is None:
         angle = np.pi / 2
     vel = np.diff(self.dat, axis=0)
     v = np.sqrt(np.sum(vel**2, axis=2))
     # check case (i)
     case1 = np.array([
         gen.angle_between(vel[:-1, i], vel[1:, i]) for i in range(self.N)
     ]).T
     case1 = (case1[:-1] > angle) & (case1[1:] > angle)
     # check case (ii)
     case2 = (v[:-2] > vlimit) & (v[1:-1] > vlimit) & (v[2:] > vlimit)
     zigZag = case1 & case2
     block = gen.find_blocks_large(zigZag.astype(int), 0.5, 1, 1)
     if len(block) > 0:
         # block refers to acceleration: positions 2 frames later needs inclusion
         block[:, 1] += 3
         self.exclude_blocks(block)
         if returnBlocks:
             return block
Beispiel #2
0
 def exclude_jumps2(self, returnBlocks=None):
     '''
     CAUSED: by missing frames or id-switch
     IDENTIFIED: (i) by an positive acceleration
                     directly followed by a similar negative acceleration
                     -> acc = [80, -80]
                 (ii) the acceleration should have doubled the speed
     '''
     if returnBlocks is None:
         returnBlocks = False
     vel = np.diff(self.dat, axis=0)
     v = np.sqrt(np.sum(vel**2, axis=2))
     acc = np.diff(v, axis=0)
     case1 = -acc[:-1] / acc[1:]
     case1 = (0.8 < case1) & (case1 < 1.2) & (acc[:-1] > 0)
     # check case (ii)
     case2 = (acc[:-1] / v[:-2]) > 2
     jump = case1 & case2
     block = gen.find_blocks_large(jump.astype(int), 0.5, 1, 1)
     if len(block) > 0:
         # block refers to acceleration: positions 2 frames later needs inclusion
         block[:, 1] += 3
         self.exclude_blocks(block)
         if returnBlocks:
             return block
Beispiel #3
0
def get_update_rate(acc_s):
    '''
    returns the update events, length and the 
    "update" (marked by 1st. positive acceleration)
    estimated in window of size "win"
    INPUT:
        acc_s.shape(time, N)
            change of speed NOT of velocity-vector
            OR
            CLASS with attr. acc_s
        win float
    OUTPUT:
        update.shape(time, N)
    '''
    if hasattr(acc_s, 'acc_s'):
        acc_s = acc_s.acc_s
    assert len(acc_s.shape) == 2, 'len(acc_s.shape) != 2'
    time, N = acc_s.shape

    update = np.zeros((time, N), dtype='float')
    upLen = []
    upAcc = []
    for i in range(N):
        blocks = gen.find_blocks_large(acc_s[:, i], 0, 1, 1)
        if len(blocks) > 0:
            update[blocks[:, 0], i] = 1  # = update time series
            temp = list(blocks[:, 1] + 1 - blocks[:, 0])
            upLen.append(temp)
            temp = [acc_s[b[0]:b[1] + 1].mean() for b in blocks]
            upAcc.append(temp)
    return update, upLen, upAcc
Beispiel #4
0
def get_burst_behavior(burstPlus_coastMinus, acc_s, acc_v, acc_phi, s, d_phi):
    '''
    INPUT:
        burstPlus_coastMinus shape=(time, N)
            timeseries which marks a burst with +1 and coast with -1
        acc_s shape=(time, N)
            acceleration
        s shape=(time, N)
            speed
    OUTPUT:
        coast_acc list
            accelerations at coasting
        coast_s list
            speed at coasting
    '''
    assert len(acc_s.shape) == 2, 'len(acc_s.shape) != 2'
    time, N = acc_s.shape
    burst_acc_s = []
    burst_acc_v = []
    burst_acc_phi = []
    burst_s = []
    burst_d_phi = []
    for i in range(N):
        thereLarge = gen.find_blocks_large(burstPlus_coastMinus[:, i],
                                           0,
                                           1,
                                           1,
                                           noBlocks=True)
        if len(thereLarge) > 0:
            burst_acc_s.append(list(acc_s[thereLarge, i]))
            burst_acc_v.append(list(acc_v[thereLarge, i]))
            burst_acc_phi.append(list(acc_phi[thereLarge, i]))
            burst_s.append(list(s[thereLarge, i]))
            burst_d_phi.append(list(d_phi[thereLarge, i]))
    return burst_acc_s, burst_acc_v, burst_acc_phi, burst_s, burst_d_phi
Beispiel #5
0
def get_burst_blockDetails(burstPlus_coastMinus):
    '''
    in contrast to get_burst_behavior it just returns
    the start-, end-time and the ID of the bursting agent
        This allows in combination with the other measures
        to estimate the social forces
    INPUT:
        burstPlus_coastMinus shape=(time, N)
            timeseries which marks a burst with +1 and coast with -1
    OUTPUT:
        burstBlockDetails list [[t_start, t_end, IDburst], ...]
            list of block-detail-lists where the latter defines start
            and end time and ID of burster
    '''
    assert len(
        burstPlus_coastMinus.shape) == 2, 'Invalid Shape: len(shape) != 2'
    time, N = burstPlus_coastMinus.shape
    burstStart = []
    burstEnd = []
    bursterID = []
    for i in range(N):
        blocksLarge = gen.find_blocks_large(burstPlus_coastMinus[:, i],
                                            0,
                                            1,
                                            1,
                                            noBlocks=False)
        if len(blocksLarge) > 0:
            blocksLarge = np.array(blocksLarge).T
            burstStart += list(blocksLarge[0])
            burstEnd += list(blocksLarge[1])
            bursterID += len(blocksLarge[0]) * [i]
    return burstStart, burstEnd, bursterID
Beispiel #6
0
 def exclude_jumps(self, speed_max, speed_mean, returnBlocks=None):
     '''
     CAUSED: by missing frames or id-switch
     IDENTIFIED: by an extreme positive acceleration
                 directly followed by extreme negative acceleration
                 -> acc = [80, -80]
     extreme acceleration= speed_max - speed_mean
     '''
     if returnBlocks is None:
         returnBlocks = False
     vel = np.diff(self.dat, axis=0)
     v = np.sqrt(np.sum(vel**2, axis=2))
     acc = np.diff(v, axis=0)
     jump = -1 * np.diff(acc, axis=0)
     crazy_jump = (speed_max - speed_mean) * 2
     block = gen.find_blocks_large(jump, crazy_jump, 1, 1)
     if len(block) > 0:
         # block refers to acceleration: positions 2 frames later needs inclusion
         block[:, 1] += 2
         self.exclude_blocks(block)
         if returnBlocks:
             return block
Beispiel #7
0
 def make_v_block(self):
     '''
     computes from excluded blocks the valid blocks:
     e.g.:
         ex_block = [[0, 10], [100, 140], [end-3, end]]
         ->
         v_block = [[11, 99], [141, end-4]]
     '''
     if hasattr(self, 'ex_block'):
         # if whole block is excluded
         if self.ex_block[0, 0] == 0 and self.ex_block[0,
                                                       1] == self.time - 1:
             self.v_block = np.zeros((0, 2), dtype='int')
             self.v_time = np.array([0])
             self.v_N = len(self.v_block)
             return
         valid = np.ones(self.time)
         for ex in self.ex_block:
             valid[ex[0]:ex[1] + 1] = 0
         self.v_block = gen.find_blocks_large(valid, 0.5, 1, 1)
     else:
         self.v_block = np.array([[0, self.time - 1]])
     self.v_time = (np.diff(self.v_block, axis=1) + 1).flatten()
     self.v_N = len(self.v_block)