diff --git a/Data Extracter.py b/Data Extracter.py deleted file mode 100644 index 04e34c9..0000000 --- a/Data Extracter.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python -"""This file is part of Vida. --------------------------- -Copyright 2009, Sean T. Hammond - -Vida is experimental in nature and is made available as a research courtesy "AS IS," but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -You should have received a copy of academic software agreement along with Vida. If not, see . -""" - -import cherrypy -import webbrowser -import os -import os.path - - -class HelloWorld(object): - @cherrypy.expose - def index(self): - #return "Hello World!" - return cherrypy.tools.staticdir.root - - @cherrypy.expose - def extract(self): - return open('Vida_Data/GUI/prototypeExtractor.html').read() - - @cherrypy.expose - def listdir(self, directory='.'): - print "**********" - print directory - print "**********" - ###check and see if what is returned is a file of a directory - if not os.path.isdir(directory): - selectedExtension=os.path.splitext(directory)[1] - directory=os.path.dirname(directory) - rawFileList = os.listdir(directory) - ###show only files with the desired suffixes - okFileSuffix=[".csv", ".cfdg", ".png", ".pickle"] - theFileList=[] - for file in rawFileList: - theExtension=os.path.splitext(file)[1] - if theExtension in okFileSuffix and theExtension==selectedExtension: - theFileList.append(file) - rawFileList=[] - if len(theFileList)==0: - theFileList=["No compatible file found."] - return '\n'.join( ['' % i for i in theFileList] ) - - @cherrypy.expose - def submitCommands(self, filePath="", fileSuffix="", selectedAll=0, n="", c=0, g=0, v=0, fa=0, fs=0 ): - if not os.path.isdir(filePath): - theDirectory=os.path.dirname(filePath)+"/" - if type(n)==str: - n=theDirectory+n - if type(n)==list: - theIndex=0 - for aFile in n: - n[theIndex]=theDirectory+n[theIndex] - theIndex=theIndex+1 - n=",".join(n) - theArgument="-n \"%s\"" - if c==1: theArgument=theArgument+" -c " - if g=="1": theArgument=theArgument+" -g " - if v=="1": - if selectedAll=="0": - theArgument=theArgument+" -v " - else: - theArgument=theArgument+" -va " - if fa=="1": theArgument=theArgument+" -fa " - if fs=="1": - if selectedAll=="0": - theArgument=theArgument+" -fs " - else: - theArgument=theArgument+" -fsa " - print "" - theArgument=theArgument % (n) - print "from Extract: %s" % (theArgument) - os.system("python Vida_Data/vextract.py %s" % (theArgument)) - - - - -theUrlBase="localhost" -thePort=8080 -curdir = os.path.join(os.getcwd(), "Vida_Data/GUI") -conf = { - '/interfaceGraphics': { - 'tools.staticdir.on': True, - 'tools.staticdir.dir': 'interfaceGraphics', - 'tools.staticdir.root': curdir, - }, - '/': { - 'tools.staticdir.on': True, - 'tools.staticdir.dir': '', - 'tools.staticdir.root': curdir, - }, -} - -cherrypy.tree.mount(HelloWorld(), config=conf) -#something changed in the latest cherrypy build -#cherrypy.engine.start(blocking=False) -cherrypy.engine.start() -cherrypy.server.socketPort=thePort -cherrypy.server.quickstart() -theUrl="http://%s:%s/extract" % (theUrlBase, thePort) -webbrowser.open(theUrl) -cherrypy.engine.block() \ No newline at end of file diff --git a/Readme_Files/Vida HOWTO.txt b/Readme_Files/Vida HOWTO.txt index c7650b5..94fba00 100644 --- a/Readme_Files/Vida HOWTO.txt +++ b/Readme_Files/Vida HOWTO.txt @@ -55,11 +55,11 @@ OPTIONS SUMMARY -v [] produce a Quicktime video, with an optional frames/second value(Macintosh only) -r reload a previously saved simulation - -rl reload a previously saved simulation & reload the Vida World Preferences file + -rl reload a previously saved simulation & reload the Vida World Preferences file -e load an event file named -a save a simulation state -f save statistical data - -x number of times to rereun the simulation + -x number of times to rerun the simulation Seeding options: Vida accepts a number of ways of placing seeds in a simulation @@ -143,9 +143,9 @@ BASIC USAGE is identical to example 2 with the exception that files containing information on each object in the simulation will be saved to a folder named "Simulation_data" within the "Output-4example" folder. Since each file can be very large, objects are divided into seeds, plants and corpses, and are saved to appropriate subfolders. When one uses the -f a command, Vida takes the additional step to generate statistical summary files from the individual data files. - Vida saves the data for the final iteration a simulation by default. This is the equivilant to using the command -fe. If one didn't want to save any data files, one would use the -f n command. + Vida saves the data for the final iteration a simulation by default. This is the equivalent to using the command -f e. If one didn't want to save any data files, one would use the -f n command. - In addition to saving graphical files, data files, and statistical files, Vida can save the state of iterations so that one could resume a simulation from a known point. The default setting for Vida is to save the final iteration of a simulation. This is the equivilant to saying: + In addition to saving graphical files, data files, and statistical files, Vida can save the state of iterations so that one could resume a simulation from a known point. The default setting for Vida is to save the final iteration of a simulation. This is the equivalent to saying: python Vida.py -n 5example -w 100 -s 10 -t 200 -m 550 -g bs -v 10 -a e diff --git a/Vida.py b/Vida.py index 1e17c8e..28b974c 100644 --- a/Vida.py +++ b/Vida.py @@ -17,11 +17,8 @@ import glob import sys import argparse -if (sys.version_info.major)==2: - import ConfigParser -else: - import configparser as ConfigParser - import pathlib +import configparser +import pathlib import copy @@ -29,53 +26,41 @@ import pickle ###append the path to basic data files sys.path.append("Vida_Data") -import vworldr as worldBasics -import vplantr as defaultSpecies -import vgraphics as outputGraphics -import list_utils as list_utils -import geometry_utils as geometry_utils +from Vida_Data import vworldr as worldBasics +from Vida_Data import vplantr as defaultSpecies +from Vida_Data import vgraphics as outputGraphics +from Vida_Data import list_utils +from Vida_Data import geometry_utils +from Vida_Data import vextract as vex from dxfwrite import DXFEngine as dxf #pip install dxfwrite #https://pypi.org/project/dxfwrite/ import yaml #pip install PyYAML #https://pypi.org/project/PyYAML/ -import progressBarClass +from Vida_Data import progressBarClass ###append the path to where species are sys.path.append("Species") sList=[] theCLArgs="" -########################################## -#Import the options# -try: - theConfig=ConfigParser.RawConfigParser() - theConfig.optionxform = str - theConfig.read('Vida.ini') - theConfigSection='Vida Options' -except ConfigParser.MissingSectionHeaderError: - print("Warning: Invalid config file, no [%s] section.") % (theConfigSection) - raise - theDefaults={} -for i in theConfig.items(theConfigSection): +for i in vex.theConfig.items(vex.theConfigSection): theItem=i[0] try: - theValue=theConfig.getint(theConfigSection, theItem) + theValue=vex.theConfig.getint(vex.theConfigSection, theItem) except: try: - theValue=theConfig.getboolean(theConfigSection, theItem) + theValue=vex.theConfig.getboolean(vex.theConfigSection, theItem) except: try: - theValue=theConfig.getfloat(theConfigSection, theItem) + theValue=vex.theConfig.getfloat(vex.theConfigSection, theItem) except: try: - theValue=theConfig.get(theConfigSection, theItem) + theValue=vex.theConfig.get(vex.theConfigSection, theItem) if theValue=="None": theValue=None except: print("what the...?") theDefaults[theItem]=theValue -#print theDefaults -#print "#################" class parseAction(argparse.Action): def __call__(self,parser,args,theValues,option_string=None): @@ -124,7 +109,6 @@ def __call__(self,parser,args,theValues,option_string=None): class Species1(defaultSpecies.genericPlant): ###The routine in defaultSpecies.genericPlant reads in default values from .yml file def __init__(self): - ##super(type, obj) -> bound super object; requires isinstance(obj, type) super(Species1, self).__init__() @@ -132,12 +116,11 @@ def saveSimulationPoint(theDirectory, theFileName, theGarden): simulationStateFile =open(theDirectory + theFileName, 'wb') pickle.dump(theGarden, simulationStateFile) simulationStateFile.close() - #print "simulation state saved to file" def saveDataPoint (theDirectory, theFileName, theGarden): #Added "Area Canopy" at end of list #Added basal area to the outputs--STH 2019-0404 - basicHeaders="Cycle #, Plant Name, Species, Mother Plant Name, X Location, Y Location, Z Location, elevation, elevation above water,\ + theHeader="Cycle #, Plant Name, Species, Mother Plant Name, X Location, Y Location, Z Location, elevation, elevation above water,\ absHeightStem, is a seed, is mature, Age at Maturity, cycles until germination, Age, Mass of Stem, Mass of Canopy, \ # of Seeds, Mass of all Seeds, Mass Stem+Mass Canopy, Mass Total, Diameter Stem, Radius Canopy, Area covered, \ Height Stem, Maximum Thickness of a Leaf, Height of Plant, Yearly Growth Stem (kg), Yearly Growth Canopy (kg), \ @@ -151,56 +134,45 @@ def saveDataPoint (theDirectory, theFileName, theGarden): allometryHeaders="B1 in Ms=B1*(Mt^a1), a1 in Ms=B1*(Mt^a1), B2 in Mlyoung=B2*(Ms^a2), a2 in Mlyoung=B2*(Ms^a2), B3 in Mlmature=B3*(Ms^a3), a3 in Mlmature=B3*(Ms^a3), B4 in Ds=B4*(Ms^a4), a4 in Ds=B4*(Ms^a4), B5 in Hs=[B5*(Ds^a5)]-B6, a5 in [B5*(Ds^a5)]-B6, B6 in Hs=[B5*(Ds^a5)]-B6, B7 in Mg=[B7*(Ml^a7)]/ area canopy 100% uncovered, a7 in Mg=[B7*(Ml^a7)]/ area canopy 100% uncovered, B8 in Mpt=B8*(Al^a8), a8 in Mpt=B8*(Al^a8)" - - #theHeader="Plant Name, Mother Plant, Species, X Location, Y Location, Mass Stem, Mass Leaf, # Seeds, Mass all Seeds, Radius Stem, Radius Leaf, Height Plant, Cause of Death \n" - theHeader= basicHeaders - thePlantList=[] - theSeedList=[] - theCorpseList=[] - thePlantList.append(theHeader) - theSeedList.append(theHeader) - theCorpseList.append(theHeader) + thePlantList, theSeedList, theCorpseList = ([] for i in range(3)) + masterList = [thePlantList, theSeedList, theCorpseList] #container so i can operate on all three lists at once + for i in masterList: + i.append(theHeader) + masterList=[] #if we let masterlist hold data during the printing, we double memory usage for plant in theGarden.soil: + theData = [theGarden.cycleNumber, plant.name, plant.nameSpecies, plant.motherPlantName, plant.x, plant.y, plant.z, plant.elevation, + (plant.elevation-theGarden.waterLevel), plant.absHeightStem, plant.isSeed, plant.isMature, plant.matureAge, plant.countToGerm, plant.age, plant.massStem, + plant.massLeaf, len(plant.seedList), plant.massSeedsTotal, plant.massStem+plant.massLeaf, plant.massTotal, plant.radiusStem*2, plant.radiusLeaf, plant.areaCovered, + plant.heightStem, plant.heightLeafMax, plant.z, plant.GMs, plant.GMl, plant.GMs+plant.GMl, 2.0*plant.GRs,plant.GHs] + if plant.age>0: - theData="%i,%s,%s,%s,%f,%f,%f,%f,%f,%f,%s,%s,%s,%i,%i,%f,%f,%i,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%s,%f,%f \n" % \ - (theGarden.cycleNumber,plant.name,plant.nameSpecies,plant.motherPlantName,plant.x,plant.y,plant.z,plant.elevation, (plant.elevation-theGarden.waterLevel), - plant.absHeightStem,plant.isSeed,plant.isMature,plant.matureAge,plant.countToGerm,plant.age,plant.massStem,plant.massLeaf, - len(plant.seedList),plant.massSeedsTotal,plant.massStem+plant.massLeaf,plant.massTotal,plant.radiusStem*2,plant.radiusLeaf,plant.areaCovered, - plant.heightStem,plant.heightLeafMax,plant.z,plant.GMs,plant.GMl, - plant.GMs+plant.GMl,2.0*plant.GRs,plant.GHs,plant.massStem/plant.age, - plant.massLeaf/plant.age,(plant.massStem+plant.massLeaf)/plant.age,(plant.radiusStem*2)/plant.age,plant.heightStem/plant.age, - "na",3.14159*plant.radiusLeaf**2-plant.areaCovered, 3.14159*plant.radiusStem**2) + #vida divide by zero if the below variables+operations are called before the above statement sorts out zeroes + theData.extend((plant.massStem/plant.age, plant.massLeaf/plant.age, (plant.massStem+plant.massLeaf)/plant.age, (plant.radiusStem*2)/plant.age, + plant.heightStem/plant.age, "na", 3.14159*plant.radiusLeaf**2-plant.areaCovered, 3.14159*plant.radiusStem**2)) + resultString = f"{theData}\n" else: - theData="%i,%s,%s,%s,%f,%f,%f,%f,%f,%f,%s,%s,%s,%i,%i,%f,%f,%i,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%s,%f,%s \n" % \ - (theGarden.cycleNumber,plant.name,plant.nameSpecies,plant.motherPlantName,plant.x,plant.y,plant.z,plant.elevation, (plant.elevation-theGarden.waterLevel), - plant.absHeightStem,plant.isSeed,plant.isMature,plant.matureAge,plant.countToGerm,plant.age,plant.massStem,plant.massLeaf, - len(plant.seedList),plant.massSeedsTotal,plant.massStem+plant.massLeaf,plant.massTotal,plant.radiusStem*2,plant.radiusLeaf,plant.areaCovered, - plant.heightStem,plant.heightLeafMax,plant.z,plant.GMs,plant.GMl, - plant.GMs+plant.GMl,2.0*plant.GRs,plant.GHs,0,0,0,0,0, - "na",0,0) + theData.extend((0, 0, 0, 0, 0, "na", 0, 0)) + resultString = f"{theData}\n" if plant.isSeed: - theSeedList.append(theData) + theSeedList.append(resultString) else: - thePlantList.append(theData) + thePlantList.append(resultString) + for plant in theGarden.deathNote: + theData = [theGarden.cycleNumber, plant.name, plant.nameSpecies, plant.motherPlantName, plant.x, plant.y, plant.z, plant.elevation, + (plant.elevation-theGarden.waterLevel), plant.absHeightStem, plant.isSeed, plant.isMature, plant.matureAge, plant.countToGerm, plant.age, plant.massStem, + plant.massLeaf, len(plant.seedList), plant.massSeedsTotal, plant.massStem+plant.massLeaf, plant.massTotal, plant.radiusStem*2, plant.radiusLeaf, plant.areaCovered, + plant.heightStem, plant.heightLeafMax, plant.z, plant.GMs, plant.GMl, plant.GMs+plant.GMl, 2.0*plant.GRs,plant.GHs] + if plant.age>0: - theData="%i,%s,%s,%s,%f,%f,%f,%f,%f,%f,%s,%s,%s,%i,%i,%f,%f,%i,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%s,%f,%f \n" % \ - (theGarden.cycleNumber,plant.name,plant.nameSpecies,plant.motherPlantName,plant.x,plant.y,plant.z,plant.elevation, (plant.elevation-theGarden.waterLevel), - plant.absHeightStem,plant.isSeed,plant.isMature,plant.matureAge,plant.countToGerm,plant.age,plant.massStem,plant.massLeaf, - len(plant.seedList),plant.massSeedsTotal,plant.massStem+plant.massLeaf,plant.massTotal,plant.radiusStem*2,plant.radiusLeaf,plant.areaCovered, - plant.heightStem,plant.heightLeafMax,plant.z,plant.GMs,plant.GMl, - plant.GMs+plant.GMl,2.0*plant.GRs,plant.GHs,plant.massStem/plant.age, - plant.massLeaf/plant.age,(plant.massStem+plant.massLeaf)/plant.age,(plant.radiusStem*2)/plant.age,plant.heightStem/plant.age, - plant.causeOfDeath,3.14159*plant.radiusLeaf**2-plant.areaCovered, 3.14159*plant.radiusStem**2) + #vida divide by zero if the below variables+operations are called before the above statement sorts out zeroes + theData.extend((plant.massStem/plant.age, plant.massLeaf/plant.age, (plant.massStem+plant.massLeaf)/plant.age, (plant.radiusStem*2)/plant.age, + plant.heightStem/plant.age, plant.causeOfDeath, 3.14159*plant.radiusLeaf**2-plant.areaCovered, 3.14159*plant.radiusStem**2)) + resultString = f"{theData}\n" else: - theData="%i,%s,%s,%s,%f,%f,%f,%f,%f,%f,%s,%s,%s,%i,%i,%f,%f,%i,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%s,%f,%s \n" % \ - (theGarden.cycleNumber,plant.name,plant.nameSpecies,plant.motherPlantName,plant.x,plant.y,plant.z,plant.elevation, (plant.elevation-theGarden.waterLevel), - plant.absHeightStem,plant.isSeed,plant.isMature,plant.matureAge,plant.countToGerm,plant.age,plant.massStem,plant.massLeaf, - len(plant.seedList),plant.massSeedsTotal,plant.massStem+plant.massLeaf,plant.massTotal,plant.radiusStem*2,plant.radiusLeaf,plant.areaCovered, - plant.heightStem,plant.heightLeafMax,plant.z,plant.GMs,plant.GMl, - plant.GMs+plant.GMl,2.0*plant.GRs,plant.GHs,0,0,0,0,0, - plant.causeOfDeath,0,0) - theCorpseList.append(theData) + theData.extend((0, 0, 0, 0, 0, plant.causeOfDeath, 0, 0)) + resultString = f"{theData}\n" + theCorpseList.append(resultString) if len(thePlantList)>1: saveDataFile =open(theDirectory+"Plants/"+ theFileName, 'w') saveDataFile.writelines(thePlantList) @@ -213,11 +185,8 @@ def saveDataPoint (theDirectory, theFileName, theGarden): saveDataFile =open(theDirectory+"Corpses/"+ theFileName, 'w') saveDataFile.writelines(theCorpseList) saveDataFile.close() - thePlantList=[] - theSeedList=[] - theCorpseList=[] - #print "simulation data saved to file - + thePlantList, theSeedList, theCorpseList = ([] for i in range(3)) #reinitialize to save memory + def makeDirectory(theDirectory): @@ -243,10 +212,6 @@ def makeDirectory(theDirectory): theDirectory=basicPath+"/" os.mkdir(theDirectory) return theDirectory - -# def dirPath(thePath): -# return thePath - def correctType(theItem): returnValue="na" @@ -263,7 +228,6 @@ def correctType(theItem): return returnValue def checkSeedPlacementList(seedPlacementList): - ################### ######STH 2022-1105 ###remove trailing "\n" seedPlacementList = [aLine.rstrip() for aLine in seedPlacementList] @@ -356,7 +320,14 @@ def main(): CFDGtext="" CFDGtextDict={} - if debug==1: print("***debug is on***") + if defaultSpecies.debug==1: + print("***debug is on***") + elif defaultSpecies.debug==0: + print("***debug is off***") + else: + print("***you have somehow bugged debug, yippee :DDD***") + + theGarden= worldBasics.garden() ##### @@ -378,21 +349,13 @@ def main(): #################################### ###experiments in importing events - #if eventFile!=None and os.path.exists(eventFile): if eventFile!=None: - #if type(eventFile)==file: print("***Loading event file: %s***" % (eventFile.name)) - #theFile=open(eventFile) - #eventData=yaml.load(theFile) eventData=yaml.load(eventFile, Loader=yaml.FullLoader) - #theFile.close eventTimes=eventData.keys() else: eventTimes=[] - ##################################### - - #################################### ###experiments in importing a terrain file if terrainFile!=None: print("***Checking for tif terrain image...***") @@ -406,7 +369,6 @@ def main(): print("***Checking directory for tif terrain image...***") tmpPath = os.path.join(terrainFile,'*.tif') #assumes file suffix is 'tif' matchFiles = glob.glob(tmpPath) - #print matchFiles if not matchFiles: #no matching files found tiffFound = False @@ -423,11 +385,8 @@ def main(): tiffFound = False if tiffFound == True: - ######################################################################### from PIL import Image, ImageOps - #if type(eventFile)==file: print("***Loading terrain file:\n %s***" % (theTerrainFile)) - #theImage = Image.open(terrainFile) tmp=Image.open(theTerrainFile) tmp=ImageOps.flip(tmp) @@ -534,8 +493,6 @@ def main(): print(" absMin: %s" % absMin) print(" terrainScale: %s" % terrainScale) print(" therefore max: %s" % (theMaxElevation)) - - #################################### #########Check for multiple species. If none, use default fileList=os.listdir("Species") @@ -555,13 +512,10 @@ def main(): #this isn't implemented pythonList.append(file) fileList=[] - ########## if (resumeSim==True or resumeSimReload==True) and not simulationFile=="": print("***Loading simulation: %s...***" % (simulationFile.name)) - #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 @@ -573,12 +527,6 @@ def main(): theGarden.importPrefs(fileLoc) ##this should reload species data. ###Important if you want to compare runs - # if reloadSpeciesData==True: - # # print "***Reloading species data...***" - # # ###fileLoc will be different for each species eventually - # # fileLoc="Vida_Data/Default_species.yml" - # # for item in theGarden.soil: - # # item.importPrefs(fileLoc) else: theGarden.makePlatonicSeedDict(ymlList, Species1) print("***Species loaded.***") @@ -597,10 +545,6 @@ def main(): 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==True: @@ -636,7 +580,6 @@ def main(): theCLIfile=open(outputDirectory+"CLI_arguments.txt", 'w') theCLIfile.writelines(theCLArgs) theCLIfile.close() - #if produceGraphics==1 or produceDXFGraphics==1: if produceGraphics==True: baseGraphicsDirectory = outputDirectory +"Graphics/" makeDirectory(baseGraphicsDirectory) @@ -675,13 +618,11 @@ def main(): if resumeSim==None and resumeSimReload==None: #2008.11.06 Moved a huge block of code related to placing seeds to vworldr.py theGarden.placeSeed(seedPlacement, sList, startPopulationSize, useDefaultYml, ymlList) - ################ #if there is a terrain file and water level then the initial placement of seeds #should be checked to see if any of them are below water #STH 0328-2021 if(theGarden.terrainImage != []): theGarden.checkSubmergedMortality() - ################ if produceGraphics==True and CFDGtextDict=={}: for aView in graphicalView: if aView!="3d": @@ -690,7 +631,6 @@ def main(): else: #Only call this once to save time in making 3d graphics DXFBlockDefs = vdxfGraphics.initDXFBlocks(theGarden) - ####### cycleNumber=0 print("\n***Running simulation.***") @@ -704,7 +644,7 @@ def main(): 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.") # + if defaultSpecies.debug==1: print("debug: A garden related event has been triggered.") # theDict=aItem[aKey][0] # gardenAttrs=theDict.keys() # for theGardenAttr in gardenAttrs: # @@ -712,7 +652,7 @@ def main(): gardenAttrs="" elif aKey=="Killzone" or aKey=="Safezone": - if debug==1: print("debug: generation of a zone event has been triggered.") + if defaultSpecies.debug==1: print("debug: generation of a zone event has been triggered.") theDict=aItem[aKey][0] # zoneAttrs=theDict.keys() zoneX=float(theDict['x']) @@ -743,7 +683,6 @@ def main(): r=theObject.radiusStem theResult=geometry_utils.checkOverlap(theObject.x, theObject.y, r, zoneX, zoneY, zoneSize) if theResult>0 and aKey=='Killzone': - #if (zoneSpecies == 'all') or (theObject.nameSpecies == zoneSpecies): #student requested addition to accept list of species. 0323-2023 if (zoneSpecies == 'all') or (theObject.nameSpecies in zoneSpecies): if zoneTarget=='all' or (theObject.isSeed and zoneTarget=='seeds') or (not theObject.isSeed and zoneTarget=='plants'): @@ -761,7 +700,6 @@ def main(): objectY=theObject.y theResult=geometry_utils.pointInsideSquare(zoneX, zoneY, zoneSize, objectX, objectY) if theResult>0 and aKey=='Killzone': - #if (zoneSpecies == 'all') or (theObject.nameSpecies == zoneSpecies): #student requested addition to accept list of species. 0323-2023 if (zoneSpecies == 'all') or (theObject.nameSpecies in zoneSpecies): if zoneTarget=='all' or (theObject.isSeed and zoneTarget=='seeds') or (not theObject.isSeed and zoneTarget=='plants'): @@ -778,7 +716,7 @@ def main(): theGarden.kill(theObject) elif aKey=="Seed": - if debug==1: print("debug: A seeding related event has been triggered.") # + if defaultSpecies.debug==1: print("debug: A seeding related event has been triggered.") # theDict=aItem[aKey][0] # seedingInfo=theDict.keys() # for infoItem in seedingInfo: @@ -789,7 +727,7 @@ def main(): if infoItem=="placement": seedPlacement=theDict[infoItem] if seedPlacement=="hexagon": seedPlacement="hex" #just make sure it is consistant if os.path.isfile(seedPlacement): - if debug == 1: print("debug: Confirming placement file exists....") + if defaultSpecies.debug == 1: print("debug: Confirming placement file exists....") theFile=open(seedPlacement) try: sList=theFile.readlines() @@ -798,7 +736,7 @@ def main(): sList=checkSeedPlacementList(sList) addPopulationSize=len(sList) seedPlacement="fromFile" - if debug ==1: print("debug: Will place seeds from a file") + if defaultSpecies.debug ==1: print("debug: Will place seeds from a file") ###if a simulation is being reloaded from a pickle, that sim might not have saved ###data on a new species being introduced. Load the new species and add it to the platonic list ###so it can be added to theGarden @@ -811,8 +749,8 @@ def main(): if not jj in theGarden.platonicSeeds: speciesIsMissing==True if speciesIsMissing==True: - if debug == 1: print("debug: Desired species missing from loaded simulation") - if debug == 1: print("debug: Adding species %s" % (jj)) + if defaultSpecies.debug == 1: print("debug: Desired species missing from loaded simulation") + if defaultSpecies.debug == 1: print("debug: Adding species %s" % (jj)) theSeed=Species1() fileLoc= "Species/"+jj theSeed.importPrefs(fileLoc) @@ -848,11 +786,11 @@ def main(): sList= [] #reset the sList to what it was when we started elif aKey=="Region": - if debug: print("debug: Region event detected...") + if defaultSpecies.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)) + if defaultSpecies.debug: print("debug: Region %s event detected." % (theRegionName)) regionNames=[] for i in theGarden.theRegions: regionNames.append(i.name) @@ -863,18 +801,15 @@ def main(): 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)) + if defaultSpecies.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)) + if defaultSpecies.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") + if defaultSpecies.debug:print("debug: updating plants with changed region info") for aPlant in theGarden.soil: plantX=aPlant.x plantY=aPlant.y @@ -886,9 +821,7 @@ def main(): 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 @@ -899,7 +832,7 @@ def main(): newRegion.shape='square' # ############################## ##now just read in the values# - if debug: print("debug: Making attributes for region") + if defaultSpecies.debug: print("debug: Making attributes for region") for theRegionAttr in regionAttrs: # setattr(newRegion, theRegionAttr, theDict[theRegionAttr]) # theGarden.theRegions.append(newRegion) @@ -914,12 +847,11 @@ def main(): if inSubregion: if not newRegion in aPlant.subregion: aPlant.subregion.append(newRegion) - #print "\nX: %f Y: %f In region: %s" % (plantX, plantY, newRegion) newRegion="" elif aKey=="Species": - if debug: print("debug: Species event detected...") + if defaultSpecies.debug: print("debug: Species event detected...") theDict = aItem[aKey][0] theSpeciesName = theDict['name'] speciesAttrs = theDict.keys() @@ -935,39 +867,23 @@ def main(): for theObject in theGarden.soil: if theObject.nameSpecies == theSpeciesName: for theSpeciesAttr in speciesAttrs: - if debug: print(" Attempting to set species '%s' property '%s' to %s" % (theObject.nameSpecies, theSpeciesAttr, theDict[theSpeciesAttr])) + if defaultSpecies.debug: print(" Attempting to set species '%s' property '%s' to %s" % (theObject.nameSpecies, theSpeciesAttr, theDict[theSpeciesAttr])) setattr(theObject, theSpeciesAttr, theDict[theSpeciesAttr]) speciesAttrs = "" theDict=[]#just clear this to free up the memory - ################################################################################### theGarden.cycleNumber=cycleNumber if not showProgressBar: theProgressBar.update(cycleNumber) - ###START OF SEEING CHANGES TO SPECIES FOLDER - #########Check for multiple species. If none, use default + #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)) + if defaultSpecies.debug==1: print("number of plants: "+str(theGarden.numbPlants)) + if defaultSpecies.debug==1: print("number of seeds: "+str(theGarden.numbSeeds)) #generate graphics if requested if produceGraphics==True: @@ -1022,23 +938,17 @@ def main(): theBar=theBar+1 theProgressBar.update(theBar) - ####################################### ###deal with violaters of basic physics theGarden.removeOffWorldViolaters() ##experimental water mortality## if(theGarden.terrainImage != []): theGarden.checkSubmergedMortality() - ########################## theGarden.causeRandomDeath() theGarden.checkSenescence() ##experimental mortality## theGarden.checkDistanceMortality() - ########################## theGarden.removeEulerGreenhillViolaters() theGarden.removeOverlaps() - ####################################### - - ####################################### ###working on waterlogging #2021-0328 if(theGarden.terrainImage != [] and theGarden.waterLevel>0.0): @@ -1047,13 +957,6 @@ def main(): worldBasics.determineWaterlogging(theGarden) worldBasics.determineDroughtTol(theGarden) - - ########This routine is done in worldBasics.determineShade - # ###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) @@ -1083,7 +986,6 @@ def main(): fileName=simulationName+'-'+str(cycleNumber)+'.csv' saveDataPoint(dataDirectory, fileName, theGarden) - #print theGarden.deathNote theGarden.deathNote=[] cycleNumber= cycleNumber+1 @@ -1095,8 +997,6 @@ def main(): fileName=simulationName+'-'+str(cycleNumber)+'.csv' saveDataPoint(dataDirectory, fileName, theGarden) - -#if produceStats: if saveData=="a": ###the real solution is to refactor vextract so it can be ###command line OR imported @@ -1123,7 +1023,6 @@ def main(): for aView in graphicalView: if aView!="3d": print("\nProducing PNG files...") - #print outputGraphicsDirectoryDict[aView] outputGraphics.outputPNGs(outputGraphicsDirectoryDict[aView], outputGraphicsDirectoryDict[aView]) if deleteCfdgFiles==True: print("Deleting .cfdg files...") @@ -1143,7 +1042,6 @@ def main(): theGarden.cycleNumber=0 for aRegion in theGarden.theRegions: aRegion.size=0.0 - #print theGarden.theRegions[0].size ###And this would be the end of the loop bit @@ -1163,9 +1061,6 @@ def main(): parser.add_argument('-c', dest='deleteCfdgFiles', action='store_false', required=False, help='Keep cfdg files') parser.add_argument('-p', dest='deletePngFiles', action='store_true', required=False, help='Delete png files') parser.add_argument('-b', dest='showProgressBar', action='store_true', required=False, help='Show progress bars') - # parser.add_argument('-r', metavar='file', type=file, dest='resumeSim', required=False, help='Load a saved simulation and continue') - # parser.add_argument('-rl', metavar='file', type=file, dest='resumeSimReload', required=False, help='Load a saved simulation, reload world prefs, and continue') - # parser.add_argument('-e', metavar='file', type=file, dest='eventFile', required=False, help='Load an event file') parser.add_argument('-r', type=open, metavar='file', dest='resumeSim', required=False, help='Load a saved simulation and continue') parser.add_argument('-rl', type=open, metavar='file', dest='resumeSimReload', required=False, help='Load a saved simulation, reload world prefs, and continue') parser.add_argument('-e', type=open, metavar='file', dest='eventFile', required=False, help='Load an event file') @@ -1181,11 +1076,9 @@ def main(): ###options that use a code action parser.add_argument('-v', type=int, metavar='int', nargs='?', action=parseAction, dest='produceVideo', required=False, help='Produce a video from images. Optional frames/second') parser.add_argument('-g', nargs='*', type=str, action=parseAction, dest='produceGraphics', required=False, choices=['b','t','s','ts','st','bs','sb','bt','tb','bts','3d' ], help='Graphical view desired') - # parser.add_argument('-s', type=int, metavar='int', nargs='?', dest='startPopulationSize', action=parseAction, help='Number of seeds to start simulation with') parser.add_argument('-s', type=int, metavar='int', nargs='?', dest='startPopulationSize', action=parseAction, help='Number of seeds to start simulation with, planted randomly') parser.add_argument('-ss', type=int, metavar='int', nargs='?', dest='startPopulationSize', action=parseAction, help='Number of seeds to start simulation with, planted in a square') parser.add_argument('-sh', type=int, metavar='int', nargs='?', dest='startPopulationSize', action=parseAction, help='Number of seeds to start simulation with, planted in a hex') - # parser.add_argument('-sf', type=open, metavar='file', dest='startPopulationSize', action=parseAction) parser.add_argument('-sf', type=pathlib.Path, metavar='file', dest='startPopulationSize', action=parseAction, required=False, help='Path to placement csv file') ###slighly overloaded options @@ -1194,8 +1087,6 @@ def main(): parser.add_argument('-f', type=str, dest='saveData', action=parseAction, nargs=1, choices=['a', 'e','n','s']) parser.add_argument('-fi', type=str, dest='saveData', action=parseAction, nargs=1 ) - ########## - parser.set_defaults(**theDefaults) theOptsVals=vars(parser.parse_args())#have it presented as a dict @@ -1210,7 +1101,7 @@ def main(): if type(produceGraphics)==list: graphicalView=produceGraphics[1] if "3d" in graphicalView: - import vdxfGraphics + from Vida_Data import vdxfGraphics produceGraphics=produceGraphics[0] if type(graphicalView)!=list: graphicalView=[graphicalView]#make sure the graphicalView is a list @@ -1258,29 +1149,17 @@ def main(): if theExtension==".csv": theFile = open(startPopulationSize[0]) sList=theFile.readlines() - #print(sList) - #print(type(sList)) sList=checkSeedPlacementList(sList) startPopulationSize=len(sList) seedPlacement="fromFile" - #print(startPopulationSize) if type(startPopulationSize)==list: seedPlacement=startPopulationSize[1] startPopulationSize=startPopulationSize[0] - # if type(startPopulationSize)=='_io.TextIOWrapper': - # sList=startPopulationSize.readlines() - # ##send the file off to make sure it's in the correct format - # sList=checkSeedPlacementList(sList) - # startPopulationSize=len(sList) theMaxElevation = absMax-absMin theMaxElevation = theMaxElevation*terrainScale - - - #for x in theOpts: -#print "%s: \t%s %s" % (x, theDefaults[x], globalVarsVals[x]) theDefaults=None#just clear it to free up memory @@ -1288,10 +1167,3 @@ def main(): main() else: main() - - - - - - - diff --git a/Vida_Data/GUI/Read me.txt b/Vida_Data/GUI/Read me.txt deleted file mode 100644 index 75db856..0000000 --- a/Vida_Data/GUI/Read me.txt +++ /dev/null @@ -1 +0,0 @@ -Note: the GUI interface no longer works due to security changes to javascript diff --git a/Vida_Data/GUI/Species Builder.py b/Vida_Data/GUI/Species Builder.py deleted file mode 100755 index 263a61b..0000000 --- a/Vida_Data/GUI/Species Builder.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python -"""This file is part of Vida. --------------------------- -Copyright 2009, Sean T. Hammond - -Vida is experimental in nature and is made available as a research courtesy "AS IS," but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -You should have received a copy of academic software agreement along with Vida. If not, see . -""" - -import cherrypy -import webbrowser -import os -import os.path -import yaml - -class HelloWorld(object): - @cherrypy.expose - def index(self): - #return "Hello World!" - return cherrypy.tools.staticdir.root - - @cherrypy.expose - def speciesBuilder(self): - return open('Vida_Data/GUI/speciesBuilder.html').read() - - @cherrypy.expose - def loadSpeciesNames(self): - theDirectory="Species/" - ###check and see if what is returned is a file of a directory - if not os.path.isdir(theDirectory): - selectedExtension=os.path.splitext(theDirectory)[1] - theDirectory =os.path.dirname(theDirectory) - rawFileList = os.listdir(theDirectory) - ###show only files with the desired suffixes - okFileSuffix=[".yml"] - theFileList=[] - for file in rawFileList: - theExtension=os.path.splitext(file)[1] - theFileName=os.path.splitext(file)[0] - if theExtension in okFileSuffix: - theFileList.append(theFileName) - rawFileList=[] - allOptions="" - for fileName in theFileList: - theOption="" % (fileName, fileName) - allOptions= allOptions+theOption - return allOptions - - @cherrypy.expose - def submitData(*args, **kw): - theKeys=kw.keys() - theKeys.sort() - theOutput=[] - for aKey in theKeys: - splitByPeriod= aKey.split(".") - if splitByPeriod[1]=="nameSpecies": - theFileName=kw[aKey] - if splitByPeriod[1][1]=="#": - theOutput.append("%s\n" % (splitByPeriod[1])) - else: - theOutput.append("%s: %s\n" % (splitByPeriod[1], kw[aKey])) - #theFileName=theFileName.replace(" ", "") - theFileName=theFileName - fileLoc="Species/"+ theFileName+".yml" - copyNumb=0 - while os.path.isfile(fileLoc): - ###There should be something here to alert the user if they are going to overwrite an existing file - #print "the file exists" - copyNumb=copyNumb+1 - fileLoc="Species/"+ theFileName+str(copyNumb)+".yml" - theFile=open(fileLoc, 'w') - theFile.writelines(theOutput) - theFile.close - print "File saved" - return "saved" - - - - - @cherrypy.expose - def loadSpeciesYMLFile(self, theFileName='Generic Gymnosperm.yml'): - #print "loading file" - fileLoc="Species/"+ theFileName - theFile=open(fileLoc) - theFileData= theFile.read().splitlines() - theFile.close - #print "file closed" - #now open the file with help/tutorial data - #print "loading file" - fileLoc="Vida_Data/SpeciesFileHelpData.yml" - theFile=open(fileLoc) - theHelpData= yaml.load(theFile) - theFile.close - #print "file closed" - CSSData="
\n
\n%s
 
\n
\n" - sectionID="
\n%s
\n" - sectionData="" - lineData="" - basicLineData="
%s:
\n" - idSectionName="" - - theFormData="" - closeDiv="\n" - sortNumber=0 - for item in theFileData: - if not item=="": - if sortNumber<10: - sortNumbStr="0"+str(sortNumber) - else: - sortNumbStr=str(sortNumber) - splitByColon=item.split(": ") - if splitByColon[0][0]=="#": - splitByPound=item.split("#")[-1] - if idSectionName=="": - theFormData=theFormData+ sectionData - sectionData="" - idSectionName= sectionID % ("section"+splitByPound, sortNumbStr+".###"+splitByPound, "###"+splitByPound, "%s") - else: - ###prev section has ended and a new one has started - sectionData = idSectionName % (sectionData) - theFormData=theFormData+ sectionData - idSectionName= sectionID % ("section"+splitByPound, sortNumbStr+".###"+splitByPound, "###"+splitByPound, "%s") - sectionData="" - else: - ##this error catch is in case the help data file is missing, or partly missing - theHelpString="No data available." - if splitByColon[0] in theHelpData: - theHelpString=theHelpData[splitByColon[0]] - lineData=basicLineData % (splitByColon[0], splitByColon[0], sortNumbStr+"."+splitByColon[0], splitByColon[-1], theHelpString) - sectionData= sectionData + lineData - sortNumber=sortNumber+1 - if not idSectionName=="": - sectionData = idSectionName % (sectionData) - theFormData=theFormData+ sectionData - theHtml=CSSData % (theFormData) - #print theHtml - return theHtml - - - - - - - - -theUrlBase="localhost" -thePort=8080 -curdir = os.path.join(os.getcwd(), "Vida_Data/GUI") -conf = { - '/interfaceGraphics': { - 'tools.staticdir.on': True, - 'tools.staticdir.dir': 'interfaceGraphics', - 'tools.staticdir.root': curdir, - }, - '/': { - 'tools.staticdir.on': True, - 'tools.staticdir.dir': '', - 'tools.staticdir.root': curdir, - }, -} - -cherrypy.tree.mount(HelloWorld(), config=conf) -#something changed in the latest cherrypy build -#cherrypy.engine.start(blocking=False) -cherrypy.engine.start() -cherrypy.server.socketPort=thePort -cherrypy.server.quickstart() -theUrl="http://%s:%s/speciesBuilder" % (theUrlBase, thePort) -webbrowser.open(theUrl) -cherrypy.engine.block() \ No newline at end of file diff --git a/Vida_Data/GUI/interfaceGraphics/icon_CFDG.jpg b/Vida_Data/GUI/interfaceGraphics/icon_CFDG.jpg deleted file mode 100644 index 9442629..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/icon_CFDG.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/icon_CSV.jpg b/Vida_Data/GUI/interfaceGraphics/icon_CSV.jpg deleted file mode 100644 index 53a22dd..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/icon_CSV.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/icon_PICKLE.jpg b/Vida_Data/GUI/interfaceGraphics/icon_PICKLE.jpg deleted file mode 100644 index f9d66e7..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/icon_PICKLE.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/icon_PNG.jpg b/Vida_Data/GUI/interfaceGraphics/icon_PNG.jpg deleted file mode 100644 index 83f76f7..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/icon_PNG.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/icon_blank.jpg b/Vida_Data/GUI/interfaceGraphics/icon_blank.jpg deleted file mode 100644 index 7b1b1ee..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/icon_blank.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/question.gif b/Vida_Data/GUI/interfaceGraphics/question.gif deleted file mode 100644 index 888e347..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/question.gif and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/-headerReproduction.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/-headerReproduction.jpg deleted file mode 100755 index 6fe3724..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/-headerReproduction.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/cardbg.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/cardbg.jpg deleted file mode 100644 index 6021bcf..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/cardbg.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/fillerButton.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/fillerButton.jpg deleted file mode 100644 index 69611c3..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/fillerButton.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/fillerButtonDim.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/fillerButtonDim.jpg deleted file mode 100644 index 5d4315d..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/fillerButtonDim.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerAll.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerAll.jpg deleted file mode 100644 index fcbfe9a..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerAll.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerAllometry.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerAllometry.jpg deleted file mode 100644 index df0f932..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerAllometry.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerBasic.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerBasic.jpg deleted file mode 100644 index fcbfe9a..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerBasic.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerEvolution.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerEvolution.jpg deleted file mode 100644 index f58ab68..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerEvolution.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerGraphics.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerGraphics.jpg deleted file mode 100644 index f43b635..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerGraphics.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerMortality.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerMortality.jpg deleted file mode 100644 index adb9be0..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerMortality.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerPhotosynthesis.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerPhotosynthesis.jpg deleted file mode 100644 index 1f150b4..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerPhotosynthesis.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerReproduction.jpg b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerReproduction.jpg deleted file mode 100644 index 90936a3..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/headerReproduction.jpg and /dev/null differ diff --git a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/question.gif b/Vida_Data/GUI/interfaceGraphics/speciesBuilder/question.gif deleted file mode 100644 index 20d5bcf..0000000 Binary files a/Vida_Data/GUI/interfaceGraphics/speciesBuilder/question.gif and /dev/null differ diff --git a/Vida_Data/GUI/jquery.js b/Vida_Data/GUI/jquery.js deleted file mode 100644 index 3747929..0000000 --- a/Vida_Data/GUI/jquery.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * jQuery 1.2.3 - New Wave Javascript - * - * Copyright (c) 2008 John Resig (jquery.com) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ - * $Rev: 4663 $ - */ -(function(){if(window.jQuery)var _jQuery=window.jQuery;var jQuery=window.jQuery=function(selector,context){return new jQuery.prototype.init(selector,context);};if(window.$)var _$=window.$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;var isSimple=/^.[^:#\[\.]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem)if(elem.id!=match[3])return jQuery().find(selector);else{this[0]=elem;this.length=1;return this;}else -selector=[];}}else -return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.3",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;this.each(function(i){if(this==elem)ret=i;});return ret;},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],name)||undefined;else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else -return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else -selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return!selector?this:this.pushStack(jQuery.merge(this.get(),selector.constructor==String?jQuery(selector).get():selector.length!=undefined&&(!selector.nodeName||jQuery.nodeName(selector,"form"))?selector:[selector]));},is:function(selector){return selector?jQuery.multiFilter(selector,this).length>0:false;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=value.constructor==Array?value:[value];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else -this.value=value;});},html:function(value){return value==undefined?(this.length?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value==null){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data==undefined&&this.length)data=jQuery.data(this[0],key);return data==null&&parts[1]?this.data(parts[0]):data;}else -return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script")){scripts=scripts.add(elem);}else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.prototype.init.prototype=jQuery.prototype;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else -jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==1){target=this;i=0;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else -jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret;function color(elem){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=elem.style.outline;elem.style.outline="0 solid black";elem.style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&elem.style&&elem.style[name])ret=elem.style[name];else if(document.defaultView&&document.defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var getComputedStyle=document.defaultView.getComputedStyle(elem,null);if(getComputedStyle&&!color(elem))ret=getComputedStyle.getPropertyValue(name);else{var swap=[],stack=[];for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(var i=0;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else -ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,""+value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(typeof array!="array")for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval!=undefined)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(arguments.callee.elem,arguments);return val;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else -for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data||[]);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event)data.unshift(this.fix({type:type,target:elem}));data[0].type=type;if(exclusive)data[0].exclusive=true;if(jQuery.isFunction(jQuery.data(elem,"handle")))val=jQuery.data(elem,"handle").apply(elem,data);if(!fn&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var handlers=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in handlers){var handler=handlers[j];args[0].handler=handler;args[0].data=handler.data;if(!parts[1]&&!event.exclusive||handler.type==parts[1]){var ret=handler.apply(this,args);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=originalEvent.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);return undefined;},toggle:function(){var args=arguments;return this.click(function(event){this.lastToggle=0==this.lastToggle?1:0;event.preventDefault();return args[this.lastToggle].apply(this,arguments)||false;});},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else -jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){var jsonp,jsre=/=\?(&|$)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get"){var ts=(new Date()).getTime();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if((!s.url.indexOf("http")||!s.url.indexOf("//"))&&s.dataType=="script"&&s.type.toLowerCase()=="get"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async,s.username,s.password);try{if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");xml.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else -jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else -for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else -s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else -e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})(); \ No newline at end of file diff --git a/Vida_Data/GUI/prototypeExtractor.html b/Vida_Data/GUI/prototypeExtractor.html deleted file mode 100644 index 762fc81..0000000 --- a/Vida_Data/GUI/prototypeExtractor.html +++ /dev/null @@ -1,240 +0,0 @@ - -Prototype extractor interface - - - - - - - - - - - -Data Extractor-mockup1 -
-
-

- - - - - - -
- -
-
-
-
- - - -
- - -
-
-
-
-
Produce CFDG files
-
Produce PNG files
-
Produce Video files
-
Produce CSV files
-
Produce Summary files
-
-
- -

-

- -

- - \ No newline at end of file diff --git a/Vida_Data/GUI/speciesBuilder.html b/Vida_Data/GUI/speciesBuilder.html deleted file mode 100644 index a72f4c4..0000000 --- a/Vida_Data/GUI/speciesBuilder.html +++ /dev/null @@ -1,218 +0,0 @@ - -Prototype Species builder - - - - - - -
- - - - - - - - - - - - - - -
-Species Builder -
-Species:
- -
tabtabtabtabtabtabtab
-
-
-
-Please select a species to begin. -
-
- -
- - -
- \ No newline at end of file diff --git a/Vida_Data/geometry_utils.py b/Vida_Data/geometry_utils.py index 2f0a38b..dda4f72 100755 --- a/Vida_Data/geometry_utils.py +++ b/Vida_Data/geometry_utils.py @@ -8,19 +8,12 @@ """ import math - -#Import Psyco if possible -try: - import psyco - psyco.log() - psyco.full() -except ImportError: - pass +#psyco was here def checkOverlap(x, y, r, xx, yy, rr): return circleOverlap(x,y,r,xx,yy,rr) - -def python_circle_circle_overlap(x,y,r,xx,yy,rr): + +def circleOverlap(x,y,r,xx,yy,rr): #no more python_circle_circle_overlap IJC 01/20/26 theDistance =distBetweenPoints(x, y, xx, yy) ###now look at the distance in relation to the radii if theDistance>(r+rr): @@ -31,17 +24,7 @@ def python_circle_circle_overlap(x,y,r,xx,yy,rr): return 1 else: ###partial overlap - return 2 - -#####look and see if there is a special C version -try: - import circtest - circleOverlap = circtest.circle_circle_overlap - print("*********Will use gib's code**************") -except ImportError: - circleOverlap = python_circle_circle_overlap - print("*********Will use straight python*********") - pass + return 2 def placePointsInGrid(numbPoints, lengthSquareSide): ###assumes the area is a square @@ -55,7 +38,6 @@ def distBetweenPoints(x0, y0, x1, y1): return theDistance def areaCircle(radius): - #area=math.pi*math.pow(radius, 2) area=3.14*radius*radius return area @@ -86,23 +68,6 @@ def boundCircle(x, y, r): yMax=y+r return [xMin, xMax, yMin, yMax] -#def checkOverlap(x, y, r, xx, yy, rr): -# if useCforCheckingOverlap==False: -# theDistance =distBetweenPoints(x, y, xx, yy) -# ###now look at the distance in relation to the radii -# if theDistance>(r+rr): -# ###no overlap -# return 0 -# elif theDistance<(math.fabs(r-rr)): -# ###complete overlap -# return 1 -# else: -# ###partial overlap -# return 2 -# else: -# theReturn=circtest.circle_circle_overlap(x,y,r,xx,yy,rr) -# return theReturn - def checkOverlapSquare(x, y, r, xx, yy, size): #x,y,r are the plant #xx, yy, size are the square @@ -131,8 +96,6 @@ def pointInsideSquare(squareX, squareY, squareSize,pointX, pointY): else: return 0 - - def distToRadical(r0, r1, distance): ###Send it radius of circle 1, radius circle 2, distance between the two circles ###returns a list in format:[distance from circle 1 to radical, distance from circle 2 to radical] diff --git a/Vida_Data/list_utils.py b/Vida_Data/list_utils.py index 84eab63..a25f838 100644 --- a/Vida_Data/list_utils.py +++ b/Vida_Data/list_utils.py @@ -7,30 +7,13 @@ You should have received a copy of academic software agreement along with Vida. If not, see . """ -#import operator#python 2.4 only def sort_by_attr(seq, attr): - #python 2.3 intermed=[(getattr(x, attr),i, x) for i, x in enumerate(seq)] intermed.sort() return [x[-1]for x in intermed] - #python 2.4 - #return sorted(seq, key=operator.attrgetter(attr)) def sort_by_attr_inplace(lst, attr): - #python 2.3 lst[:]=sort_by_attr(lst,attr) - #python 2.4 - #lst.sort(key=operator.attrgetter(attr)) def remove_duplicates(theList): - # "remove_duplicates(list) => list as a set, i.e., all repeated elements removed." - # "Ported from $list_utils:count. Imaginary Bridges lambdamoo by STH 2010.03.23" - # checkedList = [] - # for anElement in theList: - # if anElement not in checkedList: - # checkedList.append(anElement) - # print("previous method: %s" % checkedList) - # print("new method: %s" % list(set(theList))) - # return checkedList - #this should work better STH 2021-0305 return list(set(theList)) \ No newline at end of file diff --git a/Vida_Data/progressBarClass.py b/Vida_Data/progressBarClass.py index 6f6593e..373ad56 100644 --- a/Vida_Data/progressBarClass.py +++ b/Vida_Data/progressBarClass.py @@ -30,8 +30,6 @@ def __init__(self, finalcount, progresschar=None): return self.f.write('[----------------- % Progress ---------------------]\n') self.f.write('[') - #self.f.write(' 10 20 30 40 50 60 70 80 90 100\n') - #self.f.write('----|----|----|----|----|----|----|----|----|----|\n') return def update(self, count): diff --git a/Vida_Data/vdxfGraphics.py b/Vida_Data/vdxfGraphics.py index ba83fdc..81f2a9f 100755 --- a/Vida_Data/vdxfGraphics.py +++ b/Vida_Data/vdxfGraphics.py @@ -30,8 +30,6 @@ def initDXFBlocks(theGarden): ############################ #Blocks b = dxf.block(name='THEGARDEN') - # b.add(dxf.solid([(0,0,0),(1,0,0),(1,1,0),(0,1,0)])) - # theData.blocks.add(b) #Keep having problems with tools that convert DXF to STL not identifying #SOLID, so made it a 3dface #sth 2024.01.15 @@ -47,8 +45,6 @@ def initDXFBlocks(theGarden): #SOLID, so made it a 3dface #sth 2024.01.15 b = dxf.block(name='WATER') - # b.add(dxf.solid([(0,0,0),(1,0,0),(1,1,0),(0,1,0)], thickness=1.0, color=5)) - # theData.blocks.add(b) theFaceList = Cube() for x in theFaceList: the3dFace = dxf.face3d(x , flags=0) @@ -58,8 +54,6 @@ def initDXFBlocks(theGarden): b = dxf.block(name='STEM') - # b.add(dxf.circle(center=(0.0,0.0,0.0),radius=1.0,thickness=1.0)) - # theData.blocks.add(b) theFaceList = Sphere() for x in theFaceList[0:480]: the3dFace = dxf.face3d(x , flags=0) @@ -88,83 +82,73 @@ def initDXFBlocks(theGarden): #only do this if there is a terrain image to use if(terrainImage!=[]): + theData = makeTerrainMesh(theData, theWorldSize, terrainImage, theElevDelta) #from arborvida IJC 01/20/26 print("***Generating terrain mesh...***") b = dxf.block(name='MESHTERRAIN') - #xSize,ySize = (terrainImage[1][0],terrainImage[1][1]) xSize,ySize = (theWorldSize+1,theWorldSize+1) mesh = dxf.polymesh(xSize, ySize) for x in range(xSize): for y in range(ySize): - #thePixelValue = terrain_utils.getPixelValue(x-50,y-50,terrainImage) thePixelValue = terrain_utils.getPixelValue(x,y,terrainImage) z = terrain_utils.elevationFromPixel(thePixelValue, theElevDelta) - #z = terrain_utils.elevationFromPixel(thePixelValue) mesh.set_vertex(x, y, (x, y, z)) b.add(mesh) theData.blocks.add(b) - - # ############################ - # #New method - # doc = ezdxf.new('R2010') - # # Set meter as document/modelspace units - # doc.units = units.M - # # which is a shortcut (including validation) for - # #doc.header['$INSUNITS'] = units.M - # doc.header['$MEASUREMENT'] = 1 #0==Imperial, 1==Metric - - # #make the modelspace (msp) - # msp = doc.modelspace() - # msp.units = doc.units - # # - # #Blocks - # #Keep having problems with tools that convert DXF to STL not identifying - # #SOLID, so made it a 3dface - # #sth 2024.01.15 - # aBlock = doc.blocks.new(name='THEGARDEN') - # theFaceList = Cube() - # for x in theFaceList: - # aBlock.add_3dface(x) - # theFaceList="" - - # aBlock = doc.blocks.new(name='WATER') - # theFaceList = Cube() - # for x in theFaceList: - # aBlock.add_3dface(x) - # theFaceList="" - - # aBlock = doc.blocks.new(name='STEM') - # theFaceList = Cube() - # for x in theFaceList: - # aBlock.add_3dface(x) - # theFaceList="" - - # aBlock = doc.blocks.new(name='SEED') - # theFaceList = Sphere() - # for x in theFaceList: - # aBlock.add_3dface(x) - # theFaceList="" - - # aBlock = doc.blocks.new(name='CANOPY') - # theFaceList = Sphere() - # for x in theFaceList[0:480]: - # aBlock.add_3dface(x) - # theFaceList="" - ############################ - return theData - - - - - - +#function from arborvida IJC 01/20/26 +def makeTerrainMesh(theData, theWorldSize, terrainImage, theElevDelta): + ##using assimp to make other 3d file types and + ##assimp doesn't render mesh correctly + ##Keep in case assimp changes and it can read meshes correctly + ##STH 2024-0131 + ##Generate a 3dface instead of a mesh so assimp can do it correctly + print("***Generating terrain 3dface...***") + b = dxf.block(name='MESHTERRAIN') + xSize,ySize = (theWorldSize,theWorldSize) + theMesh=[] + for x in range(xSize): + aRow=[] + for y in range(ySize): + thePixelValue = terrain_utils.getPixelValue(x,y,terrainImage) + z = terrain_utils.elevationFromPixel(thePixelValue, theElevDelta) + aRow.append((x,y,z)) + theMesh.append(aRow) + aRow = None + theFaceList=[] + for theRowNumb in range(ySize-1): + i=0 + j=2 + for theColNumb in range(xSize-2): + #Starting with the mesh, which is a series of coordinates for each point + #we need to convert that into grouping of 4 coordinates defining a box + #for the 3dface. The creation needs to be done widdershins, starting in + #the lower left for the normal face to not be transparent. + #https://ezdxf.readthedocs.io/en/stable/dxfentities/3dface.html for example + #If the coordinates are: + #a b c d + #e f g h + #then the first box is: e,f,b,a. + #row 2, take the first two values, row 1, take the same index values, but reverse them + #then advance the column by 1 so the next box is: f,g,c,b + #STH 2024-0131 + theFaceBox=[] + theFaceBox=theFaceBox+theMesh[theRowNumb+1][i:j] + theFaceBox=theFaceBox+list(reversed(theMesh[theRowNumb][i:j])) + i=j-1 + j=i+2 + theFaceList.append(theFaceBox) + theFaceBox = None + for x in theFaceList: + the3dFace = dxf.face3d(x , flags=0) + b.add(the3dFace) + theFaceList = None + theData.blocks.add(b) + return theData def makeDXF(theGarden, theBlockData): theWorldSize=theGarden.theWorldSize - # theData.append(sdxf.Insert('world',point=(0-(theWorldSize/2.0),0-(theWorldSize/2.0),0),xscale=theWorldSize,yscale=theWorldSize,zscale=0,color=0,rotation=0)) - #print(0-(theWorldSize/2.0)) theBlockData.add(dxf.insert(blockname='THEGARDEN', insert=(0-(theWorldSize/2.0),0-(theWorldSize/2.0),0), xscale=theWorldSize, yscale=theWorldSize, zscale=0.001, rotation=0, color=5)) @@ -172,8 +156,6 @@ def makeDXF(theGarden, theBlockData): theBlockData.add(dxf.insert(blockname='MESHTERRAIN', insert=(0-(theWorldSize/2.0),0-(theWorldSize/2.0),0), rotation=0, color=0)) if(theGarden.waterLevel>0.0): theBlockData.add(dxf.insert(blockname='WATER', insert=(0-(theWorldSize/2.0),0-(theWorldSize/2.0),0), xscale=theWorldSize, yscale=theWorldSize, zscale=theGarden.waterLevel, rotation=0, color=5)) - - #dictColoursUsed={} for obj in theGarden.soil: x=obj.x y=obj.y @@ -187,27 +169,22 @@ def makeDXF(theGarden, theBlockData): theSeedRadius=obj.radiusSeed*obj.radiusSeedMultiplier #This should offset the seeds to match the image elevation #STH 2020-0226 - # theData.append(sdxf.Insert('seed',point=(x,y,theElevation+theSeedRadius),xscale=theSeedRadius,yscale=theSeedRadius,zscale=theSeedRadius,color=aicSeedDispersed,rotation=0)) theBlockData.add(dxf.insert(blockname='SEED', insert=(x,y,theElevation+theSeedRadius),xscale=theSeedRadius,yscale=theSeedRadius,zscale=theSeedRadius, rotation=0, color=aicSeedDispersed)) else: theStemRadius=obj.radiusStem*obj.radiusStemMultiplier theLeafRadius=obj.radiusLeaf*obj.radiusLeafMultiplier if (obj.crownShape == "PARA"): #bole height is not calculated. It's defined in the species file - # theData.append(sdxf.Insert('canopy',point=(x,y,theElevation+obj.heightStem-obj.heightStem*(obj.boleHeight/100.0)),xscale=theLeafRadius,yscale=theLeafRadius,zscale=obj.heightStem*(obj.boleHeight/100.0),color=aicLeaf,rotation=0)) theBlockData.add(dxf.insert(blockname='CANOPY', insert=(x,y,theElevation+obj.heightStem-obj.heightStem*(obj.boleHeight/100.0)),xscale=theLeafRadius,yscale=theLeafRadius,zscale=obj.heightStem*(obj.boleHeight/100.0), rotation=0, color=aicLeaf)) else: #default shape is a perfect hemisphere - # theData.append(sdxf.Insert('canopy',point=(x,y,theElevation+obj.heightStem-theLeafRadius),xscale=theLeafRadius,yscale=theLeafRadius,zscale=theLeafRadius,color=aicLeaf,rotation=0)) theBlockData.add(dxf.insert(blockname='CANOPY', insert=(x,y,theElevation+obj.heightStem-theLeafRadius),xscale=theLeafRadius,yscale=theLeafRadius,zscale=theLeafRadius, rotation=0, color=aicLeaf)) - # theData.append(sdxf.Insert('stem',point=(x,y,theElevation),xscale=theStemRadius,yscale=theStemRadius,zscale=obj.heightStem,color=aicStem,rotation=0)) theBlockData.add(dxf.insert(blockname='STEM', insert=(x,y,theElevation),xscale=theStemRadius,yscale=theStemRadius,zscale=obj.heightStem, rotation=0, color=aicStem)) for attachedSeed in obj.seedList: x= attachedSeed.x y= attachedSeed.y z= attachedSeed.z theSeedRadius= attachedSeed.radiusSeed* attachedSeed.radiusSeedMultiplier - # theData.append(sdxf.Insert('seed',point=(x,y,z),xscale=theSeedRadius,yscale=theSeedRadius,zscale=theSeedRadius,color=aicSeedAttached,rotation=0)) theBlockData.add(dxf.insert(blockname='SEED', insert=(x,y,z),xscale=theSeedRadius,yscale=theSeedRadius,zscale=theSeedRadius, rotation=0, color=aicSeedAttached)) return theBlockData diff --git a/Vida_Data/vextract.py b/Vida_Data/vextract.py index 365137a..8221e2c 100644 --- a/Vida_Data/vextract.py +++ b/Vida_Data/vextract.py @@ -15,28 +15,25 @@ import linecache import pickle import argparse -if (sys.version_info.major)==2: - import ConfigParser -else: - import configparser as ConfigParser - import pathlib +import configparser ###append the path to basic data files sys.path.append("Vida_Data") import vgraphics as outputGraphics import vplantr as defaultSpecies import list_utils +from tools import pixelCount as pCount theCLArgs="" ########################################## #Import the options# +theConfigSection='Vida Options' try: - theConfig=ConfigParser.RawConfigParser() + theConfig=configparser.RawConfigParser() theConfig.optionxform = str theConfig.read('Vida.ini') - theConfigSection='Vida Options' -except ConfigParser.MissingSectionHeaderError: +except configparser.MissingSectionHeaderError: print("Warning: Invalid config file, no [%s] section.") % (theConfigSection) raise @@ -64,14 +61,6 @@ theDefaults['allFiles']=False theDefaults['fileOrFolder']=None -#print (theDefaults) -#print ("#################") -#import vdefaults as thePrefs -#produceGraphics=thePrefs.produceGraphics -#produceVideo=thePrefs.produceVideo -#percentTimeStamp=thePrefs.percentTimeStamp -#framesPerSecond=thePrefs.framesPerSecond - class parseAction(argparse.Action): def __call__(self,parser,args,theValues,option_string=None): ###video option @@ -94,13 +83,9 @@ def __call__(self,parser,args,theValues,option_string=None): theValues=[True, theValues] setattr(args, self.dest, theValues) - -############################################## - class Species1(defaultSpecies.genericPlant): ###The routine in defaultSpecies.genericPlant reads in default values from .yml file def __init__(self): - ##super(type, obj) -> bound super object; requires isinstance(obj, type) super(Species1, self).__init__() def makeDirectory(theDirectory): @@ -111,7 +96,6 @@ def saveDataToCSVFile (theDirectory, theFileName, theData): makeDirectory(theDirectory) if not theFileName.endswith(".csv"): theFileName=theFileName+".csv" - #saveDataFile =csv.writer(file(theDirectory + theFileName, 'w'),delimiter=',',lineterminator='\n') saveDataFile =csv.writer(open(theDirectory + theFileName, 'w'),delimiter=',',lineterminator='\n') for l in theData: saveDataFile.writerow(l) @@ -143,7 +127,7 @@ def saveDataToCSVFile (theDirectory, theFileName, theData): ###Parse the name a bit more #-n is required, so it better be there - #fileOrFolder=theArguments[loc+1] + fileOrFolder=pCount.theArguments[pCount.loc+1] fileOrFolder=fileOrFolder.split(",") ###parse the graphic options a bit more @@ -180,8 +164,6 @@ def saveDataToCSVFile (theDirectory, theFileName, theData): produceVideo=False #for x in theOpts: -# print "%s: \t%s %s" % (x, theDefaults[x], globalVarsVals[x]) - theDefaults=None#just clear it to free up memory #remove the ' from start and back for essp501L if fileOrFolder[0][0]=="'": fileOrFolder[0]=fileOrFolder[0][1:] @@ -336,15 +318,7 @@ def saveDataToCSVFile (theDirectory, theFileName, theData): ignoreTheseColumns=["Cycle #", " X Location", " Y Location", " Age at Maturity"] totalCommunitySums=["Mass of Stem", "Mass of Canopy", "Mass Stem+Mass Canopy", "Mass of all Seeds", "Mass Total", "Growth Stem (kg)", "Growth Canopy (kg)", "Growth Stem+Canopy (kg)", "Functional Area"] ###Get a list of unique species names - #theIndex="na" - #theIndex=allText[0].index(" Species") - #if not theIndex=="na": - # # create array of all individuals of all species species - # theSpeciesNameColumn=[row[theIndex] for row in allText] - # theSpeciesNameColumn.pop(0) #get rid of the column heading - # theSpeciesNames=list_utils.remove_duplicates(theColumn) - # theSpeciesNames.sort() - #print theSpeciesNames + #create array of all individuals of all species species if not theColumn[0] in ignoreTheseColumns: try: if theColumn[0]=="X Location": @@ -439,7 +413,6 @@ def saveDataToCSVFile (theDirectory, theFileName, theData): theData=[row[theDataIndex] for row in allText] theData.pop(0) theSpeciesDict=dict.fromkeys(theSpeciesNames,[]) - #for aSpeciesName in theSpeciesNames: SpeciesData = [] for anElement in theColumn: theListTemp=[] @@ -450,36 +423,9 @@ def saveDataToCSVFile (theDirectory, theFileName, theData): theListTemp.append(datum) theSpeciesDict[anElement]=theListTemp - #theSpeciesDict.setdefault(anElement, SpeciesData).append(datum) - for theName in theSpeciesNames: theOutput[0].append(("Total Functional Area of %s") % theName) theOutput[1].append(sum(theSpeciesDict[theName])) - - - #allSpeciesFunctionalArea = dict(zip(theColumn,theData)) - #print allSpeciesFunctionalArea - - # # theSpeciesData = [] used to be here but I think it serves us better in the for loop so it can be repopulated - # for name in theSpeciesNames: - # # "species" should = "name" - # theSpeciesData = [] - # otherSpecies = theSpeciesNames.remove(name) - # AlltheSpeciesData = dict(zip(theColumn, theData)) - # for i in range(len(theColumn)): - # theName=theColumn[i] - # if not theName in otherSpecies: - # theSpeciesData.append(AlltheSpeciesData[theName]) - - # #for others in otherSpecies: - # # del AlltheSpeciesData[otherSpecies] - # theSpeciesData = AlltheSpeciesData - # theOutput[0].append("Total Functional Area of %s \n") % theSpeciesNames(name) - # theOutput[1].append(sum(theSpeciesData)) - # #theSpeciesCount.append(theColumn.count(theColumn[i])) - - - ###make sure the header for the summary file is the one having the most data if len(theSummaryOutputHeader)=self.startMakingSeedsHeight) or (self.age>=self.startMakingSeedsAge) or self.isMature: if self.isMature==True: self.makeSomeSeeds(theGarden.maxSeedsPerPlant, theGarden) @@ -179,10 +174,7 @@ def growPlant(self, theGarden): ###convert mass to get radius of leaf self.calcRadiusLeafFromMassLeaf() - #self.z=self.z+self.heightStem+self.heightLeafMax - #self.z=self.elevation+self.heightStem+self.heightLeafMax self.z=self.heightStem+self.heightLeafMax - #print "plant z: %f plant elevation: %f" % (self.z, self.elevation) if self.radiusLeaf>=self.radiusStem: self.r=self.radiusLeaf @@ -203,10 +195,6 @@ def makeSeed(self, theSeed, theGarden): theSeed=copy.deepcopy(self) theSeed.zeroSeedValues() theNameList= theSeed.name.split() - #if len(theNameList)<2: - # idNumb=str(random.random()) - #else: - # idNumb=theNameList[1] theMax=self.locSeedFormation[0] theMin=self.locSeedFormation[1] ###Check these values and fix them if they have weird values @@ -214,7 +202,7 @@ def makeSeed(self, theSeed, theGarden): if theMax<0.0: self.locSeedFormation[0]=0.0 if theMin>1.0: self.locSeedFormation[1]=1.0 if theMin<0.0: self.locSeedFormation[1]=0.0 - ### + theRadius=self.radiusLeaf r=theRadius*theMax delta=theRadius*theMin @@ -232,13 +220,12 @@ def makeSeed(self, theSeed, theGarden): elif dist==0.0: deltaY=0.0 else: - #deltaY=self.radiusLeaf-math.sqrt(abs((self.radiusLeaf*self.radiusLeaf)-(dist*dist))) + deltaY=self.radiusLeaf-((abs((self.radiusLeaf*self.radiusLeaf)-(dist*dist)))**0.5) seedZ=self.heightStem+(self.heightLeafMax/2.0)-deltaY else: seedZ=self.heightStem+(self.heightLeafMax/2.0) - #theSeed.name="growingSeed %s" % (idNumb) theSeed.name=str(uuid.uuid4()) theSeed.timeCreation=time.time() theSeed.motherPlant=self @@ -252,8 +239,6 @@ def makeSeed(self, theSeed, theGarden): #the seed elevation isn't the elevation if terrain at XY #it's the elevation of the terrain at the mother tree theSeed.z= seedZ+theSeed.motherPlant.elevation - #print(theSeed.motherPlant.elevation) - ########################################################### theSeed.r= theSeed.radiusSeed self.seedList.append(theSeed) @@ -269,12 +254,8 @@ def growSeedOnPlant(self, maxCarbonForSeed): #use that value to calculate the radius of the seed #convert mass to volume and the get the radius i= self.massSeed/self.densitySeed #this is volume in m^3 - #i=i/(4.0/3.0) i=i/1.3333 - #i=i/(math.pi) i=i/3.14 - #i=math.pow(i, 1.0/3.0) - #i=math.pow(i, 0.3333) i=i**0.3333 self.radiusSeed=i @@ -311,7 +292,6 @@ def disperseSeed(self, theSeed, motherPlant, theGarden): r=theRadius*theMax delta=theRadius*theMin r=(random.random()*(r-delta))+ delta - #twoPi=math.pi*2 twoPi=3.14*2 theAngle=(random.random()*(twoPi-0)+0) newX =r*math.cos(theAngle) @@ -330,7 +310,6 @@ def disperseSeed(self, theSeed, motherPlant, theGarden): theRise=theSeed.y-motherPlant.y theRun=theSeed.x-motherPlant.x theAngle=math.asin(theRise/theHypot) - #theAngle=math.degrees(theAngle) newX=math.cos(theAngle)*theDistance if theRun<0.0: newX=0.0-newX @@ -362,7 +341,6 @@ def disperseSeed(self, theSeed, motherPlant, theGarden): tempVar1= (v*math.cos(angle))/g tempVar2= (v*math.sin(angle)) - #tempVar3= math.sqrt((tempVar2*tempVar2)+(2*g*h)) tempVar3= ((tempVar2*tempVar2)+(2*g*h))**0.5 tempVar3= tempVar2+tempVar3 theDistance=tempVar1*tempVar3 @@ -389,7 +367,6 @@ def disperseSeed(self, theSeed, motherPlant, theGarden): #STH EKT 2020-0212 if theGarden.terrainImage!=[]: coordAdjust = theGarden.theWorldSize/2.0 - #thePixelValue = terrain_utils.getPixelValue(newX,newY,theGarden.terrainImage) thePixelValue = terrain_utils.getPixelValue(newX-coordAdjust,newY-coordAdjust,theGarden.terrainImage) theElevation = terrain_utils.elevationFromPixel(thePixelValue, theGarden.maxElevation) else: @@ -399,8 +376,6 @@ def disperseSeed(self, theSeed, motherPlant, theGarden): theMax = theDistance while newZ>theSeed.z + motherPlant.elevation: theTestDist = (theMin+theMax)/2.0 - #theSeed.radiusSeedMultiplier = 20.0 #visual debugging - #theSeed.colourSeedDispersed = [0.0, 0.0, 0.0] #visual debugging newX = (math.cos(theAngle)*theTestDist) if theRun<0.0: newX=(0.0-newX) newY = (math.sin(theAngle)*theTestDist) @@ -414,7 +389,6 @@ def disperseSeed(self, theSeed, motherPlant, theGarden): theMax = theTestDist if round(theMax,3) == round(theMin,3): break - #print "********seed %s be being placed at %f, %f" % (theSeed.name, newX, newY) ###Place the seed in xyz space correctly ###STH 2020-0226 theSeed.elevation = theElevation @@ -445,11 +419,6 @@ def germinate(self, theGarden): self.age=1 self.timeGermination=time.time() theNameList=self.name.split() - #if len(theNameList)<2: - #idNumb=str(random.random()) - #else: - #idNumb=theNameList[1] - #self.name="Plant %s" % (idNumb) ###update the garden theGarden.numbSeeds= theGarden.numbSeeds-1 theGarden.numbPlants= theGarden.numbPlants+1 @@ -471,8 +440,6 @@ def germinate(self, theGarden): ###will be in world_basics ###rename the seed so you know it's a plant - #self.z=self.z+self.heightStem+self.heightLeafMax - #self.z=self.elevation+self.heightStem+self.heightLeafMax self.z=self.heightStem+self.heightLeafMax ###why am I doing this, again? @@ -484,10 +451,7 @@ def germinate(self, theGarden): self.countToGerm=self.countToGerm-1 def calcNewMassFromLeaf(self, theGarden): - #print "mass stem: %s" % (self.massStem) - #print "mass leaf: %s" % (self.massLeaf) areaAvailable=self.areaPhotosynthesis-self.areaCovered - #print "Ap: %s" % (areaAvailable) if self.areaPhotosynthesis>0.0: fractionAvailable=areaAvailable/self.areaPhotosynthesis else: @@ -495,46 +459,19 @@ def calcNewMassFromLeaf(self, theGarden): if fractionAvailable>self.fractionMinimumSurvival: - #lightConversion=self.photoConstant*(self.massLeaf**self.photoExponent)#in units of kgGrowth/area leaf for photosynthesis - #newMass= (areaAvailable*lightConversion) var1=(self.massLeaf**self.photoExponent)#in units of kgGrowth/area leaf var1=areaAvailable*var1#in units of kgGrowth/area leaf - #var2=(self.photoConstant*fractionAvailable*self.waterGrowthFraction)+(self.photoConstantShade*(1-fractionAvailable)) var2=(self.photoConstant*fractionAvailable*self.waterGrowthFraction*self.droughtGrowthFraction)+(self.photoConstantShade*(1-fractionAvailable)) - #var2=(self.photoConstant*fractionAvailable+(self.photoConstantShade*(1-fractionAvailable))) - #print "%s: %s" % (self, var2) newMass=var2*var1 - #print("*****") - #print(newMass) #New property related to water tolerance #0329-2021 STH - #if theGarden.terrainImage!=[] and theGarden.waterLevel>0.0: - # newMass=newMass*self.waterGrowthFraction - #print(newMass) - #print("*****") - ###decide whether canopy transmission impacts conversion - # alterMassWitTransmission=0 - # if theGarden.canopyTransmittanceImpactsConversion==1: - # alterMassWitTransmission=1 - # elif theGarden.canopyTransmittanceImpactsConversion==0: - # alterMassWitTransmission=0 - # else: - # if self.canopyTransmittanceImpactsConversion: - # alterMassWitTransmission=1 - # else: - # alterMassWitTransmission=0 - - # if alterMassWitTransmission==1: - # newMass=newMass*(1-self.canopyTransmittance) - # #print "mass new: %s" % (newMass) return newMass else: return -1.0 def calcMassStemFromMassNew(self): massNew=self.massFixed - #GMs=self.speciesConstant1*math.pow(massNew, self.speciesExponent1) GMs=self.speciesConstant1*(massNew**self.speciesExponent1) massStem=self.massStem+GMs self.GMs=GMs @@ -546,17 +483,10 @@ def calcMassLeafFromMassStem(self): massStem=self.massStem massTotal=self.massTotal+massNew if (self.age>=self.startMakingSeedsAge) or self.isMature==True: - #massLeaf=self.speciesConstant3*(math.pow(massStem, self.speciesExponent3)) massLeaf=self.speciesConstant3*(massStem**self.speciesExponent3) - #print "mature at: %i" % (self.age) else: - #massLeaf=self.speciesConstant2*(math.pow(massStem, self.speciesExponent2)) massLeaf=self.speciesConstant2*(massStem**self.speciesExponent2) - #print "young" - #if not massStem+massLeaf==massTotal: ###something went wonky with calcs. - #print "Age: %i a bit off: %f" % (self.age, massTotal-massStem-massLeaf) - #massLeaf=massTotal-massStem self.GMl=massLeaf-self.massLeaf self.massLeaf=massLeaf @@ -573,13 +503,11 @@ def calcRadiusLeafFromMassLeaf(self): def calcRadiusStemFromMassStem(self): Ms=self.massStem - #Ds=self.speciesConstant20*math.pow(Ms,self.speciesExponent20) Ds=self.speciesConstant20*(Ms**self.speciesExponent20) Rs=Ds/2.0 self.GRs=Rs-self.radiusStem self.radiusStem=Rs if debug==1:print(" calcRadiusStemFromMassStem: Radius of stem is %f" % (self.radiusStem)) - #print " calcRadiusStemFromMassStem: Radius of stem is %f" % (self.radiusStem) def calcHeightStemFromRadiusStem(self, theGarden): Ds=self.radiusStem*2 @@ -625,7 +553,6 @@ def makeSomeSeeds(self, maxSeedsPerPlant, theGarden): avgMassFixed=theNum/theDenom ###see code from 2008.10.05 for attempts at having seed mass change as plant size increases. maxKgSeeds=self.reproductionConstant*(self.massFixed**self.reproductionExponent) - #maxKgSeeds=self.reproductionConstant*(self.massFixed**self.reproductionExponent) adjMaxKgSeeds=maxKgSeeds*self.fractionCarbonToSeeds #the adjMaxKgSeeds makes use of how selfish a plant is (fractionCarbonToSeeds) to either ###use all of the possible seed carbon for seeds, or some fraction there of. @@ -633,7 +560,6 @@ def makeSomeSeeds(self, maxSeedsPerPlant, theGarden): ###if the plant is suddenly stressed, adjust how it is making seeds theFractDifference=self.massFixed/avgMassFixed if theFractDifference. -""" - -import sys -import math -import time -import copy -import random -###append the path to basic data files -sys.path.append("Vida_Data") -import geometry_utils -import yaml - -debug=0 - -#class genericPlant(object): -class genericPlant(object): - ###define the props on this object - def __init__(self): - ### if the object lacks a certain property, it has not imported the basic prefs - if not hasattr(self, "massSeedMax"): - fileLoc="Vida_Data/Default_species.yml" - self.importPrefs(fileLoc) - self.zeroSeedValues() - - - def zeroSeedValues(self): - ###these values are set during the simulation - self.name="" - self.isSeed=True - self.isMature=False - self.timeCreation=0 - self.timeGermination=0 - self.timePlanted=0 - self.massStem=0.0 #kg - self.massLeaf=0.0 #kg - self.massSeed=0.0 #kg - self.massTotal=0.0 #kg - - self.massFixed=-0.0 #kg - self.massFixedRecord=[]#list of kg - - self.massSeedsTotal=0.0 #kg - self.heightStem=0.0 - self.radiusStem=0.0 #meters - self.radiusLeaf=0.0 #meters - self.radiusSeed=0.0 #radius in meters - self.areaPhotosynthesis=0.0#meters^2 - self.areaCovered=0.0#meters^2 - self.fractionAreaCovered=0.0 - self.seedList=[] - self.motherPlant=0 - self.countToGerm=0.0 - - self.prevHeightGrowthRate=0.0 - self.heightGrowthRate=[] - self.avgHeightGrowthRate=0.0 - self.maxAvgHeightGrowthRate=0.0 - - self.GHs=0.0 #change in Height. In meters. - self.GRs=0.0 #change in radius of stem. In meters. - self.GMs=0.0 #change in mass of stem. In kg. - self.GMl=0.0 #change in mass of leaves. In kg. - - self.causeOfDeath="" - ###World data - self.x=0.0 - self.y=0.0 - self.z=0.0 - self.r=0.00 - self.age=0.0 - self.overlapList=[] - self.colourLeaf[2]=1.0 - #fileLoc="Vida_Data/Default_species.yml" - #self.importPrefs(fileLoc) - - def importPrefs(self, fileLoc): - theFile=open(fileLoc) - theData=yaml.load(theFile) - theFile.close - for key in theData: - setattr(self, key, theData[key]) - - def dieNow(self, thePlant, theGarden): - #die! - #print len(thePlant.seedList) - #print "hmmm" - if len(thePlant.seedList)>0: - for theSeed in thePlant.seedList: - ###The plant has seeds. Drop them prior to killing plant### - ###just drop the seed straight down### - #print "********seed %s be being placed at %f, %f" % (theSeed.name, newX, newY) - theSeed.countToGerm=self.delayInGermination - theGarden.plantSeed(theSeed) - thePlant.seedList.remove(theSeed) - thePlant.seedList=[] - theGarden.soil.remove(self) - if self.isSeed: - theGarden.numbSeeds= theGarden.numbSeeds-1 - else: - theGarden.numbPlants=theGarden.numbPlants-1 - - - def growPlant(self, theGarden): - ##if you have attached seeds, allow them to grow - tempList=copy.copy(self.seedList) - if self.makeSeeds: - numbSeeds=float(len(tempList)) - self.massSeedsTotal=0 - if numbSeeds>0.0: - maxCarbonToSeed=(self.massFixed*self.fractionCarbonToSeeds) - maxCarbonToSeed=maxCarbonToSeed/numbSeeds - for attachedSeed in tempList: - if self.massFixed<=0.0: - break - ###I don't like this much - #it gives a base amount of mass to the seed - #+/- a random amount - sign=random.random() - theVarient=(random.random()*(maxCarbonToSeed-0)+0) - if sign>0.5: - ###Don't give the seed more than you have - carbonToSeed = maxCarbonToSeed +theVarient - if carbonToSeed>self.massFixed: - carbonToSeed=self.massFixed - else: - carbonToSeed = maxCarbonToSeed -theVarient - attachedSeed.growSeedOnPlant(carbonToSeed) - ###if the seed is the max size, disperse it - if attachedSeed.massSeed>=attachedSeed.massSeedMax: - attachedSeed.disperseSeed(attachedSeed, self, theGarden) - else: - self.massSeedsTotal=self.massSeedsTotal+attachedSeed.massSeed - #print "plant %f" % (self.massSeedsTotal) - - ##if you lack seeds, make them - if (self.heightStem>=self.startMakingSeedsHeight) or (self.age>=self.startMakingSeedsAge) or self.isMature: - #print self.age - self.makeSomeSeeds() - #make a seed on yourself if you don't have the max number of seeds - ###I'm using area here vs area of photosynthesis because for single, unshaded plants, this is the same - #areaLeaf=3.14*self.radiusLeaf*self.radiusLeaf - #if self.leafIsHemisphere: - # areaLeaf=areaLeaf*2.0 - #maxKgSeeds=self.reproductionConstant*math.pow(areaLeaf, self.reproductionExponent) - #currentKgMatureSeeds=numbSeeds*self.massSeedMax - #while (numbSeeds*self.massSeedMax) < maxKgSeeds: - # self.makeSeed(self) - # numbSeeds=float(len(self.seedList)) - #### - ##let yourself grow - self.calcMassStemFromMassNew() - - self.calcRadiusStemFromMassStem() - - self.calcHeightStemFromRadiusStem(theGarden) - - self.calcMassLeafFromMassStem() - - self.massTotal=self.massLeaf+self.massStem+self.massSeedsTotal - - ###convert mass to get radius of leaf - self.calcRadiusLeafFromMassLeaf() - - self.z=self.heightStem+self.heightLeafMax - - if self.radiusLeaf>=self.radiusStem: - self.r=self.radiusLeaf - else: - self.r=self.radiusStem - #save the changes in height over time - self.heightGrowthRate.append(self.heightStem-self.prevHeightGrowthRate) - self.prevHeightGrowthRate=self.heightStem - while len(self.heightGrowthRate)>self.numYearsGrowthMemory: - self.heightGrowthRate.pop(0) - self.avgHeightGrowthRate=sum(self.heightGrowthRate)/float(len(self.heightGrowthRate)) - if self.avgHeightGrowthRate>self.maxAvgHeightGrowthRate: - self.maxAvgHeightGrowthRate=self.avgHeightGrowthRate - self.age=self.age+1 - - - def makeSeed(self, theSeed): - theSeed=copy.deepcopy(self) - theSeed.zeroSeedValues() - theNameList= theSeed.name.split() - if len(theNameList)<2: - idNumb=str(random.random()) - else: - idNumb=theNameList[1] - theMax=self.locSeedFormation[0] - theMin=self.locSeedFormation[1] - ###Check these values and fix them if they have weird values - if theMax>1.0: self.locSeedFormation[0]=1.0 - if theMax<0.0: self.locSeedFormation[0]=0.0 - if theMin>1.0: self.locSeedFormation[1]=1.0 - if theMin<0.0: self.locSeedFormation[1]=0.0 - ### - theRadius=self.radiusLeaf - r=theRadius*theMax - delta=theRadius*theMin - r=(random.random()*(r-delta))+ delta - twoPi=3.14*2 - theAngle=(random.random()*(twoPi-0)+0) - seedX=r*math.cos(theAngle) - seedY=r*math.sin(theAngle) - theSeed.x= seedX +self.x - theSeed.y= seedY +self.y - if self.leafIsHemisphere: - dist=geometry_utils.distBetweenPoints(seedX+self.x, seedY+self.y, self.x, self.y) - if dist==self.radiusLeaf: - deltaY=self.radiusLeaf - elif dist==0.0: - deltaY=0.0 - else: - deltaY=self.radiusLeaf-math.sqrt(abs(math.pow(self.radiusLeaf,2.0)-math.pow(dist,2.0))) - seedZ=self.heightStem+(self.heightLeafMax/2.0)-deltaY - else: - seedZ=self.heightStem+(self.heightLeafMax/2.0) - - theSeed.name="growingSeed %s" % (idNumb) - theSeed.timeCreation=time.time() - theSeed.motherPlant=self - theSeed.x= seedX +self.x - theSeed.y= seedY +self.y - theSeed.z= seedZ - theSeed.r= theSeed.radiusSeed - self.seedList.append(theSeed) - - def growSeedOnPlant(self, maxCarbonForSeed): - if maxCarbonForSeed > self.motherPlant.massSeedMax: - maxCarbonForSeed =self.motherPlant.massSeedMax - if not self.motherPlant.massFixed==-0.0: - if maxCarbonForSeed>self.motherPlant.massFixed: - maxCarbonForSeed=self.motherPlant.massFixed - self.motherPlant.massFixed=self.motherPlant.massFixed-maxCarbonForSeed - self.massSeed= self. massSeed + maxCarbonForSeed - #use that value to calculate the radius of the seed - #convert mass to volume and the get the radius - i= self.massSeed/self.densitySeed #this is volume in m^3 - #i=i/(4.0/3.0) - i=i/1.3333 - #i=i/(math.pi) - i=i/3.14 - #i=math.pow(i, 1.0/3.0) - i=math.pow(i, 0.3333) - self.radiusSeed=i - - ###need to move the seed as the plant grows### - if self.motherPlant.leafIsHemisphere: - dist=geometry_utils.distBetweenPoints(self.x, self.y, self.motherPlant.x, self.motherPlant.y) - if dist==self.motherPlant.radiusLeaf: - deltaY=self.motherPlant.radiusLeaf - elif dist==0.0: - deltaY=0.0 - else: - deltaY=self.motherPlant.radiusLeaf-math.sqrt(abs(math.pow(self.motherPlant.radiusLeaf,2.0)-math.pow(dist,2.0))) - seedZ=self.motherPlant.heightStem+(self.motherPlant.heightLeafMax/2.0)-deltaY - else: - seedZ=self.motherPlant.heightStem+(self.motherPlant.heightLeafMax/2.0) - self.z= seedZ - self.r= self.radiusSeed - - def disperseSeed(self, theSeed, motherPlant, theGarden): - ###this dispersal method needs to be better - if motherPlant.seedDispersalMethod[0]==0: - ###This is just random anywhere in world### - newX =random.randrange(-(theGarden.theWorldSize/2),(theGarden.theWorldSize/2))+random.random() - newY =random.randrange(-(theGarden.theWorldSize/2),(theGarden.theWorldSize/2))+random.random() - elif motherPlant.seedDispersalMethod[0]==1: - ###just drop the seed straight down### - newX=theSeed.x - newY=theSeed.y - elif motherPlant.seedDispersalMethod[0]==2: - ###drop the seed in a circle with a defined max radius### - theRadius=motherPlant.seedDispersalMethod[1] - theMax=1 - theMin=0 - r=theRadius*theMax - delta=theRadius*theMin - r=(random.random()*(r-delta))+ delta - #twoPi=math.pi*2 - twoPi=3.14*2 - theAngle=(random.random()*(twoPi-0)+0) - newX =r*math.cos(theAngle) - newY =r*math.sin(theAngle) - newX = newX + theSeed.x - newY = newY + theSeed.y - elif motherPlant.seedDispersalMethod[0]==3: - ###eject the seed straight out from leaf, traveling a defined max distance### - maxDistance=motherPlant.seedDispersalMethod[1] - theMax=1 - theMin=0 - theDistance= maxDistance*theMax - delta= maxDistance*theMin - theDistance =(random.random()*(theDistance-delta))+ delta - theHypot=geometry_utils.distBetweenPoints(motherPlant.x, motherPlant.y, theSeed.x, theSeed.y) - theRise=theSeed.y-motherPlant.y - theRun=theSeed.x-motherPlant.x - theAngle=math.asin(theRise/theHypot) - #theAngle=math.degrees(theAngle) - newX=math.cos(theAngle)*theDistance - if theRun<0.0: - newX=0.0-newX - newY=math.sin(theAngle)*theDistance - newX=newX+theSeed.x - newY=newY+theSeed.y - elif motherPlant.seedDispersalMethod[0]==4: - ###get a random angle based on input### - angle=motherPlant.seedDispersalMethod[1] - theVariance=(random.random()*((angle*0.5)-0.0))+ 0.0 - if random.random()>0.5: - theVariance=0-theVariance - angle=angle+theVariance - angle=math.radians(angle) - - ###get a random velocity based on input### - ####it would be nicer to use a force so seed size influences things too - v=motherPlant.seedDispersalMethod[2] - theVariance=(random.random()*((v*0.5)-0.0))+ 0.0 - if random.random()>0.5: - theVariance=0-theVariance - v=v+theVariance - - g=theGarden.gravity - h=motherPlant.heightStem+motherPlant.heightLeafMax - - tempVar1= (v*math.cos(angle))/g - tempVar2= (v*math.sin(angle)) - tempVar3= math.sqrt(math.pow(tempVar2, 2.0)+(2*g*h)) - tempVar3= tempVar2+tempVar3 - theDistance=tempVar1*tempVar3 - theHypot=geometry_utils.distBetweenPoints(motherPlant.x, motherPlant.y, theSeed.x, theSeed.y) - theRise=theSeed.y-motherPlant.y - theRun=theSeed.x-motherPlant.x - theAngle=math.asin(theRise/theHypot) - newX=math.cos(theAngle)*theDistance - if theRun<0.0: - newX=0.0-newX - newY=math.sin(theAngle)*theDistance - newX=newX+theSeed.x - newY=newY+theSeed.y - - - #print "********seed %s be being placed at %f, %f" % (theSeed.name, newX, newY) - theSeed.x=newX - theSeed.y=newY - theSeed.countToGerm=self.delayInGermination - theGarden.plantSeed(theSeed) - motherPlant.seedList.remove(theSeed) - - def germinate(self, theGarden): - if self.countToGerm<1: - ###death due to failure to germinate - tooBad=random.random() - if theGarden.cycleNumber==0 and theGarden.ignoreGermDeathAtStart: - tooBad=1.0 - if tooBad=self.radiusStem: - self.r=self.radiusLeaf - else: - self.r=self.radiusStem - else: - self.countToGerm=self.countToGerm-1 - - def calcNewMassFromLeaf(self, theGarden): - #print "mass stem: %s" % (self.massStem) - #print "mass leaf: %s" % (self.massLeaf) - areaAvailable=self.areaPhotosynthesis-self.areaCovered - #print "Ap: %s" % (areaAvailable) - if self.areaPhotosynthesis>0.0: - fractionAvailable=areaAvailable/self.areaPhotosynthesis - else: - fractionAvailable=0.0 - if fractionAvailable>self.fractionMinimumSurvival: - lightConversion=self.photoConstant*(math.pow(self.massLeaf, self.photoExponent))#in units of kgGrowth/area leaf for photosynthesis - newMass= (areaAvailable*lightConversion) - ###decide whether canopy transmission impacts conversion - alterMassWitTransmission=0 - if theGarden.canopyTransmittanceImpactsConversion==1: - alterMassWitTransmission=1 - elif theGarden.canopyTransmittanceImpactsConversion==0: - alterMassWitTransmission=0 - else: - if self.canopyTransmittanceImpactsConversion: - alterMassWitTransmission=1 - else: - alterMassWitTransmission=0 - if alterMassWitTransmission==1: - newMass=newMass*(1-self.canopyTransmittance) - #print "mass new: %s" % (newMass) - return newMass - else: - return -1.0 - - def calcMassStemFromMassNew(self): - massNew=self.massFixed - GMs=self.speciesConstant1*math.pow(massNew, self.speciesExponent1) - massStem=self.massStem+GMs - self.GMs=GMs - self.massStem=massStem - - def calcMassLeafFromMassStem(self): - massLeaf=self.massLeaf - massNew=self.massFixed - massStem=self.massStem - massTotal=self.massTotal+massNew - if (self.age>=self.startMakingSeedsAge) or self.isMature: - massLeaf=self.speciesConstant3*(math.pow(massStem, self.speciesExponent3)) - #print "mature at: %i" % (self.age) - else: - massLeaf=self.speciesConstant2*(math.pow(massStem, self.speciesExponent2)) - #print "young" - #if not massStem+massLeaf>massTotal: - # ##something went wonky with calcs. - # print "Age: %i expected Ml: %f actual Ml: %f" % (self.age, massTotal-massStem, massLeaf) - # massLeaf=massTotal-massStem - self.GMl=massLeaf-self.massLeaf - self.massLeaf=massLeaf - - - def calcRadiusLeafFromMassLeaf(self): - leafVolume=self.massLeaf/self.densityLeaf - leafAreaDisc=leafVolume/self.heightLeafMax - #####used in trying to get seed later on - self.leafAreaDisc=leafAreaDisc - ###### - leafRadius= geometry_utils.radiusCircle(leafAreaDisc) - if self.leafIsHemisphere: - leafRadius=leafRadius*0.7071067812 - self.radiusLeaf=leafRadius - self.areaPhotosynthesis =3.14*leafRadius*leafRadius - if debug==1:print " calcRadiusLeafFromMassLeaf: Radius of Leaf is %f" % (self.radiusLeaf) - - def calcRadiusStemFromMassStem(self): - Ms=self.massStem - Ds=self.speciesConstant20*math.pow(Ms,self.speciesExponent20) - Rs=Ds/2.0 - self.GRs=Rs-self.radiusStem - self.radiusStem=Rs - if debug==1:print " calcRadiusStemFromMassStem: Radius of stem is %f" % (self.radiusStem) - #print " calcRadiusStemFromMassStem: Radius of stem is %f" % (self.radiusStem) - - def calcHeightStemFromRadiusStem(self, theGarden): - Ds=self.radiusStem*2 - #mature allocation method - ###experiment with deriving alpha### - #var0=self.heightStem+self.speciesConstant6 - #if var0>0.0: - # var1=math.log(var0) - # var2=math.log(self.speciesConstant7) - # var3=math.log(Ds) - # calc1=(var1-var2)/var3 - # - # print "cycle: %i calculation: %f exponent: %f" % (theGarden.cycleNumber, calc1, self.speciesExponent7) - - Hs=(self.speciesConstant8*math.log(Ds))+self.heightStemMax - if HsfractionTolerance: growthFraction = 1.0 else: @@ -90,11 +83,9 @@ def determineDroughtTol(theGarden): theExponent=-((((distFromWater-maxValue)*0.05)**2.0)/((2.0*stddev)**2.0)) growthFraction=((1.0/(stddev*(twoPi**0.5)))*2.71)**theExponent - #print("%s,%s,%s,%s" % (distFromWater, fractionWater, fractionTolerance, growthFraction)) obj.droughtGrowthFraction = growthFraction if round(growthFraction,5) == 0.0: obj.causeOfDeath="drought" - #print("here") theGarden.kill(obj) def determineShade(theGarden): @@ -125,10 +116,6 @@ def determineShade(theGarden): 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") - ###use absHeightStem, which is stem heigh + elevetion - ###STH 2021.0305 plantOne.overlapList = list_utils.sort_by_attr(plantOne.overlapList, "absHeightStem") ###flip the list so it's ordered tallest to shortest plantOne.overlapList.reverse() @@ -158,9 +145,8 @@ def determineShade(theGarden): 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 + #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 @@ -178,11 +164,10 @@ def determineShade(theGarden): 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): @@ -197,14 +182,12 @@ def determineShade(theGarden): 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 @@ -251,7 +234,6 @@ def makePlatonicSeedDict(self, ymlList, Species1): theSeed=Species1() fileLoc= "Species/"+ymlList[i] theSeed.importPrefs(fileLoc) - #theSeed.name="Platonic %s" % (ymlList[i]) theGarden.platonicSeeds[ymlList[i]]=theSeed i=i+1 @@ -260,12 +242,7 @@ 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) theSeed.name=str(uuid.uuid4()) if theSeed.motherPlant==0: theSeed.motherPlant=theSeed @@ -273,12 +250,8 @@ def plantSeed(self, 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 + for aRegion in theGarden.theRegions: if aRegion.shape=='square': inSubregion=geometry_utils.pointInsideSquare(aRegion.x, aRegion.y, aRegion.size, theSeed.x, theSeed.y) elif aRegion.shape=='circle': @@ -321,32 +294,13 @@ def calcEulerGreenhill(self, plant): g=plant.subregion[-1].gravity else: g=theGarden.gravity - #r=plant.radiusStem - #z=plant.z - #Pacr=(math.pow(math.pi, 3)/16.0)*(math.pow(r, 4)/math.pow(z, 2))*E heightCritical= 0.79*((E/(g*ps))**0.3333)*(Ds**0.6667) - #massCritical=0.785*ps*heightCritical*Ds*Ds - #forceCritical=0.483736625*E*(Ds*Ds*Ds*Ds) - #denom=(2.0*heightCritical)*(2.0*heightCritical) - #forceCritical=forceCritical/denom return heightCritical def checkEulerGreenhillViolation(self, plant): theGarden=self if plant.isSeed==1: return 0 #don't check it if it's a seed. - #theGravity=theGarden.gravity - #if len(plant.subregion)>0: - # theGravity=plant.subregion[-1].gravity - #determine if a plant violates the Euler-Greenhill rule - #ps=plant.densityStem - #Ds=plant.radiusStem*2.0 heightCritical=self.calcEulerGreenhill(plant) - ### - #massCritical=0.785*ps*heightCritical*Ds*Ds - #forceCritical=massCritical*theGravity - #massTotal=plant.massTotal+plant.massSeedsTotal - #theForce=massTotal*theGravity - #if plant.heightStem>=heightCritical or massTotal>=massCritical or theForce>= forceCritical: if plant.heightStem>=heightCritical: #omg! violates euler-greenhill! return 1 @@ -489,7 +443,6 @@ def checkSubmergedMortality(self): #world maxSubmerged value. Maybe this should be a species specific value #but for now it is a global #STH 2023-0524 - #print("plant partly submerged. die!") obj.causeOfDeath="submerged in water" theGarden.kill(obj) @@ -574,7 +527,6 @@ def checkDistanceMortality(self): print("***Checking for mortality due to proximity to mother...***") theProgressBar= progressBarClass.progressbarClass(len(theGarden.soil),"*") i=0 - #print "Name : Distance : Chance" for obj in theGarden.soil[:]: if not obj.isSeed: twoPi=2.0*3.14 @@ -584,7 +536,6 @@ def checkDistanceMortality(self): if theDistance>0.0: theExponent=-(((theDistance-theAvg)**2.0)/((2.0*stddev)**2.0)) theDeathChance=((1/(stddev*(twoPi**0.5)))*2.71)**theExponent - #print "%s : %s :%s" % (obj.name, theDistance, theDeathChance) tooBad=random.random() if tooBad0: theIndex=0 - #print sList for i in range(startPopulationSize): countToGerm=0 theSpeciesFile="" @@ -660,14 +609,12 @@ def placeSeed(self, seedPlacement, sList, startPopulationSize, useDefaultYml, ym prevY= prevY-seedDistance else: prevX=x - - #print theSpeciesFile + if useDefaultYml==False or theSpeciesFile=="": if theSpeciesFile=="" or theSpeciesFile=="_random_": whichSpecies=random.randint(0,len(ymlList)-1)##pick from the species randomly fileLoc= "Species/"+ymlList[whichSpecies] theSpeciesFile=ymlList[whichSpecies] - #print theSpeciesFile if (sys.version_info.major)==2: if theGarden.platonicSeeds.has_key(theSpeciesFile): platonicSeed=theGarden.platonicSeeds[theSpeciesFile] @@ -676,14 +623,10 @@ def placeSeed(self, seedPlacement, sList, startPopulationSize, useDefaultYml, ym if theSpeciesFile in theGarden.platonicSeeds: platonicSeed=theGarden.platonicSeeds[theSpeciesFile] theSeed=copy.deepcopy(platonicSeed) - - #else: - #print "something is very wrong" else: #if there are no species listed, use the default species. - theSeed=Species1() - theSeed=theGarden.plantSeed(theSeed) - #print theSeed.subregion + theSeed=vex.Species1() + theSeed=theGarden.plantSeed(theSeed) #now set some attributes theSeed.timeCreation=time.time() theSeed.countToGerm=countToGerm @@ -700,8 +643,6 @@ def placeSeed(self, seedPlacement, sList, startPopulationSize, useDefaultYml, ym #print terrainFile theSeed.radiusSeed=j theSeed.z= theSeed.radiusSeed - #theSeed.z = theSeed.z + random.randrange(1,50) - #look up the pixel grey-scale value at the target x,y #and then use that value to map to an elevation #STH EKT 0212-2020 @@ -711,17 +652,12 @@ def placeSeed(self, seedPlacement, sList, startPopulationSize, useDefaultYml, ym theAdjY = theSeed.y + coordAdjust thePixelValue = terrain_utils.getPixelValue(theAdjX,theAdjY,theGarden.terrainImage) theElevation = terrain_utils.elevationFromPixel(thePixelValue, theGarden.maxElevation) - #print("%s seedX: %s seedY: %s coordAdjust: %s xpixel: %s thePixelValue: %s theElevation: %s" % (theGarden.terrainImage[1], theSeed.x, theSeed.y, coordAdjust, (theSeed.x-coordAdjust), thePixelValue, theElevation)) else: theElevation = 0.0 theSeed.elevation = theElevation theSeed.z = theSeed.z + theSeed.elevation theSeed.r= theSeed.radiusSeed - #theSeed.growSeedOnPlant(theSeed.massSeedMax) - #print "#######" - #print theSeed.__class__().name - #print "#######" #update the progress meter if theGarden.showProgressBar or theGarden.cycleNumber<1: theProgressBar.update(i) diff --git a/requirements.txt b/requirements.txt index 3821743..b5a00f2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ pandas PyYAML xlrd openpyxl +cherrypy diff --git a/tools/PlacementFileMaker.py b/tools/PlacementFileMaker.py index 236dd23..7f88441 100644 --- a/tools/PlacementFileMaker.py +++ b/tools/PlacementFileMaker.py @@ -19,6 +19,5 @@ for x in xrange(width): for y in xrange(height): if im.getpixel((x,y))<=50: - #print >> out, "%s, %s, %s" % (x-(width/2.0),y-(height/2.0),im.getpixel((x,y))) print >> out, "random, %f, %f, 0" % (x-(width/2.0),y-(height/2.0)) out.close() \ No newline at end of file diff --git a/tools/miniVida2yml/miniVida2yml.py b/tools/miniVida2yml/miniVida2yml.py index ea8135b..9c5e873 100644 --- a/tools/miniVida2yml/miniVida2yml.py +++ b/tools/miniVida2yml/miniVida2yml.py @@ -28,90 +28,61 @@ def get_cli(): #Ms=B1*Mt^a1 B1=firstSheet.cell(2,2).value A1=firstSheet.cell(3,2).value - # print B1 - # print A1 #Canopy mass(young) from woody mass #Mlyoung=B2*Ms^a2 B2=firstSheet.cell(6,2).value A2=firstSheet.cell(7,2).value - # print B2 - # print A2 - #Canopy mass(mature) from woody mass #Mlmature=B3*Ms^a3 B3=firstSheet.cell(10,2).value A3=firstSheet.cell(11,2).value - # print B3 - # print A3 - #Woody diameter from woody mass #Ds=B4*Ms^a4 B4=firstSheet.cell(14,2).value A4=firstSheet.cell(15,2).value - # print B4 - # print A4 - #Tree height(young) from woody diameter #Hsyoung=(B5*Ds^a5)-B6 B5=firstSheet.cell(18,2).value A5=firstSheet.cell(19,2).value B6=firstSheet.cell(20,2).value - # print B5 - # print A5 - # print B6 - #Tree height(mature) from woody diameter #Hsmature=B7 + B8 ln Ds B7=firstSheet.cell(23,2).value B8=firstSheet.cell(24,2).value - # print B7 - # print B8 - #Total growth from projected area and canopy mass #Gt=Alprojected*[B9*(Ml^a6)] B9 = firstSheet.cell(27,2).value A6 = firstSheet.cell(28,2).value - # print B9 - # print A6 - #IdealSeedlingMass seedMass = firstSheet.cell(30,2).value - # print seedMass #DensityLeaf: densityLeaf = firstSheet.cell(31,2).value - # print densityLeaf #DensityStem: densityStem = firstSheet.cell(32,2).value - # print densityStem #YoungsModStem: youngsModulusStem = firstSheet.cell(33,2).value - # print youngsModulusStem #HeightLeaf: heightLeaf = firstSheet.cell(34,2).value - # print heightLeaf #fractStem@germ: fractStem = firstSheet.cell(36,2).value - # print fractStem #waterlogging: waterloggingTol = firstSheet.cell(38,2).value - #print(waterloggingTol) #drought tolerance: droughtTol = firstSheet.cell(39,2).value - #print(droughtTol) theYear = datetime.date.today().year @@ -125,7 +96,6 @@ def get_cli(): ymlTempTxt = ymlTempTxt % (shortBaseName, scriptName, theBaseName, theCreationDate, densityStem, densityLeaf, densityStem/2.0, heightLeaf, B7, youngsModulusStem, B9, A6, fractStem, B1, A1, B2, A2, B3, A3, B4, A4, B6, B5, A5, B8, waterloggingTol, droughtTol) - #print ymlTempTxt theOutFile = open(args.outFile, "w") theOutFile.write(ymlTempTxt) diff --git a/tools/pixelCount.py b/tools/pixelCount.py index bd872da..fb9c85b 100644 --- a/tools/pixelCount.py +++ b/tools/pixelCount.py @@ -7,8 +7,8 @@ def main(theFolder): thePath=theFolder+"/Graphics/bottom-up/" fileList=os.listdir(thePath) - print "***Checking for image files...***" - print"\nImage #, # of Pixels" + print ("***Checking for image files...***") + print("\nImage #, # of Pixels") showAll=True #turn this into an argument for file in fileList: theExtension=os.path.splitext(file)[1] @@ -23,18 +23,14 @@ def main(theFolder): for i in list(theImg): if i==theRGB: theCount=theCount+1 - print "%s, %s" % (theNumber, theCount) + print ("%s, %s") % (theNumber, theCount) else: theImg=Image.open(thePath+file).getdata() theCount=0 for i in list(theImg): if i==theRGB: theCount=theCount+1 - print "%s, %s" % (theNumber, theCount) - - - - #print "%s" % (theNumber) + print ("%s, %s") % (theNumber, theCount) if __name__ == '__main__': theArguments=sys.argv @@ -43,5 +39,5 @@ def main(theFolder): theFolder=theArguments[loc+1] main(theFolder) else: - print " Requires a -f option followed by a path to a Vida output folder" - print " Example: python pixelCount.py -f /path/to/data/Output-Example" + print (" Requires a -f option followed by a path to a Vida output folder") + print (" Example: python pixelCount.py -f /path/to/data/Output-Example")