def main(args): global g_output_dir g_output_dir = pj( ut.get_repo_dir(), "out/hough" ) img_dir = pj( ut.get_repo_dir(), "data/hough" ) img_fn = args.image_file img = cv2.imread( pj(img_dir, img_fn) ) edged = ut.detect_edges(img) edged_fn = img_fn[:-4] + "_edged.png" cv2.imwrite( pj(g_output_dir, edged_fn), edged ) hough_lines(np.copy(edged), np.copy(img), img_fn) hough_lines_p(np.copy(edged), np.copy(img), img_fn) bw = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) hough_circles(bw, np.copy(img), img_fn)
elif self.tuning == TuningParam.lamb: assert self.use_ppc, 'need to use ppc to tune lambda' *_, ppc_ind = self.get_ppc_off(frame, p_int) # ppc_ind: (B, F, T, J) ppc_ind_throw = torch.gather(ppc_ind, 2, tof).squeeze() # B, F, J ppc_ind_throw = torch.gather(ppc_ind_throw, 1, ball_field_ind).squeeze() # B, J return ppc_ind_throw if __name__ == '__main__': # args parser = argparse.ArgumentParser() parser.add_argument('-d', '--data_dir', default=os.path.join(get_repo_dir(), 'data'), help='path to directory with data files') parser.add_argument('-j', '--num_workers', default=4, help='number of data loader workers', type=int) parser.add_argument('-b', '--batch_size', default=4, help='batch size to use', type=int) parser.add_argument('-e', '--epochs', default=5, help='number of training epochs',
self.input_noise_std) out = self.net(net_input) total_loss = self.loss(out, image) total_loss.backward() if iter_num == self.iters[self.iter_idx]: self.iter_idx += 1 self.save(iter_num, torch_to_np(out)) if self.iter_idx == len(self.iters): self.iter_idx = 0 def run_all(self): for image, target in tqdm(self.dataloader): self.run(image.to(self.device)) data = CIFAR10(root=os.path.join(get_repo_dir(), 'data'), train=True, download=True, transform=identity_transform) save_dir = os.path.join(get_repo_dir(), 'data/transforms') os.makedirs(save_dir, exist_ok=True) #first = True #hashes = set() #if first: # for im, t in data: # hashes.add(image_hash(im)) # assert len(data) == len(hashes), 'colliding hash' # pickle.dump(hashes, open(os.path.join(save_dir, 'hashes.pkl'), 'wb')) #else: # hashes_old = pickle.load(open(os.path.join(save_dir, 'hashes.pkl'), 'rb'))
def play_eppa_cpu(track_df, game_id, play_id, viz_df=False, save_np=False, stats_df=False, viz_true_proj=False, save_all_dfs=False, out_dir_path=join(get_repo_dir(), 'output/{}'), simulatePass=None): play_df = track_df[(track_df.playId == play_id) & (track_df.gameId == game_id)].sort_values( by='frameId') events = set(play_df.event.unique()) if 'pass_forward' not in events: raise ValueError('No Pass Forward in play') if 'fumble' in events: raise ValueError('Fumble in play') ball_snap_frame = play_df.loc[ (play_df.nflId == 0) & (play_df.event == 'ball_snap')].frameId.iloc[0] pass_forward_frame = play_df.loc[(play_df.nflId == 0) & ( (play_df.event == 'pass_forward') | (play_df.event == 'pass_shovel'))].frameId.sort_values().iloc[0] play_df['frames_since_snap'] = play_df.frameId - ball_snap_frame pass_arriveds = play_df.loc[(play_df.nflId == 0) & (play_df.event == 'pass_arrived'), 'frameId'].to_list() true_pass_found = len(pass_arriveds) > 0 if true_pass_found: true_pass_completed = ('pass_outcome_caught' in events) or ('pass_outcome_touchdown' in events) pass_arrived_frame = pass_arriveds[0] true_T_frames = pass_arrived_frame - pass_forward_frame true_x, true_y = play_df.loc[(play_df.nflId == 0) & (play_df.event == 'pass_arrived'), ['x', 'y']].iloc[0].to_numpy(dtype=dt) print( f"True Pass: t: {pass_forward_frame} x:{true_x} y:{true_y} T:{true_T_frames/10}" ) true_T_idx = np.rint(true_T_frames).astype(int) - 1 true_x_idx = np.clip((true_x).astype(int), 0, len(xx[0]) - 1) # this is a bug true_y_idx = np.clip((true_y).astype(int) + 1, 0, len(xx) - 1) # this is a bug true_f_idx = np.ravel_multi_index((true_y_idx, true_x_idx), xx.shape) (true_x_idxd, true_y_idxd), true_T_idxd = field_locs[true_f_idx], T[true_T_idx] print( f"True Pass idxs: t: {pass_forward_frame} x:{true_x_idx} y:{true_y_idx} f:{true_f_idx} T:{true_T_idx}" ) print( f"True Pass idxd: t: {pass_forward_frame} x:{true_x_idxd} y:{true_y_idxd} T:{true_T_idxd}" ) else: print(f"No True Pass Found: No pass_arrived event \n") if simulatePass != None: sim_frame, true_x, true_y, true_T = simulatePass print(f"Simming Pass: t: {sim_frame} x:{true_x} y:{true_y} T:{true_T}") true_T_idx = np.rint(true_T * 10).astype(int) - 1 true_x_idx = np.clip(dt(true_x).astype(int), 0, len(xx[0]) - 1) # this is a bug true_y_idx = np.clip(dt(true_y).astype(int) + 1, 0, len(xx) - 1) # this is a bug true_f_idx = np.ravel_multi_index((true_y_idx, true_x_idx), xx.shape) (true_x_idxd, true_y_idxd), true_T_idxd = field_locs[true_f_idx], T[true_T_idx] print( f"Sim Pass idxs: t: {pass_forward_frame} x:{true_x_idx} y:{true_y_idx} f:{true_f_idx} T:{true_T_idx}" ) print( f"Sim Pass idxd: t: {pass_forward_frame} x:{true_x_idxd} y:{true_y_idxd} T:{true_T_idxd}" ) # per play epa model def getEPAModel(): epvals = np.array([7, -7, 3, -3, 2, -2, 0]) joined_df = pbp_joined[(pbp_joined.playId == play_id) & (pbp_joined.gameId == game_id)] epa_df = pd.DataFrame({'play_endpoint_x': x}) test = {} for feat in epa_model.feature_names: test[feat] = [joined_df.iloc[0][feat]] epa_df[feat] = joined_df.iloc[0][feat] first_df = pd.DataFrame(test) dtest = treelite_runtime.Batch.from_npy2d( first_df[cols_when_model_builds_ep].values) ypred = epa_predictor.predict(dtest) ep = np.sum(ypred * epvals, axis=1) epa_df["before_play_ep"] = ep[0] ###### EP FOR A INCOMPLETE ####### epa_df_incomp = epa_df.copy(deep=True) old_down = joined_df.iloc[0]['down_x'] epa_df_incomp['isFirstDown'] = 0 for d in range(1, 6): epa_df_incomp['down%d' % d] = 1 if (d == old_down + 1) else 0 # offense is other team inverted if turnover on downs epa_df_incomp['yardline_100'] = np.where( epa_df_incomp.down5 == 1, 100 - epa_df_incomp['yardline_100'], epa_df_incomp['yardline_100']) epa_df_incomp['ydstogo'] = np.where(epa_df_incomp.down5 == 1, 10, epa_df_incomp['ydstogo']) epa_df_incomp['down1'] = np.where(epa_df_incomp.down5 == 1, 1, epa_df_incomp['down1']) dtest = treelite_runtime.Batch.from_npy2d( epa_df_incomp[cols_when_model_builds_ep].values) ypred = epa_predictor.predict(dtest) ep = np.sum(ypred * epvals, axis=1) epa_df['xep_inc'] = ep epa_df['xepa_inc'] = np.where( epa_df_incomp.down5 == 1, -epa_df['xep_inc'] - epa_df_incomp['before_play_ep'], epa_df['xep_inc'] - epa_df_incomp['before_play_ep']) ###### EP FOR A CATCH ####### epa_df['los'] = 110 - epa_df['yardline_100'] epa_df['first_down_line'] = epa_df['los'] + epa_df["ydstogo"] epa_df['expected_end_up_line'] = epa_df['play_endpoint_x'] epa_df['isFirstDown'] = 0 epa_df['isFirstDown'] = np.where( epa_df['expected_end_up_line'] >= epa_df['first_down_line'], 1, 0) epa_df['yardline_100'] = np.round(110 - epa_df['expected_end_up_line']) epa_df['yardline_100'] = np.clip(epa_df['yardline_100'], 0, 100) epa_df['ydstogo'] = epa_df['first_down_line'] - epa_df[ 'expected_end_up_line'] epa_df['ydstogo'] = np.where(epa_df['isFirstDown'] == 1, 10, epa_df['ydstogo']) old_down = joined_df.iloc[0]['down_x'] for d in range(1, 6): epa_df['down%d' % d] = 1 if (d == old_down + 1) else 0 epa_df['down1'] = np.where(epa_df['isFirstDown'] == 1, 1, epa_df['down1']) epa_df['down2'] = np.where(epa_df['isFirstDown'] == 1, 0, epa_df['down2']) epa_df['down3'] = np.where(epa_df['isFirstDown'] == 1, 0, epa_df['down3']) epa_df['down4'] = np.where(epa_df['isFirstDown'] == 1, 0, epa_df['down4']) epa_df['down5'] = np.where( epa_df['isFirstDown'] == 1, 0, epa_df['down5']) # down 5 means turnover on downs # offense is other team inverted if turnover on downs epa_df['yardline_100'] = np.where(epa_df.down5 == 1, 100 - epa_df['yardline_100'], epa_df['yardline_100']) epa_df['ydstogo'] = np.where(epa_df.down5 == 1, 10, epa_df['ydstogo']) epa_df['down1'] = np.where(epa_df.down5 == 1, 1, epa_df['down1']) ### UPDATE EPA VARIABLES ### dtest = treelite_runtime.Batch.from_npy2d( epa_df[cols_when_model_builds_ep].values) ypred = epa_predictor.predict(dtest) ep = np.sum(ypred * epvals, axis=1) epa_df['xep'] = ep # ep after play # SCORE SAFETIES epa_df['xep'] = np.where(epa_df['play_endpoint_x'] <= 10, -2, epa_df['xep']) # SCORE Tds epa_df['xep'] = np.where(epa_df['play_endpoint_x'] >= 110, 7, epa_df['xep']) epa_df['xepa'] = np.where( epa_df.down5 == 1, -epa_df['xep'] - epa_df['before_play_ep'], epa_df['xep'] - epa_df['before_play_ep']) # if turnover only_vals = epa_df[[ "play_endpoint_x", "xep", "xepa", "xep_inc", "xepa_inc" ]].rename(columns={ 'xep': 'xep_comp', 'xepa': 'xepa_comp' }) # THIS CONTAINS THE EPA VALUES BASED ON PLAY ENDPOINT # breakpoint() return only_vals epa_df = getEPAModel() # input: tracking data for a single frame # output: frame_eppa (F, T)... (writes intermediate F,T to disk) def frame_eppa(frame_id): nonlocal play_df frame_df = play_df.loc[play_df.frameId == frame_id].reset_index() ball_start = frame_df.loc[frame_df.position == 'QB', ['x', 'y']].iloc[0].to_numpy(dtype=dt) t = frame_df.frames_since_snap.iloc[0] frame_df = frame_df.loc[(frame_df.nflId != 0) & ( frame_df.position != 'QB')] # remove ball and qb from df reach_vecs = (field_locs - ball_start).astype(dt) # (F, 2) frame_df = frame_df.drop_duplicates( subset='nflId').sort_values('nflId').reset_index() # project motion by reaction time frame_df['v_x_r'] = frame_df.a_x * params.reax_t + frame_df.v_x frame_df['v_y_r'] = frame_df.a_y * params.reax_t + frame_df.v_y frame_df['v_r_mag'] = np.linalg.norm(np.array( [frame_df.v_x_r, frame_df.v_y_r], dtype=dt), axis=0) frame_df['v_r_theta'] = np.arctan2(frame_df.v_y_r, frame_df.v_x_r) frame_df[ 'x_r'] = frame_df.x + frame_df.v_x * params.reax_t + 0.5 * frame_df.a_x * params.reax_t**2 frame_df[ 'y_r'] = frame_df.y + frame_df.v_y * params.reax_t + 0.5 * frame_df.a_y * params.reax_t**2 player_teams = frame_df['team_pos'].to_numpy() # J, player_team_names = frame_df['teamAbbr'].to_numpy() # J, player_ids = frame_df['nflId'].to_numpy() player_names = frame_df['displayName'].to_numpy() reaction_player_locs = frame_df[['x_r', 'y_r']].to_numpy(dtype=dt) # (J, 2) reaction_player_vels = frame_df[['v_x_r', 'v_y_r']].to_numpy(dtype=dt) # (J,2) # intercept vector between each player and field location int_d_vec = field_locs[:, None, :] - reaction_player_locs # F, J, 2 int_d_mag = np.linalg.norm(int_d_vec, axis=2) # F, J int_d_theta = np.arctan2(int_d_vec[..., 1], int_d_vec[..., 0]) # projecting player velocity on d_vec to get initial speed along d_vec int_s0 = np.clip( np.sum(int_d_vec * reaction_player_vels, axis=2) / int_d_mag, -params.s_max, params.s_max) # F, J, # calculate time to int to ball loc on d_vec based on phys model t_lt_smax = (params.s_max - int_s0) / params.a_max # F, J, d_lt_smax = t_lt_smax * ((int_s0 + params.s_max) / 2) # F, J, # if accelerating would overshoot, then t = -v0/a + sqrt(v0^2/a^2 + 2x/a) (from kinematics) t_lt_smax = np.where( d_lt_smax > int_d_mag, -int_s0 / params.a_max + np.sqrt((int_s0 / params.a_max)**2 + 2 * int_d_mag / params.a_max), t_lt_smax) d_lt_smax = np.clip(d_lt_smax, 0, int_d_mag) d_at_smax = int_d_mag - d_lt_smax # F, J, t_at_smax = d_at_smax / params.s_max # F, J, t_tot = t_lt_smax + t_at_smax + params.reax_t # F, J, # int success if T-t_tot = dT < 0. Put through sigmoid to add temporal uncertainty around int_dT = T[None, :, None] - t_tot[:, None, :] # F, T, J p_int = (1 / (1. + np.exp( -np.pi / np.sqrt(3.0) / params.tti_sigma * int_dT, dtype=dt)) ) # F, T, J p_int_def = 1 - np.prod( (1 - p_int[:, :, (player_teams == 'DEF')]), axis=-1) # F, T p_int_off = 1 - np.prod( (1 - p_int[:, :, (player_teams == 'OFF')]), axis=-1) # F, T p_int_off_adj = p_int_off * (1 - p_int_def) # adjusting indiv p_int to renormalize sum p_int_ind = p_int.copy() p_int_ind[:, :, player_teams == 'DEF'] *= ( p_int_def / np.sum(p_int_ind, where=(player_teams == 'DEF')))[..., None] p_int_ind[:, :, player_teams == 'OFF'] *= ( p_int_off_adj / np.sum(p_int_ind, where=(player_teams == 'OFF')))[..., None] # projected locations at T (F, T, J) d_proj = np.select([ T[None, :, None] <= params.reax_t, T[None, :, None] <= (t_lt_smax + params.reax_t)[:, None, :], True ], [ 0, (int_s0[:, None, :] * (T[None, :, None] - params.reax_t)) + 0.5 * params.a_max * (T[None, :, None] - params.reax_t)**2, d_lt_smax[:, None, :] + params.s_max * (T[None, :, None] - t_lt_smax[:, None, :] - params.reax_t) ]) d_proj = np.minimum( d_proj, int_d_mag[:, None, :]) # no player is going to purposefully overshoot s_proj = np.select([ T[None, :, None] <= params.reax_t, T[None, :, None] <= (t_lt_smax + params.reax_t)[:, None, :], T[None, :, None] <= (t_lt_smax + t_at_smax + params.reax_t)[:, None, :], True ], [ int_s0[:, None, :], int_s0[:, None, :] + params.a_max * (T[None, :, None] - params.reax_t), params.s_max, params.s_max ]) x_proj = reaction_player_locs[None, None, :, 0] + d_proj * np.cos( int_d_theta[:, None, :]) # (F, T, J) y_proj = reaction_player_locs[None, None, :, 1] + d_proj * np.sin( int_d_theta[:, None, :]) # (F, T, J) v_x_proj = s_proj * np.cos(int_d_theta[:, None, :]) # (F, T, J) v_y_proj = s_proj * np.sin(int_d_theta[:, None, :]) # (F, T, J) # input: qb_loc (2,), t=frames_after_snap (int) # output: (P(L,T)|t) int probability of each pass (F, T) def get_hist_trans_prob(): """ P(L|t) """ ball_start_idx = np.rint(ball_start).astype(int) # mask for zeroing out parts of the field that are too far to be thrown to per the L_given_t model L_t_mask = np.zeros_like(xx, dtype=dt) # (Y, X) L_t_mask[max(ball_start_idx[1] + y_min, 0):min(ball_start_idx[1] + y_max, len(y) - 1), max(ball_start_idx[0] + x_min, 0):min(ball_start_idx[0] + x_max, len(x) - 1)] = 1. L_t_mask = L_t_mask.flatten() # (F,) # # we clip reach vecs to be used to index into L_given_t. # # eg if qb is far right, then the left field will be clipped to y=-39 and later zeroed out # reach_vecs_int = np.rint(reach_vecs).astype(int) # clipped_reach_vecs = np.stack((np.clip(reach_vecs_int[:,0], x_min, x_max), # np.clip(-reach_vecs_int[:,1], y_min, y_max))) # (2, F) # t_i = max(t-t_min, 0) # L_given_t = L_given_ts[t_i, clipped_reach_vecs[1]-y_min, clipped_reach_vecs[0]-x_min] * L_t_mask # (F,) ; index with y and then x L_given_t = L_t_mask # changed L_given_t to uniform after discussion L_given_t /= L_given_t.sum( ) # renormalize since part of L|t may have been off field """ P(T|L) """ # we find T|L for sufficiently close spots (1 < L <= 60) reach_dist_int = np.rint(np.linalg.norm( reach_vecs, axis=1)).astype(int) # (F,) reach_dist_in_bounds_idx = (reach_dist_int > 1) & (reach_dist_int <= 60) reach_dist_in_bounds = reach_dist_int[reach_dist_in_bounds_idx] # yards 1-60 map to indices 0-59 so subtract 1 to get index # spots with dist 0 shouldn't wrap around to index -1 so clip T_given_L_subset = T_given_Ls[np.clip( reach_dist_in_bounds - 1, 0, 59 )] # (F~, T) ; F~ is subset of F that is in [1, 60] yds from ball T_given_L = np.zeros((len(field_locs), len(T)), dtype=dt) # (F, T) # fill in the subset of values computed above T_given_L[reach_dist_in_bounds_idx] = T_given_L_subset L_T_given_t = L_given_t[:, None] * T_given_L # (F, T) L_T_given_t /= L_T_given_t.sum( ) # normalize all passes after some have been chopped off return L_T_given_t def get_ppc(): # use p_int as memoized values for integration # trajectory integration g = 10.72468 # y/s/s dx = reach_vecs[:, 0] # F dy = reach_vecs[:, 1] # F vx = dx[:, None] / T[None, :] # F, T vy = dy[:, None] / T[None, :] # F, T vz_0 = (T * g) / 2 # T # note that idx (i, j, k) into below arrays is invalid when j < k traj_ts = np.tile(T, (len(field_locs), len(T), 1)) # (F, T, T) traj_locs_x_idx = np.rint( np.clip((ball_start[0] + vx[:, :, None] * T), 0, len(x) - 1)).astype(int) # F, T, T traj_locs_y_idx = np.rint( np.clip((ball_start[1] + vy[:, :, None] * T), 0, len(y) - 1)).astype(int) # F, T, T traj_locs_z = 2.0 + vz_0[ None, :, None] * traj_ts - 0.5 * g * traj_ts * traj_ts # F, T, T path_idxs = np.ravel_multi_index( np.stack((traj_locs_y_idx, traj_locs_x_idx)).reshape(2, -1), xx.shape) # (F*T*T,) traj_t_idxs = np.rint(10 * traj_ts - 1).flatten().astype( int) # (F, T, T) # TODO ppi_ind_dt = p_int_ind[path_idxs, traj_t_idxs] # F*T*T, J ppi_ind_dt = ppi_ind_dt.reshape( (*traj_locs_x_idx.shape, len(reaction_player_locs))) # F, T, T, J # ppi_off_dt = p_int_off[path_idxs, traj_t_idxs] # F*T*T, # ppi_off_dt = ppi_off_dt.reshape(traj_locs_x_idx.shape) # F, T, T # ppi_def_dt = p_int_def[path_idxs, traj_t_idxs] # F*T*T, # ppi_def_dt = ppi_def_dt.reshape(traj_locs_x_idx.shape) # F, T, T # ppi_off_adj_dt = p_int_off_adj[path_idxs, traj_t_idxs] # F*T*T, # ppi_off_adj_dt = ppi_off_adj_dt.reshape(traj_locs_x_idx.shape) # F, T, T # account for ball height on traj and normalize each locations int probability lambda_z = np.where( (traj_locs_z < params.z_max) & (traj_locs_z > params.z_min), 1, 0) # F, T, T # maybe change this to a normal distribution ppi_ind_dt = ppi_ind_dt * lambda_z[:, :, :, None] # F, T, T # ppi_off_dt = ppi_off_dt * lambda_z[:, :, :, None] # F, T, T # ppi_off_adj_dt = ppi_off_adj_dt * lambda_z[:, :, :, None] # F, T, T # ppi_def_dt = ppi_def_dt * lambda_z[:, :, :, None] # F, T, T # P(ball is still in play at t) ball_in_play_traj = np.cumprod(1 - ppi_ind_dt, axis=-1) ball_in_play_traj = np.roll(ball_in_play_traj, 1, axis=-1) # F, T, T ball_in_play_traj[:, :, 0] = 1 # ppi_def_adj_dt = ball_in_play_traj * ppi_def_dt # F, T, T # ppi_off_adj_dt = ball_in_play_traj * ppi_off_adj_dt # F, T, T ppi_ind_adj_dt = ball_in_play_traj[..., None] * ppi_ind_dt # F, T, T, J # ppi_def_traj = np.cumsum(ppi_def_adj_dt, axis=-1) # ppi_def_traj = np.einsum('ijj->ij', ppi_def_traj) # (F, T) # ppi_off_traj = np.cumsum(ppi_off_adj_dt, axis=-1) # ppi_off_traj = np.einsum('ijj->ij', ppi_off_traj) # (F, T) ppi_ind_traj = np.cumsum(ppi_ind_adj_dt, axis=-2) ppi_ind_traj = np.einsum('ijjk->ijk', ppi_ind_traj) # (F, T, J) ppi_off_traj = np.sum(ppi_ind_traj, where=(player_teams == 'OFF'), axis=-1) # (F, T) ppi_def_traj = np.sum(ppi_ind_traj, where=(player_teams == 'DEF'), axis=-1) # (F, T) ppi_rem_traj = 1 - ppi_def_traj - ppi_off_traj # (F, T) return ppi_off_traj, ppi_def_traj, ppi_ind_traj def get_xyac(): x_proj_def = x_proj[:, :, player_teams == "DEF"] # F, T, J v_proj_def = s_proj[:, :, player_teams == "DEF"] y_proj_def = y_proj[:, :, player_teams == "DEF"] x_proj_relv = x_proj_def - field_locs[:, None, None, 0] # F, T, J #GET RELATIVE COORDS y_proj_relv = y_proj_def - field_locs[:, None, None, 1] # F, T, J #GET RELATIVE COORDS distances_to_ball = np.stack((x_proj_relv, y_proj_relv), axis=-1) # F, T, J, 2 distance_mags = np.linalg.norm(distances_to_ball, axis=-1) # F, T, J sorted_indices = np.argsort(distance_mags, axis=2) # F, T, J distance_mags = np.take_along_axis(distance_mags, sorted_indices, axis=2) # F, T, J x_proj_sorted = np.take_along_axis(x_proj_relv, sorted_indices, axis=2) y_proj_sorted = np.take_along_axis(y_proj_relv, sorted_indices, axis=2) v_proj_sorted = np.take_along_axis(v_proj_def, sorted_indices, axis=2) just_top_5_distances = distance_mags[:, :, 0:5] # F, T, 5 just_top_5_x_proj = x_proj_sorted[:, :, 0:5] # F, T, 5 just_top_5_y_proj = y_proj_sorted[:, :, 0:5] # F, T, 5 just_top_5_v_proj = v_proj_sorted[:, :, 0:5] # F, T, 5 just_top_5_distances = np.reshape( just_top_5_distances, (-1, just_top_5_distances.shape[2])) # (F*T, 5) just_top_5_x_proj = np.reshape(just_top_5_x_proj, just_top_5_distances.shape) just_top_5_y_proj = np.reshape(just_top_5_y_proj, just_top_5_distances.shape) just_top_5_v_proj = np.reshape(just_top_5_v_proj, just_top_5_distances.shape) endpoints = np.repeat(field_locs, repeats=len(T), axis=0) # FxT, 2 # assert((field_locs[:, None, :]+np.zeros_like(T[None, None, :])).reshape(end)) times = np.repeat(T[None, :], repeats=len(field_locs), axis=0) times_shaped = times.reshape( (times.shape[0] * times.shape[1])) # FxT, 1 value_array = np.array( [-2.5, 2.5, 7.5, 12.5, 17.5, 22.5, 27.5, 30]) field_df = pd.DataFrame({ 'pass_endpoint_x': endpoints[:, 0], 'pass_endpoint_y': endpoints[:, 1], 'frame_thrown': t, 'time_of_flight': times_shaped, '1-closest-defender-distance': just_top_5_distances[:, 0], '2-closest-defender-distance': just_top_5_distances[:, 1], '3-closest-defender-distance': just_top_5_distances[:, 2], '4-closest-defender-distance': just_top_5_distances[:, 3], '5-closest-defender-distance': just_top_5_distances[:, 4], '1-closest-defender-x': just_top_5_x_proj[:, 0], '2-closest-defender-x': just_top_5_x_proj[:, 1], '3-closest-defender-x': just_top_5_x_proj[:, 2], '4-closest-defender-x': just_top_5_x_proj[:, 3], '5-closest-defender-x': just_top_5_x_proj[:, 4], '1-closest-defender-y': just_top_5_y_proj[:, 0], '2-closest-defender-y': just_top_5_y_proj[:, 1], '3-closest-defender-y': just_top_5_y_proj[:, 2], '4-closest-defender-y': just_top_5_y_proj[:, 3], '5-closest-defender-y': just_top_5_y_proj[:, 4], '1-closest-defender-speed': just_top_5_v_proj[:, 0], '2-closest-defender-speed': just_top_5_v_proj[:, 1], '3-closest-defender-speed': just_top_5_v_proj[:, 2], '4-closest-defender-speed': just_top_5_v_proj[:, 3], '5-closest-defender-speed': just_top_5_v_proj[:, 4], "y": endpoints[:, 1] }) # CALCULTE XYAC dtest = treelite_runtime.Batch.from_npy2d( field_df[cols_when_model_builds].values) ypred = xyac_predictor.predict(dtest) y_vals = np.sum(ypred * value_array, axis=1) field_df['xyac'] = y_vals field_df['play_endpoint_x'] = np.round(field_df['xyac'] + field_df['pass_endpoint_x']) field_df['play_endpoint_x'] = field_df['play_endpoint_x'] + .5 field_df['play_endpoint_x'] = np.clip(field_df['play_endpoint_x'], 0.5, 119.5) return field_df[[ 'pass_endpoint_x', 'pass_endpoint_y', 'time_of_flight', 'xyac', 'play_endpoint_x' ]] nonlocal epa_df # completion model ppc_off, ppc_def, ppc_ind = get_ppc() # (F, T), (F, T), (F, T, J) # value model epa_xyac_df = get_xyac().merge(epa_df, how='left', on='play_endpoint_x') xyac = epa_xyac_df.xyac.to_numpy().reshape(ppc_off.shape) # end_x = epa_xyac_df.play_endpoint_x.to_numpy().reshape(ppc_off.shape) xepa_comp = epa_xyac_df.xepa_comp.to_numpy().reshape( ppc_off.shape) # F, T xepa_inc = epa_xyac_df.xepa_inc.iloc[0] xepa_diff = xepa_comp - xepa_inc # assert(h_trans_prob.shape == ppc_off.shape) # breakpoint() # transition model h_trans_prob = get_hist_trans_prob() # (F, T) trans = h_trans_prob * np.power(ppc_off, params.alpha) # F, T trans /= trans.sum() # output metrics (eppa1 uses ppc_off as catch prob, eppa2 uses catch_prob) ind_eppa1_wo_value = ppc_ind * trans[..., None] # F, T, J ind_eppa1 = ind_eppa1_wo_value * xepa_diff[..., None] # F, T, J # ind_eppa2_wo_value = catch_prob_ind * trans[..., None] # F, T, J # ind_eppa2 = ind_eppa2_wo_value * xepa_diff[..., None] # F, T, J eppa1_pass_val = (ppc_off * xepa_comp) + (1 - ppc_off) * xepa_inc eppa1 = eppa1_pass_val * trans # F, T # eppa2_pass_val = (catch_prob_off*xepa_comp)+(1-catch_prob_off)*xepa_inc # eppa2 = eppa2_pass_val*trans # F, T eppa1_wo_value = ppc_off * trans # eppa2_wo_value = catch_prob_off*trans # maxEppa1Val = eppa1_pass_val[np.unravel_index(np.argmax(eppa1, axis=None), eppa1.shape)] # maxEppa2Val = eppa2_pass_val[np.unravel_index(np.argmax(eppa2, axis=None), eppa2.shape)] field_df = pd.DataFrame() player_stats_df = pd.DataFrame() passes_df = pd.DataFrame() proj_df = pd.DataFrame() if viz_true_proj and true_pass_found: proj_df['nflId'] = frame_df['nflId'] proj_df['reax_x'] = frame_df['x_r'] proj_df['reax_y'] = frame_df['y_r'] proj_df['reax_v_x'] = frame_df['v_x_r'] proj_df['reax_v_y'] = frame_df['v_y_r'] proj_df['d_vec_x'] = int_d_vec[true_f_idx, :, 0] proj_df['d_vec_y'] = int_d_vec[true_f_idx, :, 1] proj_df['d_mag'] = int_d_mag[true_f_idx] proj_df['int_s0'] = int_s0[true_f_idx] proj_df['t_lt_smax'] = t_lt_smax[true_f_idx] proj_df['d_lt_smax'] = d_lt_smax[true_f_idx] proj_df['t_at_smax'] = t_at_smax[true_f_idx] proj_df['d_at_smax'] = d_at_smax[true_f_idx] proj_df['t_tot'] = t_tot[true_f_idx] proj_df['int_dT'] = int_dT[true_f_idx, true_T_idx] proj_df['p_int'] = p_int[true_f_idx, true_T_idx] proj_df['p_int_adj'] = p_int_adj[true_f_idx, true_T_idx] proj_df['d_proj'] = d_proj[true_f_idx, true_T_idx] # J proj_df['s_proj'] = s_proj[true_f_idx, true_T_idx] # J proj_df['proj_x'] = x_proj[true_f_idx, true_T_idx] # J proj_df['proj_y'] = y_proj[true_f_idx, true_T_idx] # J proj_df['proj_v_x'] = v_x_proj[true_f_idx, true_T_idx] # J proj_df['proj_v_y'] = v_y_proj[true_f_idx, true_T_idx] # J proj_df['ppc_ind'] = ppc_ind[true_f_idx, true_T_idx] # proj_df['catch_prob'] = catch_prob_ind[true_f_idx, true_T_idx] # only valid for off players proj_df['frameId'] = frame_id if save_np: week = games_df.loc[games_df.gameId == game_id].week.to_numpy()[0].item() dir = out_dir_path.format(f'{week}/{game_id}/{play_id}') Path(dir).mkdir(parents=True, exist_ok=True) # np.savez_compressed(f'{dir}/{frame_id}', players_ind_info=ind_info, # ppc_ind=ppc_ind, h_trans=h_trans_prob, xepa=xepa, eppa_ind=eppa_ind) # np.savez_compressed(f'{dir}/{frame_id}', ind_info=ind_info, eppa_ind=eppa_ppc_ind) if stats_df: # ind_eppa1 = ind_eppa1.sum(axis=(0, 1)) # J # ind_eppa1_wo_value = ind_eppa1_wo_value.sum(axis=(0, 1)) # J player_stats_df = pd.DataFrame( { 'gameId': game_id, 'playId': play_id, 'frameId': frame_id, 'frame_after_snap': t, 'nflId': player_ids, 'displayName': player_names, 'team': player_team_names, 'team_pos': player_teams, 'ind_eppa1': ind_eppa1.sum(axis=(0, 1)), 'ind_eppa1_wo_value': ind_eppa1_wo_value.sum(axis=(0, 1)), }, # 'ind_eppa2': ind_eppa2.sum(axis=(0, 1)), # 'ind_eppa2_wo_value': ind_eppa2_wo_value.sum(axis=(0, 1))}, index=player_ids) off_team_name = play_df.loc[play_df.team_pos == 'OFF'].teamAbbr.iloc[0] def_team_name = play_df.loc[play_df.team_pos == 'DEF'].teamAbbr.iloc[0] # fill out passes df row = { 'gameId': game_id, 'playId': play_id, 'frameId': frame_id, 'frames_after_snap': t, 'off_team': off_team_name, 'def_team': def_team_name, 'eppa1_tot': eppa1.sum(), # 'eppa2_tot': eppa2.sum(), 'xepa_inc': xepa_inc } # for name, arr in {'eppa1': eppa1, 'eppa2': eppa2, 'ppc_off': ppc_off, 'catch_prob': catch_prob_off, 'eppa1_pass_val': eppa1_pass_val, # 'eppa2_pass_val': eppa2_pass_val, 'eppa1_wo_value': eppa1_wo_value, 'eppa2_wo_value': eppa2_wo_value}.items(): for name, arr in { 'eppa1': eppa1, 'ppc_off': ppc_off, 'eppa1_pass_val': eppa1_pass_val, 'eppa1_wo_value': eppa1_wo_value }.items(): f, T_idx = np.unravel_index(arr.argmax(), arr.shape) end_x, end_y = field_locs[f] row[f"max_{name}_x"] = end_x row[f"max_{name}_y"] = end_y row[f"max_{name}_T"] = T[T_idx] # row[f"max_{name}_catch_prob"] = catch_prob_off[f, T_idx] row[f"max_{name}_ppc_off"] = ppc_off[f, T_idx] row[f"max_{name}_pint_off"] = p_int_off[f, T_idx] row[f"max_{name}_ppc_def"] = ppc_def[f, T_idx] row[f"max_{name}_pint_def"] = p_int_def[f, T_idx] row[f"max_{name}_xyac"] = xyac[f, T_idx] row[f"max_{name}_xepa_comp"] = xepa_comp[f, T_idx] row[f"max_{name}_trans"] = trans[f, T_idx] row[f"max_{name}_trans_tof"] = h_trans_prob[f, T_idx] row[f"max_{name}_eppa1"] = eppa1[f, T_idx] # row[f"max_{name}_eppa2"] = eppa2[f, T_idx] row[f"max_{name}_eppa1_xval"] = eppa1_pass_val[f, T_idx] # row[f"max_{name}_eppa2_xval"] = eppa2_pass_val[f, T_idx] row[f"max_{name}_eppa1_wo_value"] = eppa1_wo_value[f, T_idx] # row[f"max_{name}_eppa2_wo_value"] = eppa2_wo_value[f, T_idx] if (true_pass_found and frame_id == pass_forward_frame) or ( simulatePass and frame_id == sim_frame): row[f"true_x"] = true_x_idxd row[f"true_y"] = true_y_idxd row[f"true_T"] = true_T_idxd # row[f"true_catch_prob"] = catch_prob_off[true_f_idx, true_T_idx] row[f"true_ppc_off"] = ppc_off[true_f_idx, true_T_idx] row[f"true_pint_off"] = p_int_off[true_f_idx, true_T_idx] row[f"true_ppc_def"] = ppc_def[true_f_idx, true_T_idx] row[f"true_pint_def"] = p_int_def[true_f_idx, true_T_idx] row[f"true_xyac"] = xyac[true_f_idx, true_T_idx] row[f"true_xepa_comp"] = xepa_comp[true_f_idx, true_T_idx] row[f"true_xepa"] = xepa_comp[ true_f_idx, true_T_idx] if true_pass_completed else xepa_inc row[f"true_trans"] = trans[true_f_idx, true_T_idx] row[f"true_trans_tof"] = h_trans_prob[true_f_idx, true_T_idx] row[f"true_eppa1"] = eppa1[true_f_idx, true_T_idx] # row[f"true_eppa2"] = eppa2[true_f_idx, true_T_idx] row[f"true_eppa1_xval"] = eppa1_pass_val[true_f_idx, true_T_idx] # row[f"true_eppa2_xval"] = eppa2_pass_val[true_f_idx, true_T_idx] row[f"true_eppa1_wo_value"] = eppa1_wo_value[true_f_idx, true_T_idx] # row[f"true_eppa2_wo_value"] = eppa2_wo_value[true_f_idx, true_T_idx] passes_df = pd.DataFrame(row, index=[t]) if viz_df: field_df = pd.DataFrame({ 'frameId': frame_id, 'ball_end_x': field_locs[:, 0], 'ball_end_y': field_locs[:, 1], 'eppa1m': eppa1.max(axis=1), 'eppa1s': eppa1.sum(axis=1), 'eppa1_val': eppa1_pass_val[np.arange(eppa1_pass_val.shape[0]), eppa1.argmax(axis=1)], # 'eppa2': eppa2.max(axis=1), # 'p_int_off_only': p_int_off_only.max(axis=1), 'p_int_off': p_int_off.max(axis=1), # 'p_int_adj_off': np.max(p_int_adj, axis=(1, 2), where=(player_teams=='OFF')), 'ppc_off': ppc_off.max(axis=1), 'ppc_def': ppc_def.max(axis=1), 'eppa1_wo_value': eppa1_wo_value.max(axis=1), # 'eppa2_wo_value': eppa2_wo_value.max(axis=1), 'eppa1_wo_trans': eppa1_pass_val.max(axis=1), # 'eppa2_wo_trans': eppa2_pass_val.max(axis=1), 'xyac': xyac.max(axis=1), 'xepa_comp': xepa_comp.max(axis=1) - xepa_inc, 'xepa_inc': xepa_inc, 'trans': trans.sum(axis=1), }) field_df.loc[field_df.ball_end_x < ball_start[0] - 10, :] = np.nan # remove backward passes # breakpoint() return field_df, passes_df, player_stats_df, proj_df field_dfs = pd.DataFrame() player_stats_df = pd.DataFrame() passes_df = pd.DataFrame() proj_df = pd.DataFrame() if pass_forward_frame < (min_t_frame + ball_snap_frame): return play_df, field_dfs, passes_df, player_stats_df if not simulatePass: for fid in tqdm( range( min_t_frame + ball_snap_frame, min(pass_forward_frame, max_t_frame + ball_snap_frame) + 1)): # for fid in tqdm(range(pass_forward_frame, pass_forward_frame+1)): field_df, passes, player_stats, projs = frame_eppa(fid) field_dfs = field_dfs.append(field_df, ignore_index=True) passes_df = passes_df.append(passes, ignore_index=True) player_stats_df = player_stats_df.append(player_stats, ignore_index=True) proj_df = proj_df.append(projs, ignore_index=True) else: for fid in tqdm(range(sim_frame, sim_frame + 1)): # for fid in tqdm(range(pass_forward_frame, pass_forward_frame+1)): field_df, passes, player_stats, projs = frame_eppa(fid) field_dfs = field_dfs.append(field_df, ignore_index=True) passes_df = passes_df.append(passes, ignore_index=True) player_stats_df = player_stats_df.append(player_stats, ignore_index=True) proj_df = proj_df.append(projs, ignore_index=True) if true_pass_found & viz_true_proj: play_df = pd.merge(play_df, proj_df, on=['frameId', 'nflId'], how='left') if save_all_dfs: week = games_df.loc[games_df.gameId == game_id].week.to_numpy()[0].item() dir = out_dir_path.format(f'{week}/{game_id}/{play_id}') Path(dir).mkdir(parents=True, exist_ok=True) proj_df.to_pickle(f"{dir}/true_pass_player_proj.pkl", ) passes_df.to_pickle(f"{dir}/passes.pkl", ) player_stats_df.to_pickle(f"{dir}/player_stats.pkl", ) field_dfs.to_pickle(f"{dir}/field_viz.pkl", ) return play_df, field_dfs, passes_df, player_stats_df
# params={'parallel_comp': 32}, verbose=True) #.so for ubuntu, .dylib for mac # bst = joblib.load(join(get_repo_dir(), "analysis/models/in/epa_model_rishav_no_time.model")) # xgb.plot_importance(bst) # scores = bst.get_score(importance_type='gain') # print(scores.keys()) # cols_when_model_builds = bst.feature_names # print("ADDED NEW SHIT") # model = treelite.Model.from_xgboost(bst) # toolchain = 'gcc' # model.export_lib(toolchain=toolchain, libpath=join(get_repo_dir(), 'analysis/models/in/epa_no_time_mymodel.so'), # params={'parallel_comp': 32}, verbose=True) #.so for ubuntu, .dylib for mac # file loading and prep path_shared = join(get_repo_dir(), 'data/{}') dt = np.float64 games_df = pd.read_csv(path_shared.format('games.csv')) plays_df = pd.read_csv(path_shared.format('plays.csv')) players_df = pd.read_csv(path_shared.format('players.csv')) pbp_2018 = pd.read_csv(path_shared.format('play_by_play_2018.csv'), low_memory=False) pbp_joined = pd.merge(plays_df, pbp_2018, how="left", left_on=["gameId", "playId"], right_on=["old_game_id", "play_id"]) pbp_joined["retractable"] = np.where(
import os import sys import shutil from utils import get_repo_dir from tqdm import tqdm trans_dir = os.path.join(get_repo_dir(), 'data/transforms') to_delete = [] for hash_dir in tqdm([f for f in os.scandir(trans_dir) if f.is_dir()]): if len(list(os.scandir(hash_dir))) != 200: to_delete.append(hash_dir) if to_delete: if (len(sys.argv) > 1 and sys.argv[1] == 'DELETE' and input( f'Are you sure you want to delete {len(to_delete)} directories? (y/N): ' ).lower() in ['y', 'yes']): for hash_dir in to_delete: print(f'Deleting directory {hash_dir.name}') shutil.rmtree(hash_dir.path) else: print(f'{len(to_delete)} incomplete directories found.') if input('Print? (y/N): ').lower() in ['y', 'yes']: for hash_dir in to_delete: print(hash_dir.name) else: print('No incomplete directories found.')
import pandas as pd from models.play_eppa_gpu import * from pathlib import Path import traceback import os from tqdm import tqdm from utils import get_repo_dir WEEK_START = 1 WEEK_END = 2 out_dir_path = os.path.join(get_repo_dir(), 'output/{}') # for cloud runs path_shared = os.path.join(get_repo_dir(), 'data/{}') # main loop for week in range(WEEK_START, WEEK_END): track_df = pd.read_csv( path_shared.format(f'week{week}_norm.csv', usecols=[ 'nflId', 'displayName', 'position', 'team_pos', 'x', 'y', 'v_x', 'v_y', 'v_mag', 'v_theta', 'a_x', 'a_y', 'a_mag', 'a_theta' ])) plays = sorted( list( set( map( lambda x: (x[0].item(), x[1].item()), track_df.groupby(['gameId', 'playId'], as_index=False).first()[[
# -*- coding: utf-8 -*- import os import numpy as np import pandas as pd pd.options.mode.chained_assignment = None import torch from models.params import params from models.consts import * from models.frame_eppa import frame_eppa, set_device from utils import get_repo_dir from tqdm import tqdm out_dir = os.path.join(get_repo_dir(), 'def_opt_output') os.makedirs(out_dir, exist_ok=True) out_dir_path = os.path.join(out_dir, '{}') # for cloud runs path_shared = os.path.join(get_repo_dir(), 'data/{}') plan_horizon = 0.8 # how far ahead to project (in seconds) while optimizing path plan_res = 0.1 # how long (in seconds) to execute plan. less than plan_horizon frame_dt = 0.1 # how far apart (in seconds) the frames are plan_res_linspace = np.linspace(frame_dt, plan_res, np.round(plan_res / frame_dt).astype(int))[:, None] # 10*dt is the number of frames to increment by res_incr = int(10 * plan_res) horizon_incr = int(10 * plan_horizon) reduce_eppa_mode = 'sum' # choose from {'sum', 'max', 'softmax'} softmax_temp = 1000 # used for 'softmax' reduce_eppa_mode week_game_plays = [