Advertisement
matthewrmata

Release Point Algorithm (Saved Images)

Jun 3rd, 2015
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 17.61 KB | None | 0 0
  1. ###################################
  2. # Release_Point_Combo_HA_Images.r #
  3. ###################################
  4.  
  5. # This program estimates the release point of a pitcher using PITCHf/x data.
  6. # This version will save out similar jpeg's to 'Release_Point_Combo_Home_Away.r'
  7. # rather than display on the console.
  8.  
  9. # Written by Matthew Mata, May 2015 (matthewrmata@gmail.com)
  10.  
  11. #############
  12. # LIBRARIES #
  13. #############
  14.  
  15. # This library calls MySQL
  16. library('RODBC');
  17. library('calibrate');
  18. library('diagram');
  19.  
  20. # Set the working directory and include the spatial clustering algorithm
  21. setwd("R Scripts/Release Point Scripts");
  22. source("inc_k_means_fast.r");
  23.  
  24. #############
  25. # FUNCTIONS #
  26. #############
  27.  
  28. # This function sets the x- and z-coordinates to a distance y
  29. release_dist <- function(Pitch,y){
  30.     # Define the arrays
  31.     x0 <- Pitch$x0;
  32.     y0 <- Pitch$y0;
  33.     z0 <- Pitch$z0;
  34.     vx0 <- Pitch$vx0;
  35.     vy0 <- Pitch$vy0;
  36.     vz0 <- Pitch$vz0;
  37.     ax <- Pitch$ax;
  38.     ay <- Pitch$ay;
  39.     az <- Pitch$az;
  40.     # Loop over the pitches and move the data for each pitch to distance y
  41.     a <- 0.5*ay;
  42.     b <- vy0;
  43.     c <- y0 - y;
  44.     t_rel <- (-b - sqrt(b^2 - 4*a*c))/(2*a);
  45.     x <- 0.5*ax*t_rel^2 + vx0*t_rel + x0;
  46.     z <- 0.5*az*t_rel^2 + vz0*t_rel + z0;
  47.     # Store the new data as a list and return
  48.     RP <- list(x = x, z = z);
  49.     return(RP);
  50. }
  51.  
  52. # This function calculates the location where the cluster is smallest
  53. min_cluster <- function(Pitch,Ind,y_feet,FIRST,LAST,YEAR,CL_No,H_or_A){
  54.     x0 <- Pitch$x0[Ind];
  55.     y0 <- Pitch$y0[Ind];
  56.     z0 <- Pitch$z0[Ind];
  57.     vx0 <- Pitch$vx0[Ind];
  58.     vy0 <- Pitch$vy0[Ind];
  59.     vz0 <- Pitch$vz0[Ind];
  60.     ax <- Pitch$ax[Ind];
  61.     ay <- Pitch$ay[Ind];
  62.     az <- Pitch$az[Ind];
  63.     N_p <- length(x0);
  64.     # Set the number of nodes (45 feet to 65 feet in inches)
  65.     N_y <- 241;
  66.     # Initialize the arrays for storing the data at different distances, sample means and covariances, and areas
  67.     R_x <- array(0,dim=c(N_y,N_p));
  68.     R_y <- array(0,dim=c(N_y,N_p));
  69.     R_z <- array(0,dim=c(N_y,N_p));
  70.     mu <- array(0,dim=c(N_y,2));
  71.     sig <- array(0,dim=c(N_y,2,2));
  72.     mu_temp <- array(0,dim=2);
  73.     sig_temp <- array(0,dim=c(2,2));
  74.     ellipse_area <- array(0,dim=N_y);
  75.     # Set the interval of where the release point will occur
  76.     D_y <- seq(45,65,length=N_y);
  77.     a <- 0.5*ay;
  78.     b <- vy0;
  79.     # Loop over the distances
  80.     for (i in 1:N_y){
  81.         # Set the coefficients for use in the Pythagorean theorem to solve a t^2 + b t + c = (Distance in y) for t
  82.         c <- y0 - D_y[i];
  83.         t <- (-b - sqrt(b^2 - 4*a*c))/(2*a);
  84.         # Evaluate the distance at t
  85.         R_x[i,] <- t(0.5*ax*t^2 + vx0*t + x0);
  86.         R_y[i,] <- t(0.5*ay*t^2 + vy0*t + y0);
  87.         R_z[i,] <- t(0.5*az*t^2 + vz0*t + z0);
  88.         # Compute the sample mean and sample covariance
  89.         mu_temp <- array(0,dim=2);
  90.         sig_temp <- array(0,dim=c(2,2));
  91.         mu_temp[1] <- sum(R_x[i,])/N_p;
  92.         mu_temp[2] <- sum(R_z[i,])/N_p;
  93.         sig_temp[1,1] <- sum((R_x[i,] - mu_temp[1])^2);
  94.         sig_temp[1,2] <- sum((R_x[i,] - mu_temp[1])*(R_z[i,] - mu_temp[2]));
  95.         sig_temp[2,1] <- sig_temp[1,2];
  96.         sig_temp[2,2] <- sum((R_z[i,] - mu_temp[2])^2);
  97.         sig_temp <- sig_temp/(N_p-1);
  98.         mu[i,] <- mu_temp;
  99.         sig[i,,] <- sig_temp;
  100.         # Compute the eigenvalues and eigenvectors of the covariance matrix
  101.         ellipse <- eigen(sig[i,,]);
  102.         evalues <- ellipse$values;
  103.         evectors <- ellipse$vectors;
  104.         # Determine two standard deviations along the axes
  105.         ellipse_axes <- 2*sqrt(evalues);
  106.         # Compute the area of the ellipse
  107.         ellipse_area[i] <- pi*ellipse_axes[1]*ellipse_axes[2];
  108.     }
  109.     # Find the index corresponding to the smallest area
  110.     RP_index <- which(ellipse_area == min(ellipse_area));
  111.     # Set up the data for ellipse plotting
  112.     s <- seq(0,2*pi,length=200);
  113.     x_par <- cos(s);
  114.     y_par <- sin(s);
  115.     # Find the minimum ellipse
  116.     ellipse <- eigen(sig[RP_index,,]);
  117.     # Determine the values for plotting the ellipse
  118.     evalues <- ellipse$values;
  119.     evectors <- ellipse$vectors;
  120.     ellipse_axes <- 2*sqrt(evalues);
  121.     x_ellipse <- ellipse_axes[1]*x_par;
  122.     y_ellipse <- ellipse_axes[2]*y_par;
  123.     ellipse_matrix <- rbind(x_ellipse,y_ellipse);
  124.     ellipse_coord <- evectors%*%ellipse_matrix + mu[RP_index,];
  125.     # Set bounds for the plot
  126.     min_x <- min(R_x[RP_index,])-0.15;
  127.     max_x <- max(R_x[RP_index,])+0.15;
  128.     min_y <- min(R_z[RP_index,])-0.15;
  129.     max_y <- max(R_z[RP_index,])+0.15;
  130.     # Compute the release angle
  131.     angle <- release_angle(ellipse);
  132.     # Set the index for where the clustering occurs
  133.     cluster_ind <- round(12*(y_feet-45) + 1,digits=0);
  134.     # Determine the release point
  135.     R_Point <- round(D_y[RP_index],digits=3);
  136.     R_Point_h <- round(mu[RP_index,1],digits=3);
  137.     R_Point_v <- round(mu[RP_index,2],digits=3);
  138.     if (CL_No == 0){ Cluster_Name <- ''; } else { Cluster_Name <- paste(", Cl. #",CL_No,"",sep=""); }
  139.     filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_RPF_",CL_No,".jpg",sep="");
  140.     jpeg(filename);
  141.     # Plot the functional for the area of the ellipses
  142.     plot(D_y,ellipse_area,type='n',xlab='Distance From Back of Home Plate (Feet)',ylab='Two Standard Deviation Ellipse Area (Square Feet)',
  143.          main = paste("Release Point Functional for ",FIRST," ",LAST," 20",YEAR," ",H_or_A,Cluster_Name,"",sep=""),xaxs='i',yaxs='i');
  144.     par(new=TRUE);
  145.     lines(D_y,ellipse_area);
  146.     par(new=FALSE);
  147.     dev.off();
  148.     filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_CL_Dist_",CL_No,".jpg",sep="");
  149.     jpeg(filename);
  150.     # Plot the clustered data at the distance it was clustered
  151.     plot(R_x[cluster_ind,],R_z[cluster_ind,],col="blue",pch=20,xlim=c(min_x,max_x),ylim=c(min_y,max_y),xlab='Horizontal Location (Feet)',
  152.          ylab='Vertical Location (Feet)', main = paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", Pitches at ",y_feet," Ft",Cluster_Name,"",sep=""),xaxs='i',yaxs='i');
  153.     dev.off();
  154.     filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_RP_",CL_No,".jpg",sep="");
  155.     jpeg(filename);
  156.     # Plot the cluster at the estimated release point
  157.     plot(R_x[RP_index,],R_z[RP_index,],col="blue",pch=20,xlim=c(min_x,max_x),ylim=c(min_y,max_y),xlab='Horizontal Location (Feet)',
  158.          ylab='Vertical Location (Feet)', main = paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", Est. Release Point, ",R_Point," Ft",Cluster_Name,"",sep=""),xaxs='i',yaxs='i');
  159.     par(new=TRUE);
  160.     lines(ellipse_coord[1,],ellipse_coord[2,],col='black',xlim=c(min_x,max_x),ylim=c(min_y,max_y),xlab='',ylab='',lwd=2);
  161.     par(new=FALSE);
  162.     dev.off();
  163.     # Return the release point and angle as a list
  164.     RP_data <- list( RP_x = R_Point_h, RP_y = R_Point, RP_z = R_Point_v, RP_a = angle, RP_area = ellipse_area[RP_index] );
  165.     return(RP_data);
  166. }
  167.  
  168. # This function determines the release angle
  169. release_angle <- function(E){
  170.     # Calculate the eigenvalues and eigenvectors
  171.     evals <- E$values;
  172.     evecs <- E$vectors;
  173.     # Choose the smaller of the two eigenvalues and use the geometric definition of the dot product to compute the angle from horizontal
  174.     # This means dotting the corresponding eigenvalue with (1,0), taking the absolute value, and computing the arccosine.
  175.     if (evals[1] < evals[2]){
  176.         angle <- acos(abs(evecs[1,1]));
  177.     }
  178.     else{
  179.         angle <- acos(abs(evecs[1,2]));
  180.     }
  181.     # Return the angle
  182.     angle <- round((180/pi)*angle,digits=3);
  183.     return(angle);
  184. }
  185.  
  186. # This function determines the indices of the data that has a 'pct' percent chance or better
  187. # of belonging to the primary (largest) cluster.
  188.  
  189. Largest_Cluster <- function(K,pct){
  190.     # Determine the primary cluster
  191.     Primary <- which(K$w == max(K$w));
  192.     # Find the points with 5% or better probability of being from the primary cluster
  193.     Lrg <- which(K$C[Primary,] >= pct);
  194.     return(Lrg);
  195. }
  196.  
  197. ########
  198. # MAIN #
  199. ########
  200.  
  201. # Set the player name (PARAMETER)
  202. FIRST <- 'Stephen';
  203. LAST <- 'Strasburg';
  204. YEAR <- 14;
  205.  
  206. DB <- paste("MLB20",YEAR,sep="");
  207.  
  208. # Set the release distance for clustering (PARAMETER)
  209. y_feet <- 55;
  210.  
  211. # Number of points to average over for the rolling average (PARAMETER)
  212. S <- 75;
  213.  
  214. # Set the distance in feet for a change in release location (PARAMETER)
  215. marker <- 0.75;
  216.  
  217. # Set the maximal number of spatial clusters (PARAMETER)
  218. k_max <- 10;
  219.  
  220. # Set HA to "1" for Home and "2" for Away data
  221. HA <- 1;
  222.  
  223. if (HA == 1) {H_or_A <- '(H)'} else {H_or_A <- '(A)'};
  224.  
  225. print(paste("Pitcher: ",FIRST," ",LAST,", 20",YEAR," " ,H_or_A,"",sep=""));
  226.  
  227. # Set the channel (Database is MLB2014)
  228. channel <- odbcConnect(DB);
  229.  
  230. # Set the query to get the PITCHf/x data and exclude any missing entries (by finding entries missing the px value)
  231. # Also exclude intentional balls
  232. Release_Query <- paste("SELECT x0, y0, z0, vx0, vy0, vz0, ax, ay, az FROM pitches WHERE
  233.                       ab_id IN (SELECT ab_id FROM atbats WHERE
  234.                        pitcher = (SELECT eliasid FROM players WHERE first = '",
  235.                        FIRST,"' AND last = '",LAST,"') AND half = ",HA,") AND
  236.                        pitch_type <> 'IN' AND px IS NOT NULL",sep="");
  237.  
  238. # Download the pitch data
  239. Release <- sqlQuery(channel,Release_Query);
  240.  
  241. # Close the channel
  242. close(channel);
  243.  
  244. # Move the data to y_feet and assign the values of x and z to arrays
  245. RP <- release_dist(Release,y_feet);
  246. x_rel <- RP$x;
  247. z_rel <- RP$z;
  248. N_p <- length(x_rel);
  249.  
  250. # Set bounds for plotting
  251. x_rel_min <- min(x_rel) - 0.05;
  252. x_rel_max <- max(x_rel) + 0.05;
  253. z_rel_min <- min(z_rel) - 0.05;
  254. z_rel_max <- max(z_rel) + 0.05;
  255.  
  256. # Plot unclustered data
  257. filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_Data.jpg",sep="");
  258. jpeg(filename);
  259. plot(x_rel,z_rel,col="blue",pch=20,xlim=c(x_rel_min,x_rel_max),ylim=c(z_rel_min,z_rel_max),xlab='Horizontal Location (Feet)',
  260.          ylab='Vertical Location (Feet)', main = paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", All Pitches at 55 Ft",sep=""),xaxs='i',yaxs='i');
  261. dev.off();
  262.          
  263. # Arrays for storing the rolling averages (referred to in the code as "Snake")
  264. Snake_x <- array(0,dim=(N_p-S+1));
  265. Snake_z <- array(0,dim=(N_p-S+1));
  266.  
  267. # Compute the rolling averages
  268. for (i in 1:(N_p-S+1)){
  269.     Snake_x[i] <- mean(x_rel[c(i:(S-1+i))]);
  270.     Snake_z[i] <- mean(z_rel[c(i:(S-1+i))]);
  271. }
  272.  
  273. # Calculate the line integral or length of the snake
  274. line_int <- 0;
  275. for (i in 1:(N_p-S)){
  276.     line_int <- line_int + sqrt((Snake_x[i+1]-Snake_x[i])^2 + (Snake_z[i+1]-Snake_z[i])^2);
  277. }
  278.  
  279. # Print the length of the line
  280. print(paste("Length of Line: ",round(line_int,digits=3),sep=""));
  281.  
  282. # Initialize an array for storing the distance between points in the rolling average
  283. sep_dist <- array(0,dim=(N_p-2*S+1));
  284.  
  285. # Calculate the distance between disjoint, adjacent rolling averages
  286. for (i in 1:(N_p-2*S+1)){
  287.         sep_dist[i] <- sqrt((Snake_x[i] - Snake_x[i+S])^2 + (Snake_z[i] - Snake_z[i+S])^2) - marker;
  288. }
  289.  
  290. # Initialize the number for counting the location changes
  291. peak_count <- 0;
  292.  
  293. # Count the number of peaks as the number of times the distance exceeds the 'marker' for a change
  294. for (i in 1:(N_p-2*S)){
  295.     if ( sep_dist[i] < 0 && sep_dist[i+1] > 0 ){
  296.         peak_count <- peak_count + 1;
  297.     }
  298. }
  299.  
  300. # Find the location of the maximum distance of the separations
  301. if ( peak_count != 0){
  302.     loc_change <- array(0,dim=peak_count);
  303.     k <- 1;
  304.     max_dist <- 0;
  305.     for (i in 1:(N_p-2*S+1)){
  306.         if ( sep_dist[i] > max_dist ){
  307.             loc_change[k] <- i + floor(S/2);
  308.             max_dist <- sep_dist[i];
  309.         }
  310.         if ( sep_dist[i] > 0 && sep_dist[i+1] < 0 ){
  311.             k <- k + 1;
  312.             max_dist <- 0;
  313.         }
  314.     }
  315. }
  316.  
  317. # Find bounds for the plot
  318. x_min <- min(Snake_x) - 0.05;
  319. x_max <- max(Snake_x) + 0.05;
  320. z_min <- min(Snake_z) - 0.05;
  321. z_max <- max(Snake_z) + 0.05;
  322.  
  323. # Correct for grammar
  324. if (peak_count == 1) move_des = 'Move' else move_des = 'Moves';
  325.  
  326. # If there is a change (peak count is not zero), output the location where the change occurs
  327. if (peak_count != 0){
  328.     peak_loc <- array(0,dim=peak_count);
  329.     peak_output <- "Move(s) at Pitch(es): ";
  330.     for (i in 1:peak_count){
  331.         peak_loc[i] <- loc_change[i] + ceiling(S/2);
  332.         peak_output <- paste(peak_output,(loc_change[i] + ceiling(S/2)),sep="");
  333.         if (i < peak_count){
  334.             peak_output <- paste(peak_output,", ",sep="");
  335.         }
  336.     }
  337.     print(peak_output);
  338. }
  339.  
  340. # Plot the snakes, starting point (green), ending point (red), and changes (blue)
  341. filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_Snake_",peak_count,".jpg",sep="");
  342. jpeg(filename);
  343. plot(Snake_x,Snake_z,type='n',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='Horizontal Location (Feet)',
  344.      ylab='Vertical Location (Feet)',main=paste("",FIRST," ",LAST," 20",YEAR," ",H_or_A," at ",y_feet," Ft, ",S,"-Pitch Average, ",peak_count," ",move_des,"",sep=""),xaxs='i',yaxs='i');
  345. par(new=TRUE);
  346. lines(Snake_x,Snake_z,col='black',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='');
  347. par(new=TRUE);
  348. plot(Snake_x[1],Snake_z[1],col='green',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  349. par(new=TRUE);
  350. plot(Snake_x[N_p-S+1],Snake_z[N_p-S+1],col='red',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  351. if (peak_count != 0){
  352.     for (i in 1:peak_count){
  353.         par(new=TRUE);
  354.         plot(Snake_x[loc_change[i]],Snake_z[loc_change[i]],col='blue',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  355.     }
  356. }
  357. par(new=FALSE);
  358. dev.off();
  359.  
  360. # Set up parameters for plotting with more than one release point location
  361. if (peak_count != 0){
  362.     # The number of pitches in each cluster
  363.     pitch_subcount <- array(0,dim=(peak_count+1));
  364.     # The breaks between clusters
  365.     peak_loc <- c(1,peak_loc,N_p+1);
  366.     # Fill in the sub-count
  367.     for (i in 1:(peak_count+1)){
  368.         pitch_subcount[i] <- peak_loc[i+1] - peak_loc[i];
  369.     }
  370.     # Set up the colours for plotting the clusters (more colours can be added if needed)
  371.     color_wheel <- c('red', 'blue', 'green', 'orange', 'black', 'purple', 'brown', 'pink', 'gray', 'goldenrod');
  372. }
  373.  
  374. # Check if more than one cluster
  375. if (peak_count != 0){
  376.     filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_Snakes_",peak_count,".jpg",sep="");
  377.     jpeg(filename);
  378.     plot(Snake_x,Snake_z,type='n',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='Horizontal Location (Feet)',
  379.          ylab='Vertical Location (Feet)',main=paste("",FIRST," ",LAST," 20",YEAR," ",H_or_A," at ",y_feet," Ft, ",S,"-Pitch Average, ",peak_count," ",move_des,"",sep=""),xaxs='i',yaxs='i');
  380.     # The breaks between clusters
  381.     for (i in 1:(peak_count+1)){
  382.         par(new=TRUE);
  383.         num_elem <- max(peak_loc[i+1] - peak_loc[i] - S,1);
  384.         Snake_x_temp <- array(0,dim=num_elem);
  385.         Snake_z_temp <- array(0,dim=num_elem);
  386.         avg_size <- min((S-1),(peak_loc[i+1] - peak_loc[i] - 1));
  387.         for (j in peak_loc[i]:(peak_loc[i] + num_elem - 1)){
  388.             Snake_x_temp[j-peak_loc[i]+1] <- mean(x_rel[c(j:(avg_size+j))]);
  389.             Snake_z_temp[j-peak_loc[i]+1] <- mean(z_rel[c(j:(avg_size+j))]);
  390.         }
  391.         lines(Snake_x_temp,Snake_z_temp,col=color_wheel[i],xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='');
  392.         par(new=TRUE);
  393.         plot(Snake_x_temp[1],Snake_z_temp[1],col='green',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  394.         par(new=TRUE);
  395.         plot(Snake_x_temp[num_elem],Snake_z_temp[num_elem],col='red',xlim=c(x_min,x_max),ylim=c(z_min,z_max),xlab='',ylab='',pch=15,xaxs='i',yaxs='i');
  396.         par(new=TRUE);
  397.         textxy(Snake_x_temp[1],Snake_z_temp[1],toString(i),col='black',cex=1,offset=1,m=c(x_min,z_min),lwd=2);
  398.         par(new=TRUE);
  399.         textxy(Snake_x_temp[num_elem],Snake_z_temp[num_elem],toString(i),col='black',cex=1,offset=1,m=c(x_min,z_min),lwd=2);
  400.     }
  401.     par(new=FALSE);
  402.     dev.off();
  403. }
  404.  
  405. # If the number of peaks is not zero, process each cluster to find the release point
  406. pk_ctr <- 0;
  407. if (peak_count != 0){
  408.     pk_ctr <- pk_ctr + 1;
  409.     filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_CL_",pk_ctr,".jpg",sep="");
  410.     jpeg(filename);
  411.     # Plot the clusters
  412.     for(i in 1:(peak_count+1)){
  413.         plot(x_rel[c(peak_loc[i]:(peak_loc[i+1]-1))],z_rel[c(peak_loc[i]:(peak_loc[i+1]-1))],col=color_wheel[i],
  414.              xlim=c(x_rel_min,x_rel_max),ylim=c(z_rel_min,z_rel_max),pch=20,xlab = '', ylab='',xaxs='i',yaxs='i');
  415.              par(new=TRUE);
  416.     }
  417.     title(main=paste(FIRST," ",LAST," 20",YEAR," ",H_or_A,", Pitches at ",y_feet," Ft, ",peak_count+1," Temporal Clusters",sep=""),xlab = 'Horizontal Location (Feet)',
  418.           ylab = 'Vertical Location (Feet)');
  419.     par(new=FALSE);
  420.     dev.off();
  421.     # Compute results for all clusters
  422.     for (i in 1:(peak_count+1)){
  423.         # Set the indices for the points in the cluster
  424.         C_Ind <- c(peak_loc[i]:(peak_loc[i+1]-1));
  425.         RP_C <- list(x=RP$x[C_Ind],z=RP$z[C_Ind]);
  426.         # Cluster the data to remove any outliers/extra clusters
  427.         K <- inc_k_means_fast(RP_C,10^(-4),500,k_max);
  428.         # Get the indices related to the largest cluster
  429.         L_Ind <- Largest_Cluster(K,0.05);
  430.         Release_C <- list( x0=Release$x0[C_Ind], y0=Release$y0[C_Ind], z0=Release$z0[C_Ind],
  431.                            vx0=Release$vx0[C_Ind], vy0=Release$vy0[C_Ind], vz0=Release$vz0[C_Ind],
  432.                            ax=Release$ax[C_Ind], ay=Release$ay[C_Ind], az=Release$az[C_Ind]);
  433.         # Plot the clusters and output the results to the console
  434.         CL_No <- i;
  435.         T_loc <- min_cluster(Release_C,L_Ind,y_feet,FIRST,LAST,YEAR,CL_No,H_or_A);
  436.         print(paste("Cluster #",i," Percentage: ",length(L_Ind),"/",length(C_Ind)," = ",round(100*length(L_Ind)/length(C_Ind),digits=1),"%",sep=""));
  437.         print(paste("Cluster #",i," Distance: (",T_loc$RP_x,", ",T_loc$RP_y,", ",T_loc$RP_z,")",sep=""));
  438.         print(paste("Cluster #",i," Angle: ",T_loc$RP_a,sep=""));
  439.         print(paste("Cluster #",i," Area: ",round(T_loc$RP_area,digits=3),sep=""));
  440.     }
  441. }
  442.  
  443. # Compute the results for a single cluster
  444. if(peak_count == 0){
  445.     # Cluster the data to remove any outliers/extra clusters
  446.     K <- inc_k_means_fast(RP,10^(-4),500,k_max);
  447.     # Get the indices related to the largest cluster
  448.     L_Ind <- Largest_Cluster(K,0.05);
  449.     CL_No <- 0;
  450.     T_loc <- min_cluster(Release,L_Ind,y_feet,FIRST,LAST,YEAR,CL_No,H_or_A);
  451.     print(paste("Cluster Percentage: ",length(L_Ind),"/",N_p," = ",round(100*length(L_Ind)/N_p,digits=1),"%",sep=""));
  452.     print(paste("Cluster Distance: (",T_loc$RP_x,", ",T_loc$RP_y,", ",T_loc$RP_z,")",sep=""));
  453.     print(paste("Cluster Angle: ",T_loc$RP_a,sep=""));
  454.     print(paste("Cluster Area: ",round(T_loc$RP_area,digits=3),sep=""));
  455. }
  456.  
  457.  
  458. ###################
  459. # RESET DIRECTORY #
  460. ###################
  461.  
  462. setwd("~");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement