Chertman.py

From GeoMod

Jump to: navigation, search

To run the code, once you have VPython installed, you can either.

  1. Download this file: chert_man_24-rm.py
  2. or, copy and paste the following code to a file (named "chert_man_24-rm.py" for example) using your favorite text editor.

Other necessary files:

'''
Chertman the model
Designed by
    Dr. Lensyl Urbano
    Dr. Stephen Cole
    Department of Earth Sciences
    University of Memphis
    Published on web 2005
    Free for non-commercial use
    Help and support: Look us up at the University of Memphis website
'''
from visual import *

from random import *

from string import *

from visual.graph import * # import graphing features

from datetime import *

from Numeric import *

from Scientific.Statistics import *

#from Scientific.Geometry import Vector

from sys import *

import os

from os.path import basename

from raster_map import *







class outcrop:

    def __init__(self, id, x, y, l_draw = 0, crange = 100.0, col = vector(1,0,1), z = 0.0,

                 Azero = 0.0, halflife = 9999.0):

        self.x = float(x)

        self.y = float(y)

        self.id = id

        self.Azero = Azero          #Depth of exponential attractor function (A0)(see exponential_attractors.xls)

        self.halflife = halflife    #Half life of exponential attractor function (tau) (see exponential_attractors.xls)

        if l_draw == 1:

            #print type(self.x), type(self.y), type(z), type(crange), type(col)

            self.ball = sphere(pos=(self.x, self.y, z), radius=crange, color=col)

    def elevate(self, raster_map, z_scale = 1.0): #set the x value for the outcrop position based on a dem

        self.ball.pos.z = raster_map.get_val(self.ball.pos) * z_scale

        

def elevate(pos, raster_map, z_scale = 1.0): #set the x value for the outcrop position based on a dem

    pos.z = raster_map.get_val(pos) * z_scale

    return pos



class stream:

    def __init__(self, name):

        self.x = []     #list of x locations along line

        self.y = []     #list of y locations along line

        self.z = []     #list of y locations along line

        self.size = []  #stream size

        self.name = name    #name of stream

    def cross(self):    #this method will determine which stream reaches are crossable or not

        self.crossable = equal(self.size, 1)  # a value of 1 means NOT CROSSABLE

    def elevate(self, raster_map, z_scale = 1.0):

        #print "self.x = ", self.x

        for i in range(len(self.x)):

            self.z[i] = raster_map.get_val(vector(self.x[i], self.y[i], 0.0)) * z_scale



##        print "stream = ", self.name

##        print "crossable = ", self.crossable









class hit_counter:

    def __init__(self, id):

        self.id = id

        self.ct = 0             #number of times outcrop type has been encountered

        self.mass = 0.0         #mass of outcrop-type material in bag

        self.avmass = 0.0       #average mass of material in bag after walk

        self.stmass = []        #record of mass at the end of every walk

        self.stdev = 0.0        #standard deviation of masses at end of walks

        self.min = 0.0          #minimum of masses at end of walks

        self.max = 0.0          #maximum of masses at end of walks

        self.median = 0.0       #median of masses at end of walks

        self.skew = 0.0         #skewness of masses at end of walks

        self.atr_rate = 0.0     #attrition rate of type of material

        self.prob_pickup = 1.0  #probability of picking up this type of material





class attractor:

    def __init__(self, id, Azero = 0.0, halflife = 99999.0, isactive = 1.0):

        self.id = id

        self.Azero = Azero

        self.halflife = halflife

        self.isactive = isactive

        

class cherttype:

    def __init__(self, id, Azero = 0.0, halflife = 9999999.0, attractive = 0.0, atr_rate = 0.0,

                 prob_pickup = 1.0):

        self.id = id

        self.Azero = Azero

        self.halflife = halflife

        self.attractive = attractive  #if attractors are active is active

        self.atr_rate = atr_rate

        self.prob_pickup = prob_pickup

        self.x = []     #array giving the x, y and z coordinates of each outcrop in type

        self.y = []

        self.z = []

    def makearrays(self):

        self.x = array(self.x)

        self.y = array(self.y)

        self.z = array(self.z)

        

        

        

def take_step(nhits,ndirs,step_size,oray,hit_ct,outcrops,load_add, max_load, total_mass):

    #Take step

    #print "newpos = ", newpos



    #print newpos[0], newpos[1], newpos[2]

    dx = newpos[0] - oray[:,1]

    dy = newpos[1] - oray[:,2]

    rad = sqrt(dx * dx + dy * dy) #calculates the distance to each point (outcrop)

    ##print rad

    rad_intercept = less_equal(rad, rng)  #determine if the distance to any point is less than the range of influence (rng)

    rad_list = rad_intercept.tolist()

    #print rad_intercept



    hitlist = sort(nonzero(rad_intercept.flat)).tolist() # i,j encoded as i*Natoms+j

    #print "hitlist, len(hitlist) = ", hitlist, len(hitlist)

    nhits = nhits + len(hitlist)





    # determine the id of outcrops encountered

    if len(hitlist) > 0:

        #print 'initial hitlist = ', hitlist

        # calculate if material is picked up given the probability of pickup (prob_pickup)

        newhitlist = []

        for j in hitlist:

            for k in hit_ct:

                if outcrops[j].id == k.id:

                    if random() <= k.prob_pickup: #then pickup

                        newhitlist.append(j)

        hitlist = newhitlist                  

        #print 'new hitlist     = ', hitlist

    if len(hitlist) > 0:

        # If multiple sites are selected with each step then add the same amount for each site picked

        # If the available space in the bag is smaller than the total going in then divide equally

##        print "hitlist = ", hitlist

##        print "takestep total_mass = ", total_mass

        bag_space = max_load - total_mass

##        print "bag_space = ", bag_space

##        print "bag_space/float(len(hitlist)) = ", bag_space/float(len(hitlist))

    

        mass_to_add = min(load_add, bag_space/float(len(hitlist)) )

        total_mass = total_mass + mass_to_add * float(len(hitlist))

##        print "total_mass = ", total_mass, "mass_to_add = ", mass_to_add, "len(hitlist) = ", len(hitlist)

        for j in hitlist:  #for each outcrop encountered in this step

            #print "hit index (j) = ", j

            #figure out what type of outcrop it was

            for k in hit_ct:

                if outcrops[j].id == k.id: 

                    #print "add to type ", k[0]

                    k.ct += 1

                    #add to rock bag

                    k.mass += mass_to_add





def step_dir(ndirs, bdir=vector(0,1,0), biasf=0.0):

    """Determine the direction in which to step

       Returns a vector with magnitude of 1.0

       bdir = direction of any bias

       bias = amount of bias - between 0.0 and 1.0

       ndirs = number of possible directions of motion"""

    adir = vector(0,1,0)

    tmp_dirs = int(ndirs * (1.0 - biasf))

    d = float(randint(1-(tmp_dirs)/2,tmp_dirs/2))

#    print "bdir a = ", bdir

    if bdir <> adir:

        #ang = 

        ang = vector(bdir.x,bdir.y,bdir.z).diff_angle(vector(adir.x, adir.y, adir.z))

#        print "ang (degrees)    =", ang, ang * 360.0 / 2.0 / pi

        newdir = round(ang*ndirs/(2.*pi))

#        print "newdir =", ang*ndirs/(2.*pi), "=", newdir

        if (adir.x * bdir.y - adir.y * bdir.x) < 0:

            bdir = rotate(adir,angle=-(newdir*2.0*pi/float(ndirs)))

        else:

            bdir = rotate(adir,angle=(newdir*2.0*pi/float(ndirs)))

#    print "bdir b = ", bdir

    dp = rotate(bdir,angle=d*2.0*pi/float(ndirs))    

#    if bdir <> adir:

#        print "tmp_dirs, d, dp, tmp = ", tmp_dirs, d, dp , ang

    return dp



def tri_area(x1, y1, x2, y2, x3, y3):

    """calculate the area of a triangle"""

    return x1*y2 - y1*x2 + y1*x3 - x1*y3 + x2*y3 - x3*y2





def stream_crossing(stream_perm,oldpos,newpos,streams,step_size):

    """returns 1 if stream is crossed and move not allowed and 0 otherwise"""

    l_cross = 0

    

##    triangle1 = curve(color=(1,0,0))

##    triangle1.append(pos=vector(oldpos.x,oldpos.y,0))

##    triangle1.append(pos=vector(oldpos.x,oldpos.y,0))

##    triangle1.append(pos=vector(oldpos.x,oldpos.y,0))

##    triangle1.append(pos=vector(oldpos.x,oldpos.y,0))

##    triangle2 = curve(color=(1,0,0))

##    triangle2.append(pos=vector(oldpos.x,oldpos.y,0))

##    triangle2.append(pos=vector(oldpos.x,oldpos.y,0))

##    triangle2.append(pos=vector(oldpos.x,oldpos.y,0))

##    triangle2.append(pos=vector(oldpos.x,oldpos.y,0))

    

    if stream_perm < 1.0:

        #locate streams close by

        #print newpos[0], newpos[1], newpos[2]

        for j in streams:

            dx = newpos[0] - j.x

            dy = newpos[1] - j.y

            rad = sqrt(dx * dx + dy * dy) #calculates the distance to each point (outcrop)

            ##print rad

            rad_intercept = less_equal(rad, step_size)  #determine if the distance to any point is less than the range of influence (rng)

            #rad_list = rad_intercept.tolist()

            rad_intercept = rad_intercept * j.crossable #determine if stream is crossable at all

            #print rad_intercept



            hitlist = sort(nonzero(rad_intercept.flat)).tolist() 

            for k in hitlist:

                x1, y1 = (oldpos.x, oldpos.y)

                x2, y2 = (newpos.x, newpos.y)

                #look forward along stream

                if k < (len(j.x)-1):

                    x3, y3 = (j.x[k], j.y[k])

                    x4, y4 = (j.x[k+1], j.y[k+1])

                    tri1 = tri_area(x1,y1, x2,y2, x3,y3)

                    tri2 = tri_area(x1,y1, x2,y2, x4,y4)



##                    triangle1.pos[1] = vector(newpos.x,newpos.y,0)

##                    triangle1.pos[2] = vector(x3,y3,0)

                    

                    if tri1/tri2 <= 0.0:

                        l_cross = 1

                        break

                #look backward along stream

                if k > 0:

                    x3, y3 = (j.x[k-1], j.y[k-1])

                    x4, y4 = (j.x[k], j.y[k])

                    tri1 = tri_area(x1,y1, x2,y2, x3,y3)

                    tri2 = tri_area(x1,y1, x2,y2, x4,y4)

                                     

                    if tri1/tri2 <= 0.0:

                        l_cross = 1

                        break

            if l_cross == 1:

                break

            

    if l_cross == 1:    #then check to see if you can cross stream

        if stream_perm < random():

            return 1

        else:

            return 0

    else:

        return 0                  

#end streams



def topo_bias(nslope,sslope,eslope,wslope, xmin, ymax, dx, pos, dp, max_slope, l_slope = 0.0):

    if l_slope <> 0.0:

        #determine cell location

        r = int(((ymax - pos.y) / dx) - (dx/2.0))

        c = int(((pos.x - xmin) / dx) - (dx/2.0))

        #determine applicable slope

        dir = norm(dp)

        if (-0.5 < dir.x <= 0.5):  #then move is north or south

            if dir.y >= 0:  #move is north

                s = nslope.data[r,c]

            else: #move is south

                s = sslope.data[r,c]

        else: #move is east or west

            if dir.x > 0:   #move is east

                s = eslope.data[r,c]

            else: #move is west

                s = wslope.data[r,c]



        #evaluate probability of not making the move

        p_not = (abs(s) / max_slope) * l_slope # should give a value less than 1; greater slope = greater reluctance

        if random() < p_not:

            #print "don't do it"

            return 1

        else:

            return 0

    else:

        return 0

    

def attract_grad(pos, oray):

    #oray is 2d array with id, x, y, Azero, halflife: for locations of outcrops

    #r, c = arr.shape

    dx = pos[0] - oray[:,1]

    dy = pos[1] - oray[:,2]

    rad = sqrt(dx * dx + dy * dy) #calculates the distance to each point (outcrop)

    gexp = -0.693 * rad / oray[:,5]

    gray = oray[:,6] * ((-0.693 * oray[:,4] / oray[:,5]) * exp(gexp)) 

    norm_x = dx / (dx + dy)

    norm_y = dy / (dx + dy)

    grayx = sum(gray * norm_x)

    grayy = sum(gray * norm_y)

    #print "attractor gradient =", vector(grayx, grayy, 0.0)

    return vector(grayx, grayy, 0.0)

                                                

        

    

    

##def write_walk(hit_ct, outfile):

##    outln = ""

##    for i in hit_ct:

##        outln = outln + str(i.ct) + " "

##        outln = outln + str(i.mass) + " "

##    outln = outln + "\n"

##    outfile.write(outln)

#attract = []

cherttypes = []



#####################################################

#   INPUT PARAMETERS

#####################################################



#RANGE (rng) IS THE RANGE OF INFLUENCE OF EACH LOCATION

rng = 250

#NUMBER OF STEPS IN RANDOM WALK (nsteps)

nsteps = 100

step_size = 1000

ndirs = 360    #the number of directions you can go off in

#NUMBER OF WALKS (nwalks)

nwalks = 20

#RANDOM NUMBER GENERATION SPECIFICATIONS

seed = 1



#MAXIMUM LOAD CARRIED

max_load = 20.

min_load =  0.0

#mass picked up from each outcrop encountered

load_add =  1.0

#load attrition rate (as a fraction) per rocktype per step

load_atr =  0.01



#test for convergence using an overnight run set l_converg(start,stop)

#  the simulation will repeat l_converg times

#  the maximum number of walks will be nwalks * 2^l_converg

#  To have only one set of walks run set

#       l_converg = range(0,1)

#  l_scale is the base to which the number of simulation is raised should be an integer

#    eg will give nwalks*l_scale**l_converg[i]

l_converg = range(0,1)

l_scale = 1



#draw 3d output if l_draw = 1

l_draw = 1

# draw histogram if l_draw is also 1

l_draw_graph = 1

# draw dem

l_draw_topo = 1

#scale elevation data

z_scale = 10.0  # to scale the elevation data (0.0 means a 2d map)



#setup scene window

if l_draw == 1:

    sw = 500

    sh = 800

    sx = 0

    sy = 0

    scene.width = sw

    scene.height = sh

    scene.x = sx

    scene.y = sy





#site locations

sites = []

col = vector(1,1,0)

sites.append(outcrop("la-cote",     639495.5157, 3311775.908, l_draw, 2.*rng, col))

sites.append(outcrop("Le Moustier", 682537.139,  3298763.248, l_draw, 2.*rng, col))

sites.append(outcrop("Le Flag",     683737.1246, 3282782.176, l_draw, 2.*rng, col))

sites.append(outcrop("Caminade",    697025.6269, 3283652.463, l_draw, 2.*rng, col))



#site where random walks originate - must be exactly the same as one of the location entered above (in the list sites[])

start_site = "Le Moustier"



# the home_sickness value restricts motion opposite the direction of home

# 0.0 <= home_sickness <= 1.0

# if home_sickness = 0.5 then the chert-man can only move in a direction that is within 90 degrees of the home direction. 

home_sickness = 0.5     #bias toward heading home after the walk (must be between 0 and 1.0)



# stream permeability - 

# 0.0 <= stream_perm <= 1.0

#  stream_perm is the probability of being able to cross a stream

stream_perm = 1.0



# to consider slope in the program set l_slope to a value greater than 0.0

# if l_slope > 1.0 then that sets an upper limit as to the slope 

#   that chertman can scale.

l_slope = 0.0

#l_stuck is the number of times for chertman to try and fail to escape somewhere.

l_stuck = 100



# set up attractors for the different directions of motion

# l_attract = 0 or 1

l_attract = 0

# you need to know ahead of time the ID's of the data

# to enter attractor('id', 'Azero', 'halflife', 'attractive', 'atr_rate', 'prob_pickup')

#   prob_pickup is a value between 0.0 and 1.0: Default = 1.0

#       it tells the probability that a type of chert will be picked up

#       if encountered

cherttypes.append(cherttype('1',  Azero = 100.0, halflife = 1000, attractive = 1.0,

                            atr_rate = load_atr, prob_pickup = 1.0))

cherttypes.append(cherttype('2',  atr_rate = load_atr, prob_pickup = 1.0))

cherttypes.append(cherttype('3',  atr_rate = load_atr, prob_pickup = 1.0))

cherttypes.append(cherttype('4',  atr_rate = load_atr, prob_pickup = 1.0))

cherttypes.append(cherttype('5',  atr_rate = load_atr, prob_pickup = 1.0))

cherttypes.append(cherttype('7',  atr_rate = load_atr, prob_pickup = 1.0))

cherttypes.append(cherttype('8',  atr_rate = load_atr, prob_pickup = 1.0))

cherttypes.append(cherttype('25', atr_rate = load_atr, prob_pickup = 1.0))

norm_abias = 1.0



# INPUT FILES

# Outcrop data as ordered list of data points with header line and format

# X	Y	ID

f_outcrop = "rechecked_xy_transf.txt"

# Stream data as an ordered list of data points with headerline and format

# X   Y   StreamName

f_stream = "streams_transformed2.txt"

# topography

f_topo = "rastert_asciito1.txt"



#####################################################

#   END OF INPUT PARAMETERS

#####################################################





print "File Name = ", argv[0]

wfout_file = basename(argv[0]) + ".dat"

#output filenames

#full data

#wfout_file = 



for i in sites:

    if i.id == start_site:

        start_pos = vector(i.x, i.y, 0.)

    print i.id, i.x, i.y



#set scene center

if l_draw == 1:

    scene.center = start_pos

    scene.background = (1,1,1)

    scene.autoscale = 0

    scene.range = 50000



if l_draw_graph == 1:

    gdisp = gdisplay(x=sw, y=0, width=sw, height=sh/2)

##                     ytitle="Average Mass (every 10 steps)", xtitle="walk",

##                    ymin=min_load, ymax=max_load)

    masshist = ghistogram(bins=arange(min_load, max_load, load_add), color=color.red)

#                          accumulate=1, average=1)

##    Tcurve = gcurve(color=color.cyan) # a connected curve object

##    Tdots =  gdots(color=(1,1,0))





''' READ IN OUTCROP DATA '''

outcrops = [] #list with locations of outcrops and their type

oray = [] #array for outcrops giving columns ['id','x','y','z','Azero','halflife','attractive'

# First open the file to read(r)

infile = open(f_outcrop,"r")

# read the file into a list then print each item

ncrops = 0

crop_ct = 0

hit_ct = []

attract_array = []  # the first column will be the attractor depth and the second the half life

old_crop = ""

filelines = infile.readlines()

for i in range(1, len(filelines)):  #skip first header line

    ncrops = ncrops+1

    l = split(strip(filelines[i]))

    dat_id = l[2]

    dat_x = l[0]

    dat_y = l[1]



    #print "dat_id, old_crop", dat_id, old_crop

    #print "filelines = ", filelines[i]

    same_as = 0

    for j in outcrops:

        #print "i, j, j[0], old_crop = ", i, j, j[0], old_crop

        if j.id == dat_id:        #j[0] is the outcrop id

            same_as = 1

        #print same_as    

            

    if same_as == 0:

        crop_ct += 1

        old_crop = dat_id

        #print "old_crop, line =", old_crop

        hit_ct.append(hit_counter(dat_id))



    outcrops.append(outcrop(dat_id, dat_x, dat_y, l_draw, rng))

    #oray.append((float(dat_id), float(dat_x), float(dat_y), 0.0, 0.0))

    if l_attract <> 0:

        for j in cherttypes:

            if dat_id == j.id:

                #print "oray[-1] = ", oray[-1][3]

                #print "j.Azero = ", j.Azero

                #print "j.halflife = ", j.halflife

                oray.append((float(dat_id), float(dat_x), float(dat_y), 0.0, j.Azero, j.halflife, j.attractive))

                #oray[-1][3] = 10.0

                #oray[-1][4] = j.halflife

    else:

        oray.append((float(dat_id), float(dat_x), float(dat_y)))

##    if l_attract == 1:

##        if len(l) >= 6:

##            outcrops[-1].Azero = float(l[5])

##            attract_array.append(outcrops[-1].Azero)

##        if len(l) >= 7:

##            outcrops[-1].halflife = float(l[6])

##            attract_array.append(outcrops[-1].halflife)

    for j in cherttypes:

        if j.id == dat_id:

            j.x.append(float(dat_x))

            j.y.append(float(dat_y))



# Now close it again

infile.close()

oray = array(oray)



for i in hit_ct:

    for j in cherttypes:

        if i.id == j.id:

            i.atr_rate = j.atr_rate

            i.prob_pickup = j.prob_pickup





#set outcrop color

for i in outcrops:

    if i.id == "1":

        i.ball.color = vector(0.0,0.0,0.0)

    if i.id == "2":

        i.ball.color = vector(.83,.6,.4)

    if i.id == "3":

        i.ball.color = vector(.7,.0,.4)

    if i.id == "4":

        i.ball.color = vector(0.0,0.8,0.1)

    if i.id == "5":

        i.ball.color = vector(0.9,0.9,.15)

    if i.id == "25":

        i.ball.color = vector(0.99,0.6,.0)

    if i.id == "8":

        i.ball.color = vector(.7,.52,.4)





print "Number of outcrops = ", ncrops

#print "oray "

#print oray

#print "oray first row"

#print oray[0,:]

##print "oc"

##print oc

print "number of different types of outcrops = ", crop_ct

#print hit_ct





'''STREAMS'''

streams = [] #list of streams

oc = []

# First open the file to read(r)

infile = open(f_stream,"r")

# read the file into a list then print each item

ct = 0

str = -1

str_old = ""

flines = infile.readlines()

for i in range(1, len(flines)):

    l = split(strip(flines[i]))

    dat_id = l[2]

    dat_x = l[0]

    dat_y = l[1]

    dat_size = l[3]



    if str_old <> dat_id:

        str_old =dat_id 

        streams.append(stream(dat_id))

        str = str+1

        #print streams[str].name

        

    streams[str].x.append(float(dat_x))

    streams[str].y.append(float(dat_y))

    streams[str].z.append(0.0)

    streams[str].size.append(int(dat_size))



# Now close file

infile.close()



for i in streams:

    i.x = array(i.x)

    i.y = array(i.y)

    i.z = array(i.z)

    i.size = array(i.size)

    i.cross()

    



#rotate streams, outcrops, sites

origin = vector(680097, 3294948, 0)

rangle = 2.0

for i in streams:

    for j in range(len(i.x)):

        #print i.name, i.x[j], i.y[j]

        posvec = vector(i.x[j], i.y[j], 0.0)

        posvec = posvec - origin  #translate        

        posvec = rotate(posvec, angle=rangle*pi/180, axis=(0,0,1)) #rotate

        posvec = posvec + origin #translate

        i.x[j] = posvec.x

        i.y[j] = posvec.y

        #print "     ", i.x[j], i.y[j]



for i in outcrops:

    posvec = vector(float(i.x), float(i.y), 0.0)

    posvec = posvec - origin  #translate        

    posvec = rotate(posvec, angle=rangle*pi/180, axis=(0,0,1)) #rotate

    posvec = posvec + origin  #translate

    i.x = posvec.x

    i.y = posvec.y

    

for i in sites:

    posvec = vector(float(i.x), float(i.y), 0.0)

    posvec = posvec - origin  #translate        

    posvec = rotate(posvec, angle=rangle*pi/180, axis=(0,0,1)) #rotate

    posvec = posvec + origin  #translate

    i.x = posvec.x

    i.y = posvec.y

    



'''TOPOGRAPHY'''

#READ IN TOPOGRAPHY FROM arcinfo GIS OUTPUT OF RASTER FILE (ASCII)

### reads in the header information also



topo = raster_import(f_topo)

print "TOPOGRAPHY"

print "nrows, ncols, dx, xmin, ymax"

print topo.nrows, topo.ncols, topo.dx, topo.xmin, topo.ymax

print topo.data[0:5,0:20]

#view(topo)

infile.close()



#Elevate outcrop data

for i in cherttypes:

##    print "cherttype = ", i.id

##    print "x in"

##    print i.x

    for j, k in zip(i.x, i.y):

        elev = elevate(vector(j,k,0.0),topo)

        i.z.append(elev.z)

    i.makearrays()

##    print "x out"

##    print i.x

##    print "y"

##    print i.y

##    print "z"

##    print i.z

    



#calculate slopes in 4 directions

if l_slope > 0.0:

    tmp = ( topo.data[0:nrows-1,:] - topo.data[1:nrows,:] ) / dx

    nslope = zeros((nrows*ncols,), Float)

    nslope = resize(nslope, (nrows, ncols))

    nslope[1:nrows,:] = tmp

##    for i in range(1,nrows):

##        for j in range(ncols):

##            nslope[i,j] = tmp[i-1,j]



    tmp = ( topo.data[1:nrows,:] - topo.data[0:nrows-1,:]  ) / dx

    sslope = zeros((nrows*ncols,), Float)

    sslope = resize(sslope, (nrows, ncols))

    sslope[0:nrows-1,:] = tmp

##    for i in range(0,nrows-1):

##        for j in range(ncols):

##            sslope[i,j] = tmp[i,j]



    tmp = ( topo.data[:,1:ncols] - topo.data[:,0:ncols-1]  ) / dx

    eslope = zeros((nrows*ncols,), Float)

    eslope = resize(eslope, (nrows, ncols))

    eslope[:,0:ncols-1] = tmp

##    for i in range(nrows):

##        for j in range(0,ncols-1):

##            eslope[i,j] = tmp[i,j]



    tmp = (  topo.data[:,0:ncols-1] - topo.data[:,1:ncols] ) / dx

    wslope = zeros((nrows*ncols,), Float)

    wslope = resize(wslope, (nrows, ncols))

    wslope[:,1:ncols] = tmp

##    for i in range(nrows):

##        for j in range(0,ncols-1):

##            wslope[i,j] = tmp[i,j-1]



    max_slope = max(max(nslope))

    nslope = raster_map(nslope, xmin, ymax, dx, nrows, ncols)

    sslope = raster_map(sslope, xmin, ymax, dx, nrows, ncols)

    eslope = raster_map(eslope, xmin, ymax, dx, nrows, ncols)

    wslope = raster_map(wslope, xmin, ymax, dx, nrows, ncols)

    #nslope.draw_map( 120, 200, 240, 340)

    print "MAXIMUM SLOPE IN DATASET (max_slope) = ", max_slope

    print "Maximum slope chert-man can scale    = ", max_slope / l_slope



    ##print "wSLOPE"

    ##print wslope[0:5,0:20]





''' CALCULATE ATTRACTOR SLOPE MORPHOLOGY '''

# attract_array has columns [Azero, halflife, active]

# construct raster array coincident with the topography

if l_attract <> 0:

    print 'calculating attractor slope morphology'

    attx = resize(zeros((nrows*ncols,), Float), (nrows,ncols))

    atty = resize(zeros((nrows*ncols,), Float), (nrows,ncols))

    zp = 0.0

    for i in range(nrows):

        print "row = %i of %i" % (i, nrows)

        yp = ymax - dx*i

        for j in range(ncols):

            xp = xmin + dx*j

            #print "xp, yp, zp = ", xp, yp, zp

            attx[i,j] = attract_grad(vector(xp,yp,0.0),oray).x

            atty[i,j] = attract_grad(vector(xp,yp,0.0),oray).y



##        print "attract_array"

##        print attract_array



    # create raster map for attractors

    attx_map = raster_map(attx, xmin, ymax, dx, nrows, ncols)

    atty_map = raster_map(atty, xmin, ymax, dx, nrows, ncols)







#PLOT TO VPYTHON DISPLAY

if l_draw == 1:

    print "Drawing ..."

##    #plot sites

##    for i in sites:

##        print i.x, i.y

##        sphere(pos=(i.x, i.y), radius=rng*2.0, color=(1,1,0))

##        

##    #plot outcrops

##    col = vector(1,0,1)

##    for i in outcrops:

##        sphere(pos=(i.x, i.y), radius=rng, color=col)



    #start_pos = elevate(start_pos, topo, z_scale)



    #plot outcrop elevations

    for i in sites:

        i.elevate(topo, z_scale)

    for i in outcrops:

        i.elevate(topo, z_scale)

        

    #plot streams

    print "STREAM NAME      Number of points in stream"

    for i in streams:

        i.elevate(topo, z_scale)

        print " ", i.name, len(i.x)

        river = curve(color = (0,0,1))

        for j in range(len(i.x)):

            river.append(pos = (i.x[j], i.y[j], i.z[j]))

            #tx = str(j)

            #label each point on line

##            label(pos=(float(i.x[j]), float(i.y[j])), text=repr(j),

##                  box=0, opacity = 0, xoffset=-5, yoffset=5,  height=10, color=color.blue)

            #print float(i.x[j]), float(i.y[j])

        #rate(1)



    if l_draw_topo == 1:

        #plot topography

        # resize topo array to area of interest

        

        #topo.draw_map( 60, 290, 200, 380)

        #topo.draw_map( 100, 200, 250, 350, scale = z_scale)

        #topo.draw_map(scale = z_scale)

        topo.line_3d(100, 200, 250, 350,scale = z_scale)

    if l_attract <> 0:

        attx_map.line_3d( 60, 290, 200, 380)

        



'''CALCULATE DISTRIBUTIONS BASED ON DISTANCE OF SITE FROM OUTCROPS'''

# Distance weighted

dist_fout = open("radius_based_distr.txt","w")

dist_fout.write("Calculating distance weighted distributions \n")

for i in sites:

    outline = "Site =,%s" % i.id + "\n"

    dist_fout.write(outline)



    type_dist = []  

    inv_rad = []

    inv_rad2 = []

    for j in cherttypes:

        dx = j.x - i.x

        dy = j.y - i.y

        rad = sqrt(dx * dx + dy * dy)

        wt = add.reduce(rad)

        type_dist.append(wt)

        irad = add.reduce(1.0/rad)

        inv_rad.append(irad)

        irad2 = add.reduce(1.0/(rad*rad))

        inv_rad2.append(irad2)

        

        

    tot_dist = reduce(add, type_dist)

    tot_inv = reduce(add, inv_rad)

    tot_inv2 = reduce(add, inv_rad2)

    

    outline = "Chert type, Total distance to type, Distance weight, Inverse distance Weight, Inverse Distance Squared \n"

    dist_fout.write(outline)



    type_frac = []

    inv_frac = []

    inv2_frac = []

    print "id, total radius, wt, total inverse distance, wt" 

    for j, k  in enumerate(cherttypes):

        type_frac.append(type_dist[j] / tot_dist)

        inv_frac.append(inv_rad[j] / tot_inv)

        inv2_frac.append(inv_rad2[j] / tot_inv2)

        

        outline = "%s, %10.20f, %10.20f, %10.20f, %10.20f" % (k.id, type_dist[j], type_frac[-1], inv_frac[-1], inv2_frac[-1]) + "\n"

        dist_fout.write(outline)

        print k.id, type_dist[j], type_frac[-1], inv_rad[j], inv_frac[-1], inv2_frac[-1]

        

        

    tot_frac = reduce(add, type_frac)

    tot_invfrac = reduce(add, inv_frac)

    tot_invfrac2 = reduce(add, inv2_frac)

    

    outline = "Total, %10.20f, %1.5f, %1.5f, %1.5f" % (tot_dist, tot_frac, tot_invfrac, tot_invfrac2) + "\n"

    dist_fout.write(outline)

dist_fout.close()

    



##for i in sites:

##    dx = oray[:,1] - i.x

##    dy = oray[:,2] - i.y

##    rad = sqrt(dx * dx + dy * dy)

##    tot_dist = add.reduce(rad)

##    print "tot_dist = ", tot_dist

##    for j in cherttypes:

##        type_rad = 0.0

##        for k in outcrops:

##            if j.id == k.id:

##                dx = i.x - k.x

##                dy = i.y - k.y

##                type_rad = type_rad + (dx * dx + dy * dy) ** 0.5

##                

##        









#output data for every walk

wfout = open(wfout_file,"a")

outline = "RANDOM WALK SIMULATION - " + datetime.today().strftime("%A %B %d, %Y. - %I:%M:%S") + "\n"

wfout.write(outline)

outline = "File Name = %s" % argv[0] + "\n"

wfout.write(outline)

outline = "Starting Site (start_site) = %s" % start_site + "\n"

wfout.write(outline)

outline = "RANGE OF INFLUENCE OF EACH OUTCROP (rng) = %1.1f" % rng + "\n"

wfout.write(outline)

outline = "NUMBER OF STEPS IN RANDOM WALK (nsteps)  = %i" % nsteps + "\n"

wfout.write(outline)

outline = "SIZE OF EACH RANDOM STEP (step_size)     = %1.1f" % step_size + "\n"

wfout.write(outline)

outline = "NUMBER OF MOVEMENT DIRECTIONS (ndirs)    = %i" % ndirs + "\n"

wfout.write(outline)

outline = "NUMBER OF WALKS IN SIMULATION (nwalks)   = %i" % nwalks  + "\n"

wfout.write(outline)

outline = "MAXIMUM LOAD (max_load)                  = %1.1f kg" % max_load  + "\n"

wfout.write(outline)

outline = "MINIMUM LOAD (min_load)                  = %1.1f kg" % min_load  + "\n"

wfout.write(outline)

outline = "MASS PICKED UP per step (load_add)       = %1.1f kg" % load_add  + "\n"

wfout.write(outline)

outline = "ATTRITION RATE per step (load_atr)       = \n"

wfout.write(outline)

outline = ''

for i in hit_ct:

    outline = outline + "ID=%s atr_rate=%1.3f ;" % (i.id, i.atr_rate)

outline = outline + "\n"

wfout.write(outline)

outline = "Probability of crossing stream (stream_perm)= %1.3f " % stream_perm  + "\n"

wfout.write(outline)

outline = "Slope effects (l_slope)                  = %1.3f " % l_slope  + "\n"

wfout.write(outline)

outline = "Maximum escape attempts if stuck (l_stuck) = %i " % l_stuck  + "\n"

wfout.write(outline)

outline = ""

for i in hit_ct:

    tmp1 = "Nhits-ID=%s " % i.id   #the type of outcrops encountered

    outline = outline + tmp1 #+ tmp2

for i in hit_ct:

    tmp1 = "Mass-ID=%s " % i.id   #the type of outcrops encountered

    outline = outline + tmp1 #+ tmp2

outline = outline + "walk_steps "

outline = outline + "Total\n"

wfout.write(outline)



chertman = sphere(radius = rng, color=color.red, pos=start_pos)

chertman.pos = elevate(chertman.pos, topo, z_scale)

#pathway = curve(color = (0,1,0))



#random walk

tot_mass = []   #list giving the total mass at the end of each walk

newpos = vector(0,0,0)

tot_walks = 0

adir = vector(0,1,0)

abias = 0.0

nwalks_init = nwalks

for lc in l_converg: # for convergence testing

    nwalks = nwalks_init * (l_scale**lc)

    print "nwalks = ", nwalks

    nhits = 0    

    for w in range(1,nwalks+1):

        tot_walks += 1

        # reset bag contents to zero for each walk

        for i in hit_ct:

            i.mass = 0.0

        total_mass = 0.0

        

        if l_draw == 1:

            #pathway.visible = 0

            pathway = curve(color = (0,1,0), radius=100)

            pathway.append(pos=elevate(start_pos, topo, z_scale))

        route = []

        route.append(start_pos)

##        print "start"

##        rate(.1)

##        print "go"

        

        '''HEAD OUT'''

        walk_steps = 0

        for i in range(1,nsteps+1):

            #attrition of material over step

            total_mass = 0.0

            for i in hit_ct:

                #print "item mass = ", i.id, i.mass

                i.mass = i.mass - (i.mass * i.atr_rate)   #mass attrition function

                i.mass = max(i.mass, 0.0)               #can't have negative mass

                total_mass = total_mass + i.mass



            l_stuck_test = 0

            l_again = 1

            while l_again == 1:

                l_again =0

                #determine new position

                # adjust for attractors by determining bias direction

                if l_attract <> 0:

                    agrad = attract_grad(route[-1], oray)

                    if agrad.x <> 0 or agrad.y <> 0:

                        adir = norm(agrad)

                        abias = min(mag(agrad)/norm_abias, 1.0)

                    else:

                        abias = 0.0

                    print "adir, abias = ", adir, abias

                #take step

                dp = step_size * step_dir(ndirs, adir, abias)

                newpos = route[-1]+dp

                chertman.pos = elevate(newpos, topo, z_scale)

                

                #adjust for streams

                l_again = stream_crossing(stream_perm,route[-1],newpos,streams,step_size)

                #adjust for topography (slope)

                if l_again == 0 and l_slope > 0.0:

                    l_again = topo_bias(nslope,sslope,eslope,wslope,

                                        xmin, ymax, dx, route[-1], dp, max_slope, l_slope)

                    #see that chertman is not stuck in one place forever

                    if l_again ==1:

                        l_stuck_test += 1

                        if l_stuck_test >= l_stuck:

                            l_again = 0

            walk_steps += 1

            if l_draw == 1:

                pathway.append(pos=elevate(newpos, topo, z_scale))

##                rate(.2)

            route.append(newpos)

            # Take step and add appropriate mass

            #print "o total_mass = ", total_mass

            take_step(nhits,ndirs,step_size,oray,hit_ct,outcrops,load_add, max_load, total_mass)

                              

        '''HEAD HOME'''    

        if l_draw == 1:

            #pathway.append(color = (1,0,0))

            pathway.color=(1,0,0)

        ct = nsteps

        while mag(newpos - start_pos) > step_size:

            #attrition of material over step

            total_mass = 0.0

            for i in hit_ct:

                #print "item mass = ", i.id, i.mass

                i.mass = i.mass - (i.mass * i.atr_rate)   #mass attrition function

                i.mass = max(i.mass, 0.0)               #can't have negative mass

                total_mass = total_mass + i.mass



            l_stuck_test = 0

            l_again = 1

            while l_again == 1:

                l_again = 0

                #determine new position

                home_dir = start_pos - newpos

                home_dir = norm(vector(home_dir.x, home_dir.y, 0.0))

##                print "start_pos = ", start_pos

##                print "newpos = ", newpos

##                print "  ct = ", ct

##                print "home_dir = ", home_dir

                dp = step_size * step_dir(ndirs, home_dir, home_sickness) #move biased by 0.5 in the direction of home

                newpos = route[-1]+dp

                chertman.pos = elevate(newpos, topo, z_scale)

                #adjust for streams

                l_again = stream_crossing(stream_perm,route[-1],newpos,streams,step_size)

                #adjust for topography (slope)

                if l_again == 0 and l_slope > 0.0:

                    l_again = topo_bias(nslope,sslope,eslope,wslope,

                                        xmin, ymax, dx, route[-1], dp, max_slope, l_slope)

                    #see that chertman is not stuck in one place forever

                    if l_again ==1:

                        l_stuck_test += 1

                        if l_stuck_test >= l_stuck:

                            l_again = 0



            walk_steps += 1

            if l_draw == 1:

                pathway.append(pos=elevate(newpos, topo, z_scale))

            route.append(newpos)

            #print "i total_mass = ", total_mass

            take_step(nhits,ndirs,step_size,oray,hit_ct,outcrops,load_add, max_load, total_mass)

            ct += 1



        if l_draw == 1:

                pathway.append(pos=elevate(start_pos, topo, z_scale))

#        print "pause 2"



        #record mass at end of walk

        total_mass = 0.0

        for i in hit_ct:

            tmp_mass = i.avmass * (tot_walks - 1) + i.mass

            i.avmass = tmp_mass / float(tot_walks)

            i.stmass.append(i.mass)

            total_mass = total_mass + i.mass

            #print " id = ", i.id, ": mass = ", i.mass

        tot_mass.append(total_mass)

        #write out at end of each walk

        outline = ""

        for i in hit_ct:

            outline = outline + "%i " % i.ct

        for i in hit_ct:

            outline = outline + "%1.5f " % i.mass

        outline = outline + "%i " % walk_steps

        outline += "\n"

        wfout.write(outline)

        if (w % 10) == 0:

            print "Walk ", w, " / ", nwalks, ": tot_mass[-10:-1] = ", tot_mass[-10:-1]

        #print "Walk =", tot_walks, " total_mass = ", tot_mass[-1]

            if l_draw_graph == 1:

                masshist.plot(data=tot_mass) # plot the Total Mass distribution

##                Tcurve.plot(pos=(tot_walks, mean(tot_mass)))

##                Tdots.plot(pos=(tot_walks, mean(tot_mass[-10:-1])))

    print "number of steps = ", nsteps

    print "number of hits  = ", nhits

    print "types of hits"

    wfout.close()



    for i in hit_ct:

        #calculate statistics

        if len(i.stmass) > 1:

            print "i.stmass = ", i.stmass

            i.stdev = standardDeviation(i.stmass)

        else:

            i.stdev = 0.0

        i.min = min(i.stmass)

        i.max = max(i.stmass)

        i.median = median(i.stmass)

        print "id = ", i.id, ": nhits = ", i.ct, ": Average mass = ", i.avmass

        #i.skew = skewness(i.stmass)

    print "Average total mass at end of run = ", mean(tot_mass)

    

    #Write output file    

    fout = open("random_walk_out.txt","a")

    fout.write("\n")

    outline = "RANDOM WALK SIMULATION COMPLETED - " + datetime.today().strftime("%A %B %d, %Y. - %I:%M:%S") + "\n"

    fout.write(outline)

    outline = "File Name = %s" % argv[0] + "\n"

    fout.write(outline)

    outline = "Starting Site (start_site) = %s" % start_site + "\n"

    fout.write(outline)

    outline = "RANGE OF INFLUENCE OF EACH OUTCROP (rng) = %1.1f" % rng + "\n"

    fout.write(outline)

    outline = "NUMBER OF STEPS IN RANDOM WALK (nsteps)  = %i" % nsteps + "\n"

    fout.write(outline)

    outline = "SIZE OF EACH RANDOM STEP (step_size)     = %1.1f" % step_size + "\n"

    fout.write(outline)

    outline = "NUMBER OF MOVEMENT DIRECTIONS (ndirs)    = %i" % ndirs + "\n"

    fout.write(outline)

    outline = "NUMBER OF WALKS IN SIMULATION (nwalks)   = %i" % nwalks  + "\n"

    fout.write(outline)

    outline = "MAXIMUM LOAD (max_load)                  = %1.1f kg" % max_load  + "\n"

    fout.write(outline)

    outline = "MINIMUM LOAD (min_load)                  = %1.1f kg" % min_load  + "\n"

    fout.write(outline)

    outline = "MASS PICKED UP per step (load_add)       = %1.1f kg" % load_add  + "\n"

    fout.write(outline)

    outline = "ATTRITION RATE per step (load_atr)       = %1.3f " % load_atr  + "\n"

    fout.write(outline)

    outline = ''

    for i in hit_ct:

        outline = outline + "ID=%s atr_rate=%1.3f ;" % (i.id, i.atr_rate)

    outline = outline + "\n"

    fout.write(outline)

    outline = "Probability of crossing stream (stream_perm)= %1.3f " % stream_perm  + "\n"

    fout.write(outline)

    outline = "Slope effects (l_slope)                  = %1.3f " % l_slope  + "\n"

    fout.write(outline)

    outline = "Maximum escape attempts if stuck (l_stuck) = %i " % l_stuck  + "\n"

    fout.write(outline)

    outline = "Average total mass (mean(tot_mass))      = %1.3f kg" % mean(tot_mass)  + "\n"

    fout.write(outline)

    fout.write("\n")

    outline = "    ID#    #HITS    Mass   Average_mass  Standard_Deviation Minimum    Maximum     Median \n"

    fout.write(outline)

    for i in hit_ct:

        outline = " %5s    %5i     %5.5f   %5.5f    %5.5f          %5.5f      %5.5f      %5.5f" % (i.id, i.ct, i.mass, i.avmass, i.stdev, i.min, i.max, i.median) + "\n"

        fout.write(outline)

    if len(tot_mass) > 1:

        totstdev =  standardDeviation(tot_mass)

    else:

        totstdev = 0.0

    outline = " %5s    %5i     %5.5f   %5.5f    %5.5f          %5.5f      %5.5f      %5.5f" % ("Total", 0, 0, mean(tot_mass),totstdev, min(tot_mass), max(tot_mass), median(tot_mass)) + "\n"

    fout.write(outline)



    fout.close()

    ##    print rad_list



if (len(argv) > 1):

    os._exit(0)


Personal tools