Пример #1
0
	def __init__(self, G=None, vis=True, anim=False, head='BC',nCranes=2,series=None, bundler=False, twigCrack=False, observer=False):
		SimExtend.__init__(self,G, vis, anim, animDelay=1.2,series=series) #does some common stuff, e.g. seed

		#if no file to read the simulationsparameters from:
		setDefaultThinningParams(self.G.simParam) #sets the parameters to default values
			
		if not self.G.terrain:
			self.G.areaPoly=[(0,0), (25,0), (25,40), (0,40)] #default for thinning files.
			self.G.terrain=Terrain(G=self.G)
			self.G.terrain.readTrees(thinning=True)
		craneMax=self.G.simParam['maxCraneLength']
		startPos=[random.uniform(craneMax, 25-craneMax), -4]
		self.m=ThinningMachine(name="thinny", sim=self, G=self.G, head=head, nCranes=nCranes,startPos=startPos, bundler=bundler,twigCrack=twigCrack)
		self.treeStats() #do some statistics on the trees
		self.activate(self.m,self.m.run())
		if observer:
			self.o=Observer(name="obsy", sim=self, G=self.G)
			self.activate(self.o, self.o.run())
		self.simulate(until=10000)
		#some simulation information:
		if observer:
			self.timeStats()
			"""
			print self.o.tstep*sum([c[1] for c in self.o.lAMoni]), 'left head active time via monitor'
			print self.o.tstep*sum([c[1] for c in self.o.lWBMoni]), 'left head waiting for Bundler'
			print self.stats['oneCraneWorkTime'], 'one crane work time'
			print self.stats['oneCraneWaitDriverTime'], 'one crane wait for driver time'
			if self.m.hasBundler:
				print self.stats['oneCraneWaitBundlerTime'], 'one crane wait for bundler time'
			if len(self.m.heads)==2:
				print self.o.tstep*sum([c[1] for c in self.o.rAMoni]), 'right head active time via monitor'
				print self.o.tstep*sum([c[1] for c in self.o.rWBMoni]), 'right head waiting for Bundler'
				print self.stats['twoCranesWorkTime'], 'two cranes work time'
				print self.stats['twoCranesWaitDriverTime'], 'two cranes wait for driver time'
				if self.m.hasBundler:
					print self.stats['twoCranesWaitBundlerTime'], 'two cranes wait for bundler time'
			"""
		self.stats['productivity']=len(self.m.trees)/self.now()*3600
		self.stats['outTake']=100*len(self.m.trees)/float(len(self.G.terrain.trees))
		self.stats['groundAreaRatio']=sum([t.dbh**2*pi*0.25 for t in self.m.trees])/max(1,sum([t.dbh**2*pi*0.25 for t in self.G.terrain.trees]))
		
		print "Simulation ended. Productivity: %.1f trees/hour. %.1f %% of the trees were harvested"%(len(self.m.trees)/self.now()*3600, self.stats['outTake'])
		print "average trees per corridor: %f average log weight in corridor: %f trees in main road: %f"%(self.avTreesPerCorr, self.avCorrTreeWeight, self.treesPerRoad)
		self.setQueuePerc()
		print self.getGeneralStatsString()
		if self.p: #plot
			self.p.terminate()
			if vis: plt.show()
Пример #2
0
class ThinningSim(SimExtend):
	"""
	class for a single simulation with a 1a or 2a thinning machine
	"""
	def __init__(self, G=None, vis=True, anim=False, head='BC',nCranes=2,series=None, bundler=False, twigCrack=False, observer=False):
		SimExtend.__init__(self,G, vis, anim, animDelay=1.2,series=series) #does some common stuff, e.g. seed

		#if no file to read the simulationsparameters from:
		setDefaultThinningParams(self.G.simParam) #sets the parameters to default values
			
		if not self.G.terrain:
			self.G.areaPoly=[(0,0), (25,0), (25,40), (0,40)] #default for thinning files.
			self.G.terrain=Terrain(G=self.G)
			self.G.terrain.readTrees(thinning=True)
		craneMax=self.G.simParam['maxCraneLength']
		startPos=[random.uniform(craneMax, 25-craneMax), -4]
		self.m=ThinningMachine(name="thinny", sim=self, G=self.G, head=head, nCranes=nCranes,startPos=startPos, bundler=bundler,twigCrack=twigCrack)
		self.treeStats() #do some statistics on the trees
		self.activate(self.m,self.m.run())
		if observer:
			self.o=Observer(name="obsy", sim=self, G=self.G)
			self.activate(self.o, self.o.run())
		self.simulate(until=10000)
		#some simulation information:
		if observer:
			self.timeStats()
			"""
			print self.o.tstep*sum([c[1] for c in self.o.lAMoni]), 'left head active time via monitor'
			print self.o.tstep*sum([c[1] for c in self.o.lWBMoni]), 'left head waiting for Bundler'
			print self.stats['oneCraneWorkTime'], 'one crane work time'
			print self.stats['oneCraneWaitDriverTime'], 'one crane wait for driver time'
			if self.m.hasBundler:
				print self.stats['oneCraneWaitBundlerTime'], 'one crane wait for bundler time'
			if len(self.m.heads)==2:
				print self.o.tstep*sum([c[1] for c in self.o.rAMoni]), 'right head active time via monitor'
				print self.o.tstep*sum([c[1] for c in self.o.rWBMoni]), 'right head waiting for Bundler'
				print self.stats['twoCranesWorkTime'], 'two cranes work time'
				print self.stats['twoCranesWaitDriverTime'], 'two cranes wait for driver time'
				if self.m.hasBundler:
					print self.stats['twoCranesWaitBundlerTime'], 'two cranes wait for bundler time'
			"""
		self.stats['productivity']=len(self.m.trees)/self.now()*3600
		self.stats['outTake']=100*len(self.m.trees)/float(len(self.G.terrain.trees))
		self.stats['groundAreaRatio']=sum([t.dbh**2*pi*0.25 for t in self.m.trees])/max(1,sum([t.dbh**2*pi*0.25 for t in self.G.terrain.trees]))
		
		print "Simulation ended. Productivity: %.1f trees/hour. %.1f %% of the trees were harvested"%(len(self.m.trees)/self.now()*3600, self.stats['outTake'])
		print "average trees per corridor: %f average log weight in corridor: %f trees in main road: %f"%(self.avTreesPerCorr, self.avCorrTreeWeight, self.treesPerRoad)
		self.setQueuePerc()
		print self.getGeneralStatsString()
		if self.p: #plot
			self.p.terminate()
			if vis: plt.show()

	def timeStats(self):
		""" observe that this method performs the statcalculations on the
		times and sets the values to self.s.stats"""
		noCWforBundler=0
		noCWforBundlerTwo=0
		if self.m.hasBundler:
			self.stats['bundlingTime']=self.o.tstep*sum([c[1] for c in self.o.bundlerActiveMoni])# 'active bundler time via monitor'
		else: self.stats['bundlingTime']=0
		if len(self.m.heads)==1:
			self.stats['oneCraneWorkTime']=self.o.tstep*sum([c[1] for c in self.o.lAMoni])
			self.stats['oneCraneWaitDriverTime']=self.o.tstep*sum([c[1] for c in self.o.lWDMoni])
			self.stats['oneCraneWaitBundlerTime']=self.o.tstep*sum([c[1] for c in self.o.lWBMoni])
			self.stats['twoCranesWorkTime']=0
			self.stats['twoCranesWaitDriverTime']=0
			self.stats['twoCranesWaitBundlerTime']=0
			for i in range(len(self.o.lWBMoni)-1):
				if self.o.lWBMoni[i][1]==0 and self.o.lWBMoni[i+1][1]==1: noCWforBundler+=1
			self.stats['noCraneWaitings']=noCWforBundler
			self.stats['noCraneWaitingsTwo']=noCWforBundlerTwo
			
		elif len(self.m.heads)==2:
			for i in range(len(self.o.lWBMoni)-1):
				if self.o.lWBMoni[i][1]==0 and self.o.lWBMoni[i+1][1]==1: noCWforBundler+=1
				if self.o.rWBMoni[i][1]==0 and self.o.rWBMoni[i+1][1]==1: noCWforBundler+=1
			self.stats['noCraneWaitings']=noCWforBundler
			lAMoni=np.array(self.o.lAMoni)
			rAMoni=np.array(self.o.rAMoni)
			#t=lAMoni[:,[0]]#takes the times into one array
			addedActivity=lAMoni[:,[1]]+rAMoni[:,[1]]
			addedActivityTwo=copy.deepcopy(addedActivity)
			for i in range(len(addedActivity)):
				if addedActivity[i]==2:	addedActivity[i]=0
				if addedActivityTwo[i]==1: addedActivityTwo[i]=0
				elif addedActivityTwo[i]==2: addedActivityTwo[i]=1
			self.stats['oneCraneWorkTime']=float(self.o.tstep*sum(addedActivity))
			self.stats['twoCranesWorkTime']=float(self.o.tstep*sum(addedActivityTwo))
			lWDMoni=np.array(self.o.lWDMoni)
			rWDMoni=np.array(self.o.rWDMoni)
			addedWD=lWDMoni[:,[1]]+rWDMoni[:,[1]]
			addedWDTwo=copy.deepcopy(addedWD)
			for i in range(len(addedWD)):
				if addedWD[i]==2: addedWD[i]=0
				if addedWDTwo[i]==1: addedWDTwo[i]=0
				elif addedWDTwo[i]==2: addedWDTwo[i]=1
			self.stats['oneCraneWaitDriverTime']=float(self.o.tstep*sum(addedWD))
			self.stats['twoCranesWaitDriverTime']=float(self.o.tstep*sum(addedWDTwo))
			lWBMoni=np.array(self.o.lWBMoni)
			rWBMoni=np.array(self.o.rWBMoni)
			addedWB=lWBMoni[:,[1]]+rWBMoni[:,[1]]
			addedWBTwo=copy.deepcopy(addedWB)
			for i in range(len(addedWB)):
				if addedWB[i]==2: addedWB[i]=0
				if addedWBTwo[i]==1: addedWBTwo[i]=0
				elif addedWBTwo[i]==2: addedWBTwo[i]=1
			for i in range(len(addedWBTwo)-1):
				if addedWBTwo[i]==0 and addedWBTwo[i+1]==1: noCWforBundlerTwo+=1
			self.stats['noCraneWaitingsTwo']=noCWforBundlerTwo
			self.stats['oneCraneWaitBundlerTime']=float(self.o.tstep*sum(addedWB))
			self.stats['twoCranesWaitBundlerTime']=float(self.o.tstep*sum(addedWBTwo))
		else: raise Exception('Some error in number of heads in timeStats()')
		
	def treeStats(self):
		"""
		calculates some statistics.. should maybe be done in terrain class instead?
		"""
		trees=float(len(self.G.terrain.trees))
		self.saveGeneralStats("stand no", self.G.terrain.treeFile, "-") #see simSeries for how it works..
		self.saveGeneralStats("trees", trees, "-")
		if trees==0: return None
		self.saveGeneralStats("pine percentage", 100*len([t for t in self.G.terrain.trees if t.specie=='pine'])/trees, "%")
		self.saveGeneralStats("spruce percentage", 100*len([t for t in self.G.terrain.trees if t.specie=='spruce'])/trees, "%")
		self.saveGeneralStats("leaf tree percentage", 100*len([t for t in self.G.terrain.trees if t.specie=='leaf'])/trees, "%")
		treeDensity=trees/self.G.terrain.area
		self.saveGeneralStats("tree density", treeDensity, "trees/m2")
		mLogs=len(self.m.mainRoadTrees)
		mNum=0
		cLogs=len(self.m.corridorTrees)
		cNum=0
		for r in self.m.roadList:
			if r.radius>2*self.m.craneMaxL/2.+2: #main road.
				mNum+=1
			else:
				cNum+=1
		self.cNum=cNum
		self.mNum=mNum
		self.mLogs=mLogs
		self.cLogs=cLogs
		cWeight=sum([t.logWeight for w in self.m.corridorTrees ])
		mWeight=sum([t.logWeight for w in self.m.corridorTrees ])
		print "number of main roads:", mNum, "number of corridors:", cNum
		if cNum==0: self.avTreesPerCorr=0
		else: self.avTreesPerCorr=cLogs/float(cNum)
		self.treesPerRoad=mLogs
		if cLogs==0: self.avCorrTreeWeight=0
		else: self.avCorrTreeWeight=cWeight/float(cNum)
		if mLogs==0: self.avRoadTreeWeight=0
		else: self.avRoadTreeWeight=mWeight/float(mNum) #the cumulative sum
		#clustering...  see Clark and Evans 1954
		rexp=0.5*1/(sqrt(treeDensity)) #expected r
		robs=0
		for t in self.G.terrain.trees:
			tmp=[]
			R=5
			while len(tmp)==0 and R<sqrt(self.G.terrain.area): #in 99.9% of the cases, this loop only runs once.
				#we are not using self.G.terrain.trees for speedup reasons.
				tmp=self.G.terrain.GetTrees(t.pos, R)
				R+=2
			if len(tmp)==0:
				self.saveGeneralStats("clustering agg. index", "no trees", "trees/m2")
				break
			shortest=1e10
			for treeTmp in tmp:
				if treeTmp==t: continue #same tree
				d=fun.getDistance(t.pos, treeTmp.pos)
				if d<shortest: shortest=d
			if shortest==1e10: raise Exception('could not find shortest tree...')
			robs+=shortest
		robs/=trees
		print "rexp:", rexp, "robs.", robs
		aggregationIndex=robs/rexp
		self.saveGeneralStats("clustering agg. index", aggregationIndex, "-")

	def plotMoni(self, ax, number):
		tcap=50
		tmin=-0.1
		if self.now()<tcap: t=tcap
		else:
			if self.now()-tmin>400: tmin=self.now()-400
			t=self.now()
		if number==1: #plot driver activity
			driver=self.m.driver
			moni=driver.actMon
			if len(moni)>0:
				ax.plot(moni.tseries(),moni.yseries(), drawstyle='steps-post')
				ax.axis([tmin, t, -0.1, 1.2])
				ax.grid(True)
				ax.set_ylabel('Working pattern')
				ax.set_yticks((0,  1))#, ('idle', 'busy'))#, color = 'k')
		elif number==2: #plot driver waiting queue
			moni=self.m.driver.waitMon
			if len(moni)>0:
				maxt=int(max(moni.yseries()))
				ticks=[]
				for i in range(maxt+1): ticks.append(i)
				ax.set_yticks(tuple(ticks))
				ax.plot(moni.tseries(),moni.yseries(), drawstyle='steps-post')
				ax.axis([tmin, t, -0.1, max(moni.yseries())+0.1])
				ax.grid(True)
				ax.set_ylabel('Wait queue for driver.')
		elif number==3: #plot trees planted
			moni=self.m.treeMoni
			#trees planted
			if len(moni)>0:
				ax.plot(moni.tseries(),moni.yseries(), drawstyle='steps-post')
				ax.axis([-0.1, t, -0.1, (max(moni.yseries())+1)])
				ax.grid(True)
				ax.set_xlabel('time(s)')
				ax.set_ylabel('trees harvested')
		return ax