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
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
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)
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
#!/usr/bin/env python
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)