Пример #1
0
 def plantSeed(self, theSeed):
     #self=garden, obj=seed
     theGarden = self
     theNameList = theSeed.name.split()
     if len(theNameList) < 2:
         idNumb = str(random.random())
     else:
         idNumb = theNameList[1]
     theSeed.timePlanted = time.time()
     theSeed.name = "plantedSeed %s" % (idNumb)
     if theSeed.motherPlant == 0:
         theSeed.motherPlant = theSeed
     theGarden.soil.append(theSeed)
     theGarden.numbSeeds = self.numbSeeds + 1
     #####If there are subregions defined, see what subregion does it belong in this seed belongs
     #print "the Garden: %s" % (theGarden)
     #print "the region: %s" % (theGarden.theRegions)
     if len(theGarden.theRegions) > 0:
         for aRegion in theGarden.theRegions:
             #print aRegion.name
             #print theSeed.name
             if aRegion.shape == 'square':
                 inSubregion = geometry_utils.pointInsideSquare(
                     aRegion.x, aRegion.y, aRegion.size, theSeed.x,
                     theSeed.y)
             elif aRegion.shape == 'circle':
                 #size needs to be radius but region defines diameter
                 inSubregion = geometry_utils.pointInsideCircle(
                     aRegion.x, aRegion.y, aRegion.size / 2.0, theSeed.x,
                     theSeed.y)
             if inSubregion:
                 if not aRegion in theSeed.subregion:
                     theSeed.subregion.append(aRegion)
     return theSeed
Пример #2
0
	def plantSeed(self, theSeed):
		#self=garden, obj=seed
		theGarden=self
		theNameList= theSeed.name.split()
		if len(theNameList)<2:
			idNumb=str(random.random())
		else:
			idNumb=theNameList[1]
		theSeed.timePlanted=time.time()
		theSeed.name="plantedSeed %s" % (idNumb)
		if theSeed.motherPlant==0:
			theSeed.motherPlant=theSeed
		theGarden.soil.append(theSeed)
		theGarden.numbSeeds=self.numbSeeds+1
		#####If there are subregions defined, see what subregion does it belong in this seed belongs
		#print "the Garden: %s" % (theGarden)
		#print "the region: %s" % (theGarden.theRegions)
		if len(theGarden.theRegions)>0:
			for aRegion in theGarden.theRegions:
				#print aRegion.name
				#print theSeed.name
				if aRegion.shape=='square':
					inSubregion=geometry_utils.pointInsideSquare(aRegion.x, aRegion.y, aRegion.size, theSeed.x, theSeed.y)
				elif aRegion.shape=='circle':
					#size needs to be radius but region defines diameter
					inSubregion=geometry_utils.pointInsideCircle(aRegion.x, aRegion.y, aRegion.size/2.0, theSeed.x, theSeed.y)
				if inSubregion:
					if not aRegion in theSeed.subregion:
						theSeed.subregion.append(aRegion)		
		return theSeed
Пример #3
0
def determineShade(theGarden):
    if theGarden.showProgressBar:
        print "***Generating lists of overlapping plants. This could take a while...***"
        theProgressBar = progressBarClass.progressbarClass(
            len(theGarden.soil), "*")
        i = 0
    ###populate the overlap list
    theIndex = 0
    for plantOne in theGarden.soil:
        if plantOne.isSeed == 0 or (plantOne.isSeed and
                                    plantOne.minimumLightForGermination > 0.0):
            plantOne.overlapList = []
            plantOne.areaCovered = 0.0
            plantOne.colourLeaf[2] = 1.0
            ###the following might be able to be used to speed things up
            #for overlappingItem in plantOne.overlapList:
            #	if not overlappingItem in theGarden.soil or not overlappingItem.z>plantOne.z:
            #		###make sure the overlapping item is still alive
            #		###and that overlapping item is still taller
            #		plantOne.overlapList.remove(overlappingItem)
            ###need to insert something so tallest plant looks at all the other plants of exactly the same size
            ###if they are the same size and overlapping, they need to share shading
            for plantTwo in range(theIndex):
                plantTwo = theGarden.soil[plantTwo]
                ###is plant two overlapping you?
                overlapStatus = geometry_utils.checkOverlap(
                    plantOne.x, plantOne.y, plantOne.r, plantTwo.x, plantTwo.y,
                    plantTwo.r)
                if overlapStatus > 0:
                    if not plantTwo in plantOne.overlapList:
                        if not plantTwo == plantOne:
                            plantOne.overlapList.append(plantTwo)
            ###sort the overlap list by height of the plants. Ordered shortest to tallest
            plantOne.overlapList = list_utils.sort_by_attr(
                plantOne.overlapList, "heightStem")
            ###flip the list so it's ordered tallest to shortest
            plantOne.overlapList.reverse()
            theIndex = theIndex + 1
            if theGarden.showProgressBar:
                i = i + 1
                theProgressBar.update(i)

    ###take the overlap list and start dropping photons onto it.
    if theGarden.showProgressBar:
        print "***Determining shading. This could take a while...***"
        theProgressBar = progressBarClass.progressbarClass(
            len(theGarden.soil), "*")
        i = 0
    for plant in theGarden.soil:
        if plant.isSeed == 0 or (plant.isSeed
                                 and plant.minimumLightForGermination > 0.0):
            fractionExposed = 1.0
            if len(plant.subregion) > 0:
                theRegion = plant.subregion[-1]
            else:
                theRegion = theGarden
            if len(plant.overlapList) > 0:
                thePlantAreaTotal = geometry_utils.areaCircle(plant.r)
                if thePlantAreaTotal == 0.0:
                    print "name:%s r:%f isSeed:%i massSeed:%f massTotal:%f" % (
                        plant.name, plant.r, plant.isSeed, plant.massSeed,
                        plant.massTotal)
                if len(
                        plant.overlapList
                ) == 1:  ###if you are covered by just 1 other, do a direct calc
                    overPlant = plant.overlapList[0]
                    areaCovered = geometry_utils.areaOverlappingCircles(
                        plant.x, plant.y, plant.r, overPlant.x, overPlant.y,
                        overPlant.r)
                    areaCovered = areaCovered - (areaCovered *
                                                 plantTwo.canopyTransmittance)
                    thePlantAreaExposed = thePlantAreaTotal - areaCovered
                    #plant.areaCovered=areaCovered
                    fractionExposed = thePlantAreaExposed / thePlantAreaTotal
                    #fractionExposed=fractionExposed*theGarden.lightIntensity #try and take into account overall world light intensity
                    fractionExposed = fractionExposed * theRegion.lightIntensity  #try and take into account overall world light intensity
                    thePlantAreaExposed = thePlantAreaTotal * fractionExposed
                    plant.areaCovered = thePlantAreaTotal - thePlantAreaExposed
                elif len(plant.overlapList
                         ) > 1:  ###if you are covered by 2, use monte-carlo
                    numbPhotons = int(thePlantAreaTotal)
                    if numbPhotons == 0:
                        numbPhotons = 1
                    numbPhotons = numbPhotons * 100
                    if numbPhotons > 750:  #we don't need monster numbers
                        numbPhotons = 750
                    hitCount = 0
                    for photon in range(numbPhotons):
                        #####consider moving this to geometry_utils
                        ###pick uniformly distributed point in a circle
                        randr = (random.random() * (plant.r - 0)
                                 ) + 0  #random between 0 and the radius
                        twoPi = math.pi * 2
                        randAngle = random.random() * twoPi
                        #randr =math.sqrt(randr) #if you don't use sqrt, you get clustering in the center
                        randr = randr**0.5  #if you don't use sqrt, you get clustering in the center
                        photonX = (randr * math.cos(randAngle)) + plant.x
                        photonY = (randr * math.sin(randAngle)) + plant.y
                        ######
                        for overPlant in plant.overlapList:
                            if not photonX == "gone":
                                if geometry_utils.pointInsideCircle(
                                        overPlant.x, overPlant.y, overPlant.r,
                                        photonX, photonY):
                                    randomValue = random.random()
                                    if randomValue > overPlant.canopyTransmittance:
                                        ###these points are where the overlap is
                                        photonX = "gone"
                                    break
                        if not photonX == "gone":
                            hitCount = hitCount + 1
                    if numbPhotons == 0:
                        fractionExposed = 0.0
                    else:
                        fractionExposed = float(hitCount) / float(numbPhotons)
                    #fractionExposed=fractionExposed*theGarden.lightIntensity #try and take into account overall world light intensity
                    fractionExposed = fractionExposed * theRegion.lightIntensity  #try and take into account overall world light intensity
                    thePlantAreaExposed = thePlantAreaTotal * fractionExposed
                    plant.areaCovered = thePlantAreaTotal - thePlantAreaExposed
            else:  #if you are not covered at all
                thePlantAreaTotal = geometry_utils.areaCircle(plant.r)
                fractionExposed = 1.0
                #fractionExposed=fractionExposed*theGarden.lightIntensity #try and take into account overall world light intensity
                fractionExposed = fractionExposed * theRegion.lightIntensity  #try and take into account overall world light intensity
                thePlantAreaExposed = thePlantAreaTotal * fractionExposed
                plant.areaCovered = thePlantAreaTotal - thePlantAreaExposed
            ###now change the colour accordingly
            plant.colourLeaf[2] = fractionExposed
        if theGarden.showProgressBar:
            i = i + 1
            theProgressBar.update(i)
Пример #4
0
def main():
	#why do only these need to be reminded they are global?
	global simulationFile
	global theWorldSize
	global startPopulationSize
	global seedPlacement
	global sList
	
	#Import Psyco if possible
	try:
		import psyco
		psyco.log()
		psyco.full()
	except ImportError:
		pass
		
	CFDGtext=""
	
	####################################
	###experiments in importing events
	import yaml
	if os.path.exists(eventFile):
		print "***Loading event file: %s***" % (eventFile)
		theFile=open(eventFile)
		eventData=yaml.load(theFile)
		theFile.close
		eventTimes=eventData.keys()
	else:
		eventTimes=[]
	#####################################
	
	if debug==1: print "***debug is on***"

	theGarden= worldBasics.garden()
	theGarden.platonicSeeds={}
	theGarden.theRegions=[]

	
	####

	#########Check for multiple species. If none, use default
	fileList=os.listdir("Species")
	ymlList=[]
	pythonList=[]
	useDefaultYml=True
	print "***Checking for species...***"
	for file in fileList:
		theExtension=os.path.splitext(file)[1]
		if theExtension==".yml":
			#add this file to the list of yaml files
			ymlList.append(file)
			useDefaultYml=False
		elif theExtension==".py":
			#this might be override info for a species
			#add this file to the list of species python files
			#this isn't implemented
			pythonList.append(file)
	fileList=[]
	##########

	if resumeSim==1 and not simulationFile=="":
		simulationFile=open(simulationFile, 'r')
		theGarden=pickle.load(simulationFile)
		simulationFile.close()
		theWorldSize=theGarden.theWorldSize
		print "***Resuming Simulation: %s as %s***" % (theGarden.name, simulationName)
		theGarden.name=simulationName
		startPopulationSize=theGarden.numbPlants
		##this should reload species data.
		###Important if you want to compare runs
		if reloadSpeciesData==1:
			###fileLoc will be different for each species eventually
			fileLoc="SERA_Data/Default_species.txt"
			for item in theGarden.soil:
				item.importPrefs(fileLoc)
	else:
		theGarden.makePlatonicSeedDict(ymlList, Species1)
		print "***Species loaded.***"
		theGarden.name=simulationName
		theGarden.theWorldSize=theWorldSize
		print "***Beginning Simulation: %s***" % (simulationName)

	theGarden.showProgressBar=showProgressBar

	print "     World size: %ix%i" % (theWorldSize, theWorldSize)
	print "     Maximum population size will be: %i" % (maxPopulation)
	print "              and"
	print "     Running simulation for %i cycles" % (maxCycles)
	print "              (whichever comes first)"
	print "     Starting population size: %i" % (startPopulationSize)
	if theGarden.carbonAllocationMethod==0:
		print "     Plants will allocate carbon to stem and leaf using methods defined by the species."
	else:
		print "     All plants will allocate carbon to stem and leaf using method %i" % (theGarden.carbonAllocationMethod)

	print ""
	if produceGraphics==1: 
		print "     Graphical output will be produced."
		if theView==1:
			print "       Graphical output will be a bottom-up view."
		elif theView==2:
			print "       Graphical output will be a top-down view."
		elif theView==3:
			print "       Graphical output will be a side-view."
		elif theView==12:
			print "       Graphical output will be a combination bottom-up and top-down view."
		elif theView==21:
			print "       Graphical output will be a combination top-down and bottom-up view."
		elif theView==23:
			print "       Graphical output will be a combined top-down and side view."
		elif theView==13:
			print "       Graphical output will be a combined bottom-up and side view."
		elif theView==123:
			print "       Graphical output will be a combination bottom-up, top-down and side view."
		if produceVideo==1:
			print "       Graphical output will include a %s frame/second video." % (framesPerSecond)
	###I think this is where to start the times to repeat bit
	for x in range(timesToRepeat):
		###make necessary directories
		outputDirectory="Output-"+simulationName+"/"
		outputDirectory=makeDirectory(outputDirectory)
		if produceGraphics==1 or produceDXFGraphics==1:
			outputGraphicsDirectory = outputDirectory +"Graphics/"
			makeDirectory(outputGraphicsDirectory)
			if produceDXFGraphics==1:
				outputDXFGraphicsDirectory = outputGraphicsDirectory +"DXF/"
				makeDirectory(outputDXFGraphicsDirectory)
			####SUPER IMPORTANT!!!!
			####DON'T USE SPACES IN DIR NAMES!
			####COMMAND LINES HATE THAT SHIT
			if theView==1:
				outputGraphicsDirectory = outputGraphicsDirectory +"bottom-up/"
				makeDirectory(outputGraphicsDirectory)
			elif theView==2:
				outputGraphicsDirectory = outputGraphicsDirectory +"top-down/"
				makeDirectory(outputGraphicsDirectory)
			elif theView==3:
				outputGraphicsDirectory = outputGraphicsDirectory +"side/"
				makeDirectory(outputGraphicsDirectory)
			elif theView==12:
				outputGraphicsDirectory = outputGraphicsDirectory +"combined-bottom-top/"
				makeDirectory(outputGraphicsDirectory)
			elif theView==21:
				outputGraphicsDirectory = outputGraphicsDirectory +"combined-top-bottom/"
				makeDirectory(outputGraphicsDirectory)
			elif theView==13:
				outputGraphicsDirectory = outputGraphicsDirectory +"combined-bottom-side/"
				makeDirectory(outputGraphicsDirectory)
			elif theView==23:
				outputGraphicsDirectory = outputGraphicsDirectory +"combined-top-side/"
				makeDirectory(outputGraphicsDirectory)
			elif theView==123:
				outputGraphicsDirectory = outputGraphicsDirectory +"combined-bottom-top-side/"
				makeDirectory(outputGraphicsDirectory)
		if not archive=="n":
			saveDirectory = outputDirectory+"Save_points/"
			makeDirectory(saveDirectory)
		if not saveData=="n":
			dataDirectory = outputDirectory+"Simulation_data/"
			makeDirectory(dataDirectory)
			makeDirectory(dataDirectory+"Seeds/")
			makeDirectory(dataDirectory+"Plants/")
			makeDirectory(dataDirectory+"Corpses/")


		
		if resumeSim==0:
			#2008.11.06 Moved a huge block of code related to placing seeds to vworldr.py
			theGarden.placeSeed(seedPlacement, sList, startPopulationSize, useDefaultYml, ymlList)
		if produceGraphics and CFDGtext=="": 
			CFDGtext=outputGraphics.initCFDGText(theGarden, theView, percentTimeStamp, 50.0)	
		#######
		cycleNumber=0
		print "\n***Running simulation.***"
		if not showProgressBar and not runningInNodeBox:
			theProgressBar= progressBarClass.progressbarClass(maxCycles,"*") #why -1? because index 0. So if total=100, 0-99.
		#print "Cycle, plant age, Mass Stem, Mass Leaf, # Seeds, Mass all Seeds, Radius Stem, Radius Leaf, Height Plant, areaPhoto, new mass"
		while (theGarden.numbPlants<=maxPopulation and cycleNumber<=maxCycles) and (theGarden.numbPlants+theGarden.numbSeeds)>0:
			###################################################################################
			####Experimental scripting event stuff                                            #
			if cycleNumber in eventTimes:                                                     # 
				for aItem in eventData[cycleNumber]:                                          #
					for aKey in aItem.keys():                                                 #
						if aKey=="Garden":                                                    #
							if debug==1: print "debug: A garden related event has been triggered."   #
							theDict=aItem[aKey][0]                                            #
							gardenAttrs=theDict.keys()                                        #
							for theGardenAttr in gardenAttrs:                                 #
								setattr(theGarden, theGardenAttr, theDict[theGardenAttr])     #
							gardenAttrs=""	
						elif aKey=="Killzone" or aKey=="Safezone":
							if debug==1: print "debug: generation of a zone event has been triggered."
							theDict=aItem[aKey][0]                                           #
							zoneAttrs=theDict.keys()
							zoneX=float(theDict['x'])
							zoneY=float(theDict['y'])
							zoneSize=float(theDict['size'])
							zoneShape=theDict['shape']
							if zoneShape not in ['circle','square']:
								print "***WARNING: improper zone shape defined. Defaulting to square.***"
								zoneShape='square'
							zoneTarget=theDict['target']
							if zoneTarget not in ['all','plants','seeds']:
								print "***WARNING: improper zone target defined. Defaulting to all.***"
								zoneTarget='all'
							if zoneShape=='circle':
								killThese=[]
								for theObject in theGarden.soil:
									if theObject.isSeed:
										r=theObject.radiusSeed
									else:
										r=theObject.radiusStem
									theResult=geometry_utils.checkOverlap(theObject.x, theObject.y, r, zoneX, zoneY, zoneSize)
									if theResult>0 and aKey=='Killzone':
										if zoneTarget=='all' or (theObject.isSeed and zoneTarget=='seeds') or (not theObject.isSeed and zoneTarget=='plants'):
											killThese.append(theObject)	
									elif aKey=='Safezone':
										if theResult==0:
											killThese.append(theObject)
										elif theResult>0:
											if (theObject.isSeed and zoneTarget=='plants') or (not theObject.isSeed and zoneTarget=='seeds'):
												killThese.append(theObject)	
																				
								for theObject in killThese:
									theObject.causeOfDeath="zone"
									theGarden.kill(theObject)
						elif aKey=="Seed":
							if debug==1: print "debug: A seeding related event has been triggered."   #
							theDict=aItem[aKey][0]                                            #
							seedingInfo=theDict.keys()                                        #
							for infoItem in seedingInfo:
								if infoItem=="number" and not seedPlacement=="fromFile": startPopulationSize=theDict[infoItem]
								if infoItem=="species": 
									sList=theDict[infoItem]
									if sList=="random": sList=[]
								if infoItem=="placement": seedPlacement=theDict[infoItem]
								if seedPlacement=="hexagon": seedPlacement="hex" #just make sure it is consistant
								if os.path.isfile(seedPlacement):
									theFile=open(seedPlacement)
									try:
										sList=theFile.readlines()
									finally:
										theFile.close()
									sList=checkSeedPlacementList(sList)
									startPopulationSize=len(sList)
									seedPlacement="fromFile"
							if not seedPlacement=="fromFile" and not sList==[]:
								newList=[]
								for j in range(startPopulationSize):
									newList.append(sList)
								#print sList
								sList=newList
								newList=[]
								#print sList
							theGarden.placeSeed(seedPlacement, sList, startPopulationSize, useDefaultYml, ymlList)
						elif aKey=="Region":
							if debug: print "debug: Region event detected..."
							theDict=aItem[aKey][0] 
							regionAttrs=theDict.keys()
							theRegionName=str(theDict['name'])
							if debug: print "debug: Region %s event detected." % (theRegionName)
							regionNames=[]
							for i in theGarden.theRegions:
								regionNames.append(i.name)
							if theRegionName in regionNames:
								for j in theGarden.theRegions:
									if j.name==theRegionName:
										theRegion=j
										break
								for aAttr in regionAttrs:
									if not getattr(theRegion,aAttr,"does not exist")==theDict[aAttr]:
										if debug: print "debug: Region %s has had a change in one or more attributes." % (theRegionName)
										updatePlants=True
										break
								#if (not theRegion.size==theDict["size"]) or (not theRegion.x==theDict["x"]) or (not theRegion.y==theDict["y"]) or (not theRegion.shape==theDict["shape"]):
								#	if debug:print "debug: a region has changed shape, size or location"
								#	updatePlants=True
								##now just read in the values#
								if debug: print "debug: Updating attributes for region %s." % (theRegionName)
								for theRegionAttr in regionAttrs:                                 #
									setattr(theRegion, theRegionAttr, theDict[theRegionAttr])     #
								if updatePlants:
									if debug:print "debug: updating plants with changed region info"
									for aPlant in theGarden.soil:
										plantX=aPlant.x
										plantY=aPlant.y
										if theRegion.shape=='square':
											inSubregion=geometry_utils.pointInsideSquare(theRegion.x, theRegion.y, theRegion.size, plantX, plantY)
										elif theRegion.shape=='circle':
											#size needs to be radius but region defines diameter
											inSubregion=geometry_utils.pointInsideCircle(theRegion.x, theRegion.y, theRegion.size/2.0, plantX, plantY)
										if inSubregion:
											if not theRegion in aPlant.subregion:
												aPlant.subregion.append(theRegion)
												#print "\nX: %f  Y: %f  In region: %s" % (plantX, plantY, newRegion)

								#print theRegion.size
							else:
								newRegion=worldBasics.garden()
								newRegion.name=theRegionName
								###these are default values###
								newRegion.x=0.0              #
								newRegion.y=0.0              #
								newRegion.worldSize=1.0      #
								newRegion.shape='square'     #
								##############################
								##now just read in the values#
								if debug: print "debug: Making attributes for region"
								for theRegionAttr in regionAttrs:                                 #
									setattr(newRegion, theRegionAttr, theDict[theRegionAttr])     #
								theGarden.theRegions.append(newRegion)
								for aPlant in theGarden.soil:
									plantX=aPlant.x
									plantY=aPlant.y
									if newRegion.shape=='square':
										inSubregion=geometry_utils.pointInsideSquare(newRegion.x, newRegion.y, newRegion.size, plantX, plantY)
									elif newRegion.shape=='circle':
										#size needs to be radius but region defines diameter
										inSubregion=geometry_utils.pointInsideCircle(newRegion.x, newRegion.y, newRegion.size/2.0, plantX, plantY)
									if inSubregion:
										if not newRegion in aPlant.subregion:
											aPlant.subregion.append(newRegion)
											#print "\nX: %f  Y: %f  In region: %s" % (plantX, plantY, newRegion)
										
								newRegion=""
							
							
						theDict=[]#just clear this to free up the memory
			###################################################################################
			theGarden.cycleNumber=cycleNumber
			if not showProgressBar and not runningInNodeBox:
					theProgressBar.update(cycleNumber)
			#print "%i, %i, %f, %f, %i, %f, %f, %f, %f, %f, %f" % (cycleNumber-1, theGarden.soil[0].age, theGarden.soil[0].massStem, theGarden.soil[0].massLeaf, len(theGarden.soil[0].seedList), theGarden.soil[0].massSeedsTotal, theGarden.soil[0].radiusStem, theGarden.soil[0].radiusLeaf, theGarden.soil[0].heightStem+theGarden.soil[0].heightLeafMax, theGarden.soil[0].areaPhotosynthesis, theGarden.soil[0].massFixed)

			###START OF SEEING CHANGES TO SPECIES FOLDER
			#########Check for multiple species. If none, use default
			fileList=os.listdir("Species")
			#print fileList
			#ymlList=[]
			#print "***Checking for species...***"
			#for file in fileList:
			#	theExtension=os.path.splitext(file)[1]
			#	if theExtension==".yml":
			#		#add this file to the list of yaml files
			#		ymlList.append(file)
			#		useDefaultYml=False
			#fileList=[]
			##########





			if debug==1: print "number of plants: "+str(theGarden.numbPlants)
			if debug==1: print "number of seeds: "+str(theGarden.numbSeeds)
			
			#generate graphics if requested
			if produceDXFGraphics:
				theData=vdxfGraphics.makeDXF(theGarden)
				theFileName= simulationName+str(cycleNumber)
				vdxfGraphics.writeDXF(outputDXFGraphicsDirectory, theFileName, theData)
			if produceGraphics:
				theData=outputGraphics.makeCFDG(theView, CFDGtext, theGarden, cycleNumber)
				if webOutput==0:
					if theView==1:
						cfdgFileName= simulationName +"-bottom-"+str(cycleNumber)
					elif theView==2:
						cfdgFileName= simulationName +"-top-"+str(cycleNumber)
					elif theView==3:
						cfdgFileName= simulationName +"-side-"+str(cycleNumber)
					elif theView==12:
						cfdgFileName= simulationName +"-bottom-top-"+str(cycleNumber)
					elif theView==21:
						cfdgFileName= simulationName +"-top-bottom-"+str(cycleNumber)
					elif theView==13:
						cfdgFileName= simulationName +"-bottom-side-"+str(cycleNumber)
					elif theView==23:
						cfdgFileName= simulationName +"-top-side-"+str(cycleNumber)
					elif theView==123:
						cfdgFileName= simulationName +"-bottom-top-side"+str(cycleNumber)
					outputGraphics.writeCFDG(outputGraphicsDirectory, cfdgFileName, theData)
				else:
					cfdgFileName= simulationName
					outputGraphics.writeCFDG(outputGraphicsDirectory, cfdgFileName, theData)
					outputGraphics.outputPNGs(outputGraphicsDirectory, webDirectory)
					#outputGraphics.deleteCFDGFiles(outputGraphicsDirectory)

			###go through the soil list and germinate seed or grow plant
			if theGarden.showProgressBar:
				print"***Allowing plants a turn to grow***"
				theProgressBar= progressBarClass.progressbarClass(len(theGarden.soil),"*")
				theBar=0
			for obj in theGarden.soil[:]:
				if obj.isSeed:
					obj.germinate(theGarden)
				else:
					obj.growPlant(theGarden)
				if theGarden.showProgressBar:
					theBar=theBar+1
					theProgressBar.update(theBar)

			###deal with violaters of basic physics
			theGarden.causeRandomDeath()
			theGarden.checkSenescence()
			theGarden.removeOffWorldViolaters()
			theGarden.removeEulerGreenhillViolaters()
			theGarden.removeOverlaps()
			

			###sort the garden.soil by height of the plants.Ordered shortest to tallest
			theGarden.soil= list_utils.sort_by_attr(theGarden.soil, "heightStem")
			###flip the list so it's ordered tallest to shortest
			theGarden.soil.reverse()

			###work out shading
			worldBasics.determineShade(theGarden)

			###Calculate the amount of carbon each plant will have to start the next turn
			if theGarden.showProgressBar:
				print "***Calculating new mass from photosynthesis***"
				theProgressBar= progressBarClass.progressbarClass(len(theGarden.soil),"*")
				i=0
			for plant in theGarden.soil[:]:
				if plant.isSeed==False:
					plant.massFixed=plant.calcNewMassFromLeaf(theGarden)
					if plant.massFixed==-1.0:
						plant.causeOfDeath="lack of light"
						theGarden.kill(plant)
					else:
						plant.massFixedRecord.append(plant.massFixed)
						while len(plant.massFixedRecord)>plant.numYearsGrowthMemory:
							plant.massFixedRecord.pop(0)
				if theGarden.showProgressBar:
					i=i+1
					theProgressBar.update(i)




			if archive=="a":
				fileName=simulationName+'-'+str(cycleNumber)+'.pickle'
				saveSimulationPoint(saveDirectory, fileName, theGarden)

			if saveData=="a":
				fileName=simulationName+'-'+str(cycleNumber)+'.csv'
				saveDataPoint(dataDirectory, fileName, theGarden)
			#print theGarden.deathNote
			theGarden.deathNote=[]		
			
			cycleNumber= cycleNumber+1

			###pause if you're making web graphic
			#if webOutput==1:
			#	time.sleep(5)

		if archive=="e":
			fileName=simulationName+'-'+str(cycleNumber)+'.pickle'
			saveSimulationPoint(saveDirectory, fileName, theGarden)

		if saveData=="e":
				fileName=simulationName+'-'+str(cycleNumber)+'.csv'
				saveDataPoint(dataDirectory, fileName, theGarden)
				
							
		if produceStats:
			#print dataDirectory
			theArgument="-n '%s' -fs" % (dataDirectory+"Seeds/")
			print "***sending to Extract: %s" % (theArgument)
			os.system("python SERA_Data/vextract.py %s" % (theArgument))
			theArgument="-n '%s' -fs" % (dataDirectory+"Plants/")
			print "***sending to Extract: %s" % (theArgument)
			os.system("python SERA_Data/vextract.py %s" % (theArgument))
			theArgument="-n '%s' -fs" % (dataDirectory+"Corpses/")
			print "***sending to Extract: %s" % (theArgument)
			os.system("python SERA_Data/vextract.py %s" % (theArgument))


		###final graphics calls
		if produceGraphics==1 and webOutput==0: 
			print "Producing PNG files..."
			outputGraphics.outputPNGs(outputGraphicsDirectory, outputGraphicsDirectory)
		if produceGraphics==1 and deleteCfdgFiles==1 and webOutput==0:
			print "Deleting .cfdg files..."
			outputGraphics.deleteCFDGFiles(outputGraphicsDirectory)

		###only try and make a video if it is wanted and if pngs were made
		if produceVideo and produceGraphics and webOutput==0:
			print "Producing MOV file..." 
			outputGraphics.outputMOV(outputGraphicsDirectory, simulationName, framesPerSecond)
		print "*****Simulation Complete*****"
		#print theGarden.deathNote
		#clear the values
		theGarden.soil=[]
		theGarden.deathNote=[]
		theGarden.cycleNumber=0
		for aRegion in theGarden.theRegions:
			aRegion.size=0.0
Пример #5
0
#!/usr/bin/env python
Пример #6
0
def determineShade(theGarden):
	if theGarden.showProgressBar:
		print "***Generating lists of overlapping plants. This could take a while...***"
		theProgressBar= progressBarClass.progressbarClass(len(theGarden.soil),"*")
		i=0
	###populate the overlap list
	theIndex=0
	for plantOne in theGarden.soil:
		if plantOne.isSeed==0 or (plantOne.isSeed and plantOne.minimumLightForGermination>0.0):
			plantOne.overlapList=[]
			plantOne.areaCovered=0.0
			plantOne.colourLeaf[2]= 1.0
			###the following might be able to be used to speed things up
			#for overlappingItem in plantOne.overlapList:
			#	if not overlappingItem in theGarden.soil or not overlappingItem.z>plantOne.z: 
			#		###make sure the overlapping item is still alive
			#		###and that overlapping item is still taller
			#		plantOne.overlapList.remove(overlappingItem)
			###need to insert something so tallest plant looks at all the other plants of exactly the same size
			###if they are the same size and overlapping, they need to share shading
			for plantTwo in range(theIndex):
				plantTwo=theGarden.soil[plantTwo]
				###is plant two overlapping you?
				overlapStatus=geometry_utils.checkOverlap(plantOne.x, plantOne.y, plantOne.r, plantTwo.x, plantTwo.y, plantTwo.r)
				if overlapStatus>0:
					if not plantTwo in plantOne.overlapList:
						if not plantTwo==plantOne:
							plantOne.overlapList.append(plantTwo)
			###sort the overlap list by height of the plants. Ordered shortest to tallest
			plantOne.overlapList = list_utils.sort_by_attr(plantOne.overlapList, "heightStem")
			###flip the list so it's ordered tallest to shortest
			plantOne.overlapList.reverse()
			theIndex=theIndex+1
			if theGarden.showProgressBar:
				i=i+1
				theProgressBar.update(i)

	###take the overlap list and start dropping photons onto it.
	if theGarden.showProgressBar:
		print "***Determining shading. This could take a while...***"
		theProgressBar= progressBarClass.progressbarClass(len(theGarden.soil),"*")
		i=0
	for plant in theGarden.soil:
		if plant.isSeed==0 or (plant.isSeed and plant.minimumLightForGermination>0.0):
			fractionExposed=1.0
			if len(plant.subregion)>0:
				theRegion=plant.subregion[-1]
			else:
				theRegion=theGarden
			if len(plant.overlapList)>0:
				thePlantAreaTotal=geometry_utils.areaCircle(plant.r)
				if thePlantAreaTotal==0.0:
					print "name:%s r:%f isSeed:%i massSeed:%f massTotal:%f"%(plant.name, plant.r, plant.isSeed, plant.massSeed, plant.massTotal)
				if len(plant.overlapList)==1: ###if you are covered by just 1 other, do a direct calc
					overPlant =plant.overlapList[0]
					areaCovered=geometry_utils.areaOverlappingCircles(plant.x, plant.y, plant.r, overPlant.x, overPlant.y, overPlant.r)
					areaCovered=areaCovered-(areaCovered*plantTwo.canopyTransmittance)
					thePlantAreaExposed=thePlantAreaTotal-areaCovered
					#plant.areaCovered=areaCovered
					fractionExposed= thePlantAreaExposed/thePlantAreaTotal
					#fractionExposed=fractionExposed*theGarden.lightIntensity #try and take into account overall world light intensity
					fractionExposed=fractionExposed*theRegion.lightIntensity #try and take into account overall world light intensity
					thePlantAreaExposed= thePlantAreaTotal*fractionExposed
					plant.areaCovered=thePlantAreaTotal-thePlantAreaExposed
				elif len(plant.overlapList)>1: ###if you are covered by 2, use monte-carlo
					numbPhotons=int(thePlantAreaTotal)
					if numbPhotons==0:
						numbPhotons=1
					numbPhotons= numbPhotons*100
					if numbPhotons>750: #we don't need monster numbers
						numbPhotons=750
					hitCount=0
					for photon in range(numbPhotons):
						#####consider moving this to geometry_utils
						###pick uniformly distributed point in a circle
						randr=(random.random()*(plant.r-0))+0 #random between 0 and the radius
						twoPi=math.pi*2
						randAngle=random.random()*twoPi
						#randr =math.sqrt(randr) #if you don't use sqrt, you get clustering in the center
						randr =randr**0.5 #if you don't use sqrt, you get clustering in the center
						photonX = (randr*math.cos(randAngle))+plant.x
						photonY = (randr*math.sin(randAngle))+plant.y
						######
						for overPlant in plant.overlapList:
							if not photonX=="gone":
								if geometry_utils.pointInsideCircle(overPlant.x, overPlant.y, overPlant.r, photonX, photonY):
									randomValue=random.random()
									if randomValue > overPlant.canopyTransmittance:
										###these points are where the overlap is
										photonX="gone"
									break
						if not photonX=="gone":
							hitCount=hitCount+1
					if numbPhotons ==0:
						fractionExposed=0.0
					else:
						fractionExposed=float(hitCount)/float(numbPhotons)
					#fractionExposed=fractionExposed*theGarden.lightIntensity #try and take into account overall world light intensity
					fractionExposed=fractionExposed*theRegion.lightIntensity #try and take into account overall world light intensity
					thePlantAreaExposed= thePlantAreaTotal*fractionExposed
					plant.areaCovered=thePlantAreaTotal-thePlantAreaExposed
			else: #if you are not covered at all
				thePlantAreaTotal=geometry_utils.areaCircle(plant.r)
				fractionExposed=1.0
				#fractionExposed=fractionExposed*theGarden.lightIntensity #try and take into account overall world light intensity
				fractionExposed=fractionExposed*theRegion.lightIntensity #try and take into account overall world light intensity
				thePlantAreaExposed= thePlantAreaTotal*fractionExposed
				plant.areaCovered=thePlantAreaTotal-thePlantAreaExposed
			###now change the colour accordingly
			plant.colourLeaf[2]= fractionExposed
		if theGarden.showProgressBar:
			i=i+1
			theProgressBar.update(i)