# FlockingSimulatorDivergence2.py 
# Run as FlockingSimulatorDivergence2.py filename

# This Program is very similiar to the program FlockingSimulator2.py except that it in addition to the 
# original flock with randomly generated intial positions and velocities it also creates a copy flock
# where the positions and/or velocities of some of the birds have been slightly perturbed. It then 
# simulates the movement of these two flocks for some number of timesteps and writes the data to two
# data files (filename and filenamecopy) for later analysis. (No Obstacles are used)

# Parameters:

# (1) gridsize = the size of the grid to run simulation on, a rectangle gridsize x gridsize
# (2) num_steps = the number of timesteps to simulate for
# (3) timestep = the size of each timestep 
# (4) N = total number of birds in the flock
# (5) MA = birds maximum acceleration
# (6) MV = birds maximum velocity
# (7) sightrange = the birds sightrange
# (8) dmin = the minimum distance an object can be from a bird, before the bird treats it as an obstacle to avoid
# (9) num_modify the number of birds which we should modify the positions/velocities of
# (10) max_postition_difference the maximum possible position modification of a given bird
# (11) max_velocity_difference the maximum possible velocity modification of a given bird

# determine filename
import sys
filename = sys.argv[1]
filenamecopy = filename + 'copy'

# import modules
from Scientific.Geometry import *
from numpy import *
from numpy.random import *
from FlockingClassDefinitions import *
from FlockingUpdateRules2 import *


# define parameters
gridsize = 100          #(integer)
num_steps = 10000       #(integer)
timestep = 0.1          #(float)
N = 20                  #(integer)
MA = 0.125              #(float)
MV = 0.5                #(float)
sightrange = 10.0       #(float)
dmin = 3.0              #(float)
num_modify = 1
max_position_difference = 1.0 
max_velocity_difference = 0.1

# There are no Obstacles
Obstacles = [] 

# Step (I) - Generate a reference Flock, and a modified flock with a slightly perturbed intial condition
ListOfBirds = []
ListOfBirdsCopy = []

# Create Birds with randomly assigned positions and velocities on the grid
for n in xrange(N):
    position_displacement = array([0.0,0.0])
    velocity_displacement = array([0.0,0.0]) 

    label = 'b' + `n`
    labelcopy = 'c' + `n`

    p_current = uniform(0.0,gridsize*1.0,(1,2))
    if n < num_modify:
       position_displacement = uniform(-max_position_difference,max_position_difference,(1,2)) # Modify here
    p_current_copy = p_current + position_displacement
 
    p_current = Vector(p_current[0][0],p_current[0][1],0.0)
    p_current_copy = Vector(p_current_copy[0][0],p_current_copy[0][1],0.0)   
    
    v_current = uniform(0.0,MV/2**0.5,(1,2))
    if n < num_modify:
        velocity_displacement = uniform(-max_velocity_difference,max_velocity_difference,(1,2)) # Modify here
    v_current_copy = v_current + velocity_displacement   
 
    v_current = Vector(v_current[0][0],v_current[0][1],0.0)
    v_current_copy = Vector(v_current_copy[0][0],v_current_copy[0][1],0.0)
 
    p_last = p_current - v_current*timestep
    p_last_copy = p_current_copy - v_current_copy*timestep

    bird = Bird(label,MV,MA,sightrange,p_current,p_last,v_current,[])
    bird_copy = Bird(label,MV,MA,sightrange,p_current_copy,p_last_copy,v_current_copy,[])

    ListOfBirds.append(bird)
    ListOfBirdsCopy.append(bird_copy)
   
# Create the flocks 
dummyflock = Flock('dummyflock',ListOfBirds,Vector(0.0,0.0,0.0),Vector(0.0,0.0,0.0),Vector(0.0,0.0,0.0))
dummyflockcopy = Flock('dummyflockcopy',ListOfBirdsCopy,Vector(0.0,0.0,0.0),Vector(0.0,0.0,0.0),Vector(0.0,0.0,0.0))

# Find initial neighbors

for n in xrange(N):
    FindNeighbors(n,dummyflock)

for n in xrange(N):
    FindNeighbors(n,dummyflockcopy)



# Step (II) - run the simulation for the initial flock

# open the file to write to 
file = open(filename,'w')

# write the initial data

# x data on one line
for n in xrange(N):
    file.write(`dummyflock.ListOfBirds[n].p_current[0]` + ' ')
file.write('\n')

# y data on another
for n in xrange(N):
    file.write(`dummyflock.ListOfBirds[n].p_current[1]` + ' ')
file.write('\n')

# run the simulation and write data at each time step
for step in xrange(num_steps):
    FlockStep(dummyflock,timestep,dmin,gridsize,Obstacles)  

    # x data on one line 
    for n in xrange(N):
        file.write(`dummyflock.ListOfBirds[n].p_current[0]` + ' ')
    file.write('\n')

    # y data on the next
    for n in xrange(N):
        file.write(`dummyflock.ListOfBirds[n].p_current[1]` + ' ')
    file.write('\n')

file.close()



# Step (III) - run the simulation for the modified flock

# open the file to write to 
file = open(filenamecopy,'w')

# write the initial data

# x data on one line
for n in xrange(N):
    file.write(`dummyflockcopy.ListOfBirds[n].p_current[0]` + ' ')
file.write('\n')

# y data on another
for n in xrange(N):
    file.write(`dummyflockcopy.ListOfBirds[n].p_current[1]` + ' ')
file.write('\n')

# run the simulation and write data at each time step
for step in xrange(num_steps):
    FlockStep(dummyflockcopy,timestep,dmin,gridsize,Obstacles)  

    # x data on one line 
    for n in xrange(N):
        file.write(`dummyflockcopy.ListOfBirds[n].p_current[0]` + ' ')
    file.write('\n')

    # y data on the next
    for n in xrange(N):
        file.write(`dummyflockcopy.ListOfBirds[n].p_current[1]` + ' ')
    file.write('\n')

file.close()




