Commit da40245f authored by Georgios Dagkakis's avatar Georgios Dagkakis

commit to be uploaded to Nexedi server

parents
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ProdLine</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/ProdLine/src</path>
</pydev_pathproperty>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project>
'''
Created on 18 Feb 2013
@author: George
'''
'''
Models an assembly object
it gathers frames and parts which are loaded to the frames
'''
from SimPy.Simulation import *
import xlwt
from RandomNumberGenerator import RandomNumberGenerator
import scipy.stats as stat
#the Assembly object
class Assembly(Process):
#initialize the object
def __init__(self, id, name, dist, time):
Process.__init__(self)
self.id=id
self.objName=name
self.distType=dist #the distribution that the procTime follows
self.rng=RandomNumberGenerator(self, self.distType)
self.rng.avg=time[0]
self.rng.stdev=time[1]
self.rng.min=time[2]
self.rng.max=time[3]
self.next=[] #list with the next objects in the flow
self.previousPart=[] #list with the previous objects that send parts
self.previousFrame=[] #list with the previous objects that send frames
#lists to hold statistics of multiple runs
self.Waiting=[]
self.Working=[]
self.Blockage=[]
def initialize(self):
Process.__init__(self)
self.waitToDispose=False #flag that shows if the Assembly waits to dispose an entity
self.totalBlockageTime=0 #holds the total blockage time
self.totalWaitingTime=0 #holds the total waiting time
self.totalWorkingTime=0 #holds the total working time
self.completedJobs=0 #holds the number of completed jobs
self.timeLastEntityEnded=0 #holds the last time that an entity ended processing in the Assembly
self.timeLastEntityEntered=0 #holds the last time that an entity ended processing in the Assembly
self.timeLastFrameWasFull=0 #holds the time that the last frame was full, ie that assembly process started
self.nameLastFrameWasFull="" #holds the name of the last frame that was full, ie that assembly process started
self.nameLastEntityEntered="" #holds the name of the last frame that entered processing in the Assembly
self.nameLastEntityEnded="" #holds the name of the last frame that ended processing in the Assembly
self.Res=Resource(1)
self.Res.activeQ=[]
self.Res.waitQ=[]
def Run(self):
while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Assembly can accept a frame
#and one "frame" predecessor requests it
self.getEntity("Frame") #get the Frame
for i in range(self.Res.activeQ[0].numOfParts): #this loop will be carried until the Frame is full with the parts
yield waituntil, self, self.isRequestedFromPart #wait until a part is requesting for the assembly
self.getEntity("Part")
self.outputTrace(self.Res.activeQ[0].name, "is now full in "+ self.objName)
self.timeLastFrameWasFull=now()
self.nameLastFrameWasFull=self.Res.activeQ[0].name
startWorkingTime=now()
yield hold,self,self.rng.generateNumber() #hold for the time the assembly operation is carried
self.totalWorkingTime+=now()-startWorkingTime
self.outputTrace(self.Res.activeQ[0].name, "ended processing in " + self.objName)
self.timeLastEntityEnded=now()
self.nameLastEntityEnded=self.Res.activeQ[0].name
startBlockageTime=now()
self.completedJobs+=1 #Assembly completed a job
self.waitToDispose=True #since all the frame is full
yield waituntil, self, self.next[0].canAccept #wait until the next object is free
self.totalBlockageTime+=now()-startBlockageTime #add the blockage time
#checks if the Assembly can accept an entity
def canAccept(self):
return len(self.Res.activeQ)==0
#checks if the machine can accept an entity and there is a Frame waiting for it
def canAcceptAndIsRequested(self):
return len(self.Res.activeQ)==0 and self.previousFrame[0].haveToDispose()
#checks if the machine can accept an entity and there is a Frame waiting for it
def isRequestedFromPart(self):
return len(self.Res.activeQ)==1 and self.previousPart[0].haveToDispose()
#checks if the Assembly can dispose an entity to the following object
def haveToDispose(self):
return len(self.Res.activeQ)>0 and self.waitToDispose
#sets the routing in and out elements for the queue
def defineRouting(self, pp, pf, n):
self.next=n
self.previousPart=pp
self.previousFrame=pf
#removes an entity from the Assembly
def removeEntity(self):
self.outputTrace(self.Res.activeQ[0].name, "releases "+ self.objName)
self.Res.activeQ.pop(0)
self.waitToDispose=False
#gets an entity from the predecessor
#it may handle both Parts and Frames
def getEntity(self, type):
if(type=="Part"):
self.Res.activeQ[0].Res.activeQ.append(self.previousPart[0].Res.activeQ[0]) #get the part from the predecessor and append it to the frame!
self.previousPart[0].removeEntity() #remove the part from the previews object
self.outputTrace(self.Res.activeQ[0].Res.activeQ[-1].name, "got into "+ self.objName)
elif(type=="Frame"):
self.Res.activeQ.append(self.previousFrame[0].Res.activeQ[0]) #get the frame from the predecessor
self.previousFrame[0].removeEntity() #remove the frame from the previews object
self.outputTrace(self.Res.activeQ[0].name, "got into "+ self.objName)
self.nameLastEntityEntered=self.Res.activeQ[0].name
self.timeLastEntityEntered=now()
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
#if there is an entity that finished processing in Assembly but did not get to reach
#the following Object
#till the end of simulation, we have to add this blockage to the percentage of blockage in Machine
#we should exclude the blockage time in current entity though!
if (len(self.next[0].Res.activeQ)>0) and ((self.nameLastEntityEntered == self.nameLastEntityEnded)):
self.totalBlockageTime+=now()-self.timeLastEntityEnded
#if Assembly is currently processing an entity we should count this working time
if(len(self.Res.activeQ)>0) and (not (self.nameLastEntityEnded==self.nameLastFrameWasFull)):
self.totalWorkingTime+=now()-self.timeLastFrameWasFull
self.totalWaitingTime=MaxSimtime-self.totalWorkingTime-self.totalBlockageTime
self.Waiting.append(100*self.totalWaitingTime/MaxSimtime)
self.Working.append(100*self.totalWorkingTime/MaxSimtime)
self.Blockage.append(100*self.totalBlockageTime/MaxSimtime)
#outputs message to the trace.xls. Format is (Simulation Time | Entity or Frame Name | message)
def outputTrace(self, name, message):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1,name)
G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation)
if(G.traceIndex==65536):
G.traceIndex=0
G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
#outputs data to "output.xls"
def outputResultsXL(self, MaxSimtime):
from Globals import G
if(G.numberOfReplications==1): #if we had just one replication output the results to excel
G.outputSheet.write(G.outputIndex,0, "The percentage of Working of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWorkingTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of Blockage of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalBlockageTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of Waiting of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWaitingTime/MaxSimtime)
G.outputIndex+=1
else: #if we had multiple replications we output confidence intervals to excel
#for some outputs the results may be the same for each run (eg model is stochastic but failures fixed
#so failurePortion will be exactly the same in each run). That will give 0 variability and errors.
#so for each output value we check if there was difference in the runs' results
#if yes we output the Confidence Intervals. if not we output just the fix value
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Working of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Working):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Working[0])
G.outputSheet.write(G.outputIndex,2,self.Working[0])
G.outputSheet.write(G.outputIndex,3,self.Working[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Blockage of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Blockage):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Blockage[0])
G.outputSheet.write(G.outputIndex,2,self.Blockage[0])
G.outputSheet.write(G.outputIndex,3,self.Blockage[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Waiting of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Waiting):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Waiting[0])
G.outputSheet.write(G.outputIndex,2,self.Waiting[0])
G.outputSheet.write(G.outputIndex,3,self.Waiting[0])
G.outputIndex+=1
G.outputIndex+=1
#takes the array and checks if all its values are identical (returns false) or not (returns true)
#needed because if somebody runs multiple runs in deterministic case it would crash!
def checkIfArrayHasDifValues(self, array):
difValuesFlag=False
for i in range(1, len(array)):
if(array[i]!=array[1]):
difValuesFlag=True
return difValuesFlag
\ No newline at end of file
'''
Created on 6 Feb 2013
@author: George
'''
'''
models the exit of the model
'''
from SimPy.Simulation import *
import xlwt
import scipy.stats as stat
#The exit object
class Exit(Process):
def __init__(self, id, name):
Process.__init__(self)
self.id=id
self.objName=name
self.type="Exit"
self.previous=[] #list with the previous objects in the flow
#lists to hold statistics of multiple runs
self.Exits=[]
self.Lifespan=[]
def initialize(self):
Process.__init__(self)
self.Res=Resource(capacity=infinity)
self.numOfExits=0
self.totalLifespan=0
def Run(self):
while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity
#and one predecessor requests it
self.getEntity()
self.numOfExits+=1 #increase the exits by one
#sets the routing in element for the Exit
def defineRouting(self, p):
self.previous=p
#checks if the Exit can accept an entity
def canAccept(self):
return True #the exit always can accept an entity
#checks if the Exit can accept an entity and there is an entity waiting for it
def canAcceptAndIsRequested(self):
return self.previous[0].haveToDispose()
#gets an entity from the predecessor
def getEntity(self):
name=self.previous[0].Res.activeQ[0].name #get the name of the entity for the trace
self.totalLifespan+=now()-self.previous[0].Res.activeQ[0].startTime #Add the entity's lifespan to the total one.
self.previous[0].removeEntity() #remove the entity from the previous object
self.outputTrace(name)
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
from Globals import G
self.Exits.append(self.numOfExits)
try:
self.Lifespan.append(((self.totalLifespan)/self.numOfExits)/G.Base)
except ZeroDivisionError:
self.Lifespan.append(0)
#outputs message to the trace.xls. Format is (Simulation Time | Entity Name | "generated")
def outputTrace(self, message):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1,message)
G.traceSheet.write(G.traceIndex,2,"exited the system")
G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation)
if(G.traceIndex==65536):
G.traceIndex=0
G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
#outputs data to "output.xls"
def outputResultsXL(self, MaxSimtime):
from Globals import G
if(G.numberOfReplications==1): #if we had just one replication output the results to excel
G.outputSheet.write(G.outputIndex,0, "The Throughput is:")
G.outputSheet.write(G.outputIndex,1,self.numOfExits)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The average lifespan of an entity is:")
G.outputSheet.write(G.outputIndex,1,((self.totalLifespan)/self.numOfExits)/G.Base)
G.outputIndex+=1
else: #if we had multiple replications we output confidence intervals to excel
#for some outputs the results may be the same for each run (eg model is stochastic but failures fixed
#so failurePortion will be exactly the same in each run). That will give 0 variability and errors.
#so for each output value we check if there was difference in the runs' results
#if yes we output the Confidence Intervals. if not we output just the fix value
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean Throughput is:")
if self.checkIfArrayHasDifValues(self.Exits):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Exits, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Exits, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Exits, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Exits[0])
G.outputSheet.write(G.outputIndex,2,self.Exits[0])
G.outputSheet.write(G.outputIndex,3,self.Exits[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean Lifespan of an entity is:")
if self.checkIfArrayHasDifValues(self.Lifespan):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Lifespan, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Lifespan, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Lifespan, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Lifespan[0])
G.outputSheet.write(G.outputIndex,2,self.Lifespan[0])
G.outputSheet.write(G.outputIndex,3,self.Lifespan[0])
G.outputIndex+=1
G.outputIndex+=1
#takes the array and checks if all its values are identical (returns false) or not (returns true)
#needed because if somebody runs multiple runs in deterministic case it would crash!
def checkIfArrayHasDifValues(self, array):
difValuesFlag=False
for i in range(1, len(array)):
if(array[i]!=array[1]):
difValuesFlag=True
return difValuesFlag
\ No newline at end of file
'''
Created on 9 Nov 2012
@author: George
'''
'''
models the failures that servers can have
'''
from SimPy.Simulation import *
import math
from RandomNumberGenerator import RandomNumberGenerator
class Failure(Process):
def __init__(self, victim, dist, MTTF, MTTR, availability, index, repairman):
Process.__init__(self)
self.distType=dist #the distribution that the failure duration follows
self.MTTF=MTTF #the MTTF
self.MTTR=MTTR #the MTTR
self.availability=availability #the availability
self.victim=victim #the victim of the failure (work center)
self.name="F"+str(index)
self.repairman=repairman #the resource that may be needed to fix the failure
#if now resource is needed this will be "None"
self.type="Failure"
self.id=0
if(self.distType=="Availability"):
#the following are used if we have availability defined (as in plant)
#the erlang is a special case of Gamma.
#To model the Mu and sigma that is given in plant as alpha and beta for gamma you should do the following:
#beta=(sigma^2)/Mu
#alpha=Mu/beta
self.AvailabilityMTTF=MTTR*(float(availability)/100)/(1-(float(availability)/100))
self.sigma=0.707106781185547*MTTR
self.theta=(pow(self.sigma,2))/float(MTTR)
self.beta=self.theta
self.alpha=(float(MTTR)/self.theta)
self.rngTTF=RandomNumberGenerator(self, "Exp")
self.rngTTF.avg=self.AvailabilityMTTF
self.rngTTR=RandomNumberGenerator(self, "Erlang")
self.rngTTR.alpha=self.alpha
self.rngTTR.beta=self.beta
else: #if the distribution is fixed
self.rngTTF=RandomNumberGenerator(self, self.distType)
self.rngTTF.avg=MTTF
self.rngTTR=RandomNumberGenerator(self, self.distType)
self.rngTTR.avg=MTTR
def Run(self):
while 1:
#yield hold,self,self.calcTimeToFailure()
yield hold,self,self.rngTTF.generateNumber() #wait until a failure happens
try:
#print self.name
if(len(self.victim.Res.activeQ)>0):
self.interrupt(self.victim) #when a Machine gets failure while in process it is interrupted
self.victim.Up=False
self.victim.timeLastFailure=now()
#print str(now())+":M"+str(self.victim.id)+" is down"
self.outputTrace("is down")
except AttributeError:
print "AttributeError1"
failTime=now()
if(self.repairman!="None"): #if the failure needs a resource to be fixed, the machine waits until the
#resource is available
yield request,self,self.repairman.Res
timeRepairStarted=now()
self.repairman.timeLastRepairStarted=now()
#yield hold,self,self.calcTimeToRepair() #wait until the repairing process is over
yield hold,self,self.rngTTR.generateNumber() #wait until the repairing process is over
self.victim.totalFailureTime+=now()-failTime
try:
if(len(self.victim.Res.activeQ)>0):
reactivate(self.victim) #since repairing is over, the Machine is reactivated
self.victim.Up=True
#print str(now())+":M"+str(self.victim.id)+" is up"
self.outputTrace("is up")
if(self.repairman!="None"): #if a resource was used, it is now released
yield release,self,self.repairman.Res
self.repairman.totalWorkingTime+=now()-timeRepairStarted
#print "reactivating "+str(self.victim.currentEntity)
except AttributeError:
print "AttributeError2"
'''
#calculates the time until the next failure
def calcTimeToFailure(self):
from Globals import G
if self.distType=="Fixed": #in a fixed distribution every TTF should be equal to MTTF
TTF=self.MTTF
elif self.distType=="Availability": #if we have availability defined, TTF should follow the exponential distribution
TTF=G.Rnd.expovariate(float(1)/self.AvailabilityMTTF)
#print self.name+" TTF="+str(TTF)
return TTF
#calculates the time that it is needed for the repair
def calcTimeToRepair(self):
from Globals import G
if self.distType=="Fixed": #in a fixed distribution every TTR should be equal to MTTR
TTR=self.MTTR
elif self.distType=="Availability": #if we have availability defined, TTR should follow the Erlang distribution
TTR=G.Rnd.gammavariate(self.alpha,self.beta)
#print self.name+" TTR="+str(TTR)
return TTR
'''
#outputs message to the trace.xls. Format is (Simulation Time | Machine Name | message)
def outputTrace(self, message):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1, self.victim.objName)
G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation)
if(G.traceIndex==65536):
G.traceIndex=0
G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
#outputs data to "output.xls"
def outputResultsXL(self, MaxSimtime):
pass
\ No newline at end of file
'''
Created on 18 Feb 2013
@author: George
'''
'''
models a frame entity. This can flow through the system and carry parts
'''
from SimPy.Simulation import *
from Globals import G
#The entity object
class Frame(object):
type="Frame"
numOfParts=4 #the number of parts that the frame can take
def __init__(self, name):
self.name=name
self.currentStop=None #contains the current object that the material is in
self.creationTime=0
self.startTime=0 #holds the startTime for the lifespan
self.Res=Resource(self.numOfParts)
'''
Created on 8 Nov 2012
@author: George
'''
'''
carries some global variables
'''
from SimPy.Simulation import *
from Machine import Machine
from Queue import Queue
from Repairman import Repairman
import xlwt
import xlrd
from random import Random, expovariate, gammavariate, normalvariate
# globals
class G:
seed=1450 #the seed of the random number generator
Rnd = Random(seed) #random number generator
ObjList=[] #a list that holds all the simulation objects
numberOfReplications=1 #the number of replications default=1
confidenceLevel=0.9 #the confidence level default=90%
Base=1 #the Base time unit. Default =1 minute
maxSimTime=0 #the total simulation time
#data for the trace output in excel
trace="" #this is written from input. If it is "Yes" then you write to trace, else we do not
traceIndex=0 #index that shows in what row we are
sheetIndex=1 #index that shows in what sheet we are
traceFile = xlwt.Workbook() #create excel file
traceSheet = traceFile.add_sheet('sheet '+str(sheetIndex), cell_overwrite_ok=True) #create excel sheet
#the output excel
outputIndex=0 #index that shows in what row we are
sheetIndex=1 #index that shows in what sheet we are
outputFile = xlwt.Workbook() #create excel file
outputSheet = outputFile.add_sheet('sheet '+str(sheetIndex), cell_overwrite_ok=True) #create excel sheet
'''
Created on 21 Feb 2013
@author: George
'''
'''
The main script that is ran.
It reads the inputs, runs the experiments and calls the post-processing method
'''
from SimPy.Simulation import *
from Source import Source
from Globals import G
from Machine import Machine
from Exit import Exit
from Queue import Queue
from QueueLIFO import QueueLIFO
from Repairman import Repairman
from Part import Part
from Frame import Frame
from Assembly import Assembly
import xlwt
import xlrd
import time
import numpy as np
from random import Random
import sys
#read general simulation inputs
def readGeneralInput():
GeneralXL=xlrd.open_workbook('inputs/General.xls')
GeneralSheet = GeneralXL.sheet_by_index(0)
G.numberOfReplications=int(GeneralSheet.cell(1,1).value)
G.maxSimTime=GeneralSheet.cell(2,1).value
G.trace=GeneralSheet.cell(3,1).value
G.confidenceLevel=GeneralSheet.cell(4,1).value
#create the simulation objects
def createObjects():
#Read Source Data and create sources
SourceXL=xlrd.open_workbook('inputs/Source.xls')
SourceSheet = SourceXL.sheet_by_index(0)
i=1
G.SourceList=[] #a list that will hold all the sources
while(SourceSheet.cell(0,i).value!="END"):
if SourceSheet.cell(3,i).value=="Part":
S=Source(i, "S"+str(i), SourceSheet.cell(1,i).value, SourceSheet.cell(2,i).value, Part)
elif SourceSheet.cell(3,i).value=="Frame":
S=Source(i, "S"+str(i), SourceSheet.cell(1,i).value, SourceSheet.cell(2,i).value, Frame)
G.SourceList.append(S)
i+=1
G.ObjList=G.ObjList+G.SourceList #add sources also to object list
#Read Queue Data and create queues
QueueXL=xlrd.open_workbook('inputs/Queue.xls')
QueueSheet = QueueXL.sheet_by_index(0)
i=1
G.QueueList=[] #a list that will hold all the queues
while(QueueSheet.cell(0,i).value!="END"):
if QueueSheet.cell(2,i).value=="Yes":
Q=Queue(i, "Q"+str(i), int(QueueSheet.cell(1,i).value), True)
else:
Q=Queue(i, "Q"+str(i), int(QueueSheet.cell(1,i).value), False)
i+=1
G.QueueList.append(Q)
G.ObjList=G.ObjList+G.QueueList #add queues also to object list
#Read Queue Data and create QueueLifo
QueueLIFOXL=xlrd.open_workbook('inputs/QueueLIFO.xls')
QueueLIFOSheet = QueueLIFOXL.sheet_by_index(0)
i=1
G.QueueLIFOList=[] #a list that will hold all the queues
while(QueueLIFOSheet.cell(0,i).value!="END"):
if QueueLIFOSheet.cell(2,i).value=="Yes":
Q=QueueLIFO(i, "QLIFO"+str(i), int(QueueLIFOSheet.cell(1,i).value), True)
else:
Q=QueueLIFO(i, "QLIFO"+str(i), int(QueueLIFOSheet.cell(1,i).value), False)
i+=1
G.QueueLIFOList.append(Q)
G.ObjList=G.ObjList+G.QueueLIFOList #add queues also to object list
#Read Repairman Data and create repairmen
RepairmanXL=xlrd.open_workbook('inputs/Repairman.xls')
RepairmanSheet = RepairmanXL.sheet_by_index(0)
i=1
G.RepairmanList=[] #a list that will hold all the repairmen
while(RepairmanSheet.cell(0,i).value!="END"):
W=Repairman(i, "W"+str(i), RepairmanSheet.cell(1,i).value)
G.RepairmanList.append(W)
i+=1
G.ObjList=G.ObjList+G.RepairmanList #add repairmen also to object list
#Read Machine Data and create machines
MachineXL=xlrd.open_workbook('inputs/Machine.xls')
MachineSheet = MachineXL.sheet_by_index(0)
i=1
G.MachineList=[] #a list that will hold all the machines
while(MachineSheet.cell(0,i).value!="END"):
if MachineSheet.cell(11,i).value=="Yes" and len(G.RepairmanList)>0:
MR=G.RepairmanList[0]
else:
MR="None"
M=Machine(i, "M"+str(i), int(MachineSheet.cell(1,i).value), MachineSheet.cell(2,i).value, [MachineSheet.cell(3,i).value, MachineSheet.cell(4,i).value,
MachineSheet.cell(5,i).value, MachineSheet.cell(6,i).value], MachineSheet.cell(7,i).value,
MachineSheet.cell(8,i).value, MachineSheet.cell(9,i).value, MachineSheet.cell(10,i).value,
MR)
G.MachineList.append(M)
i+=1
G.ObjList=G.ObjList+G.MachineList #add machines also to object list #add sources also to object list
#Read Exit Data and create exits
ExitXL=xlrd.open_workbook('inputs/Exit.xls')
ExitSheet = ExitXL.sheet_by_index(0)
i=1
G.ExitList=[] #a list that will hold all the exits
while(ExitSheet.cell(0,i).value!="END"):
E=Exit(i, "E"+str(i))
G.ExitList.append(E)
i+=1
G.ObjList=G.ObjList+G.ExitList #add exits also to object list
#Read Assembly Data and create assemblies
AssemblyXL=xlrd.open_workbook('inputs/Assembly.xls')
AssemblySheet = AssemblyXL.sheet_by_index(0)
i=1
G.AssemblyList=[] #a list that will hold all the machines
while(AssemblySheet.cell(0,i).value!="END"):
A=Assembly(i, "A"+str(i), AssemblySheet.cell(1,i).value, [AssemblySheet.cell(2,i).value, AssemblySheet.cell(3,i).value,
AssemblySheet.cell(4,i).value, AssemblySheet.cell(5,i).value])
G.AssemblyList.append(A)
i+=1
G.ObjList=G.ObjList+G.AssemblyList #add machines also to object list #add sources also to object list
#reads the topology and defines it for the objects
def setTopology(topologyFilename):
G.TopologyList=[]
try:
TopologyXL=xlrd.open_workbook('inputs/'+topologyFilename+'.xls')
except IOError:
print "no such topology file. The programm is terminated"
sys.exit()
TopologySheet = TopologyXL.sheet_by_index(0)
i=1
while(TopologySheet.cell(i,0).value!="END"):
curList=list(str(TopologySheet.cell(i,0).value))
if curList[0]=="S":
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==next:
nextObjInd=j
G.SourceList[int(curList[1])-1].defineRouting([G.ObjList[nextObjInd]])
G.TopologyList.append(G.SourceList[int(curList[1])-1])
elif curList[0]=="Q":
previous=str(TopologySheet.cell(i,1).value)
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previous:
previousObjInd=j
if G.ObjList[j].objName==next:
nextObjInd=j
G.QueueList[int(curList[1])-1].defineRouting([G.ObjList[previousObjInd]], [G.ObjList[nextObjInd]])
G.TopologyList.append(G.QueueList[int(curList[1])-1])
elif curList[0]=="M":
previous=str(TopologySheet.cell(i,1).value)
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previous:
previousObjInd=j
if G.ObjList[j].objName==next:
nextObjInd=j
G.MachineList[int(curList[1])-1].defineRouting([G.ObjList[previousObjInd]], [G.ObjList[nextObjInd]])
G.TopologyList.append(G.MachineList[int(curList[1])-1])
elif curList[0]=="A":
previousPart=str(TopologySheet.cell(i,3).value)
previousFrame=str(TopologySheet.cell(i,4).value)
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previousPart:
previousPartObjInd=j
if G.ObjList[j].objName==previousFrame:
previousFrameObjInd=j
if G.ObjList[j].objName==next:
nextObjInd=j
G.AssemblyList[int(curList[1])-1].defineRouting([G.ObjList[previousPartObjInd]], [G.ObjList[previousFrameObjInd]], [G.ObjList[nextObjInd]])
G.TopologyList.append(G.AssemblyList[int(curList[1])-1])
elif curList[0]=="E":
previous=str(TopologySheet.cell(i,1).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previous:
previousObjInd=j
G.ExitList[int(curList[1])-1].defineRouting([G.ObjList[previousObjInd]])
G.TopologyList.append(G.ExitList[int(curList[1])-1])
i+=1
G.TopologyList.append(G.RepairmanList[0])
#initializes all the objects that are in the topology
def initializeObjects():
for j in range(len(G.TopologyList)):
G.TopologyList[j].initialize()
#activates all the objects
def activateObjects():
for j in range(len(G.TopologyList)):
try:
activate(G.TopologyList[j],G.TopologyList[j].Run())
except AttributeError:
pass
#the main script that is ran
def main():
topologyId=raw_input("give the topology id\n")
G.ObjList=[]
start=time.time() #start counting execution time
readGeneralInput()
createObjects()
setTopology("Topology"+topologyId)
for j in range(len(G.TopologyList)):
print G.TopologyList[j].objName
for i in range(G.numberOfReplications):
print "start run number "+str(i+1)
G.seed+=1
G.Rnd=Random(G.seed)
initialize() #initialize the simulation
initializeObjects()
activateObjects()
for j in range(len(G.TopologyList)):
pass
#print G.TopologyList[j]
simulate(until=G.maxSimTime) #start the simulation
#carry on the post processing operations for every object in the topology
for j in range(len(G.TopologyList)):
G.TopologyList[j].postProcessing(G.maxSimTime)
#output trace to excel
if(G.trace=="Yes"):
G.traceFile.save('trace'+str(i+1)+'.xls')
G.traceIndex=0 #index that shows in what row we are
G.sheetIndex=1 #index that shows in what sheet we are
G.traceFile = xlwt.Workbook() #create excel file
G.traceSheet = G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True) #create excel sheet
G.outputSheet.write(G.outputIndex,0, "Execution Time")
G.outputSheet.write(G.outputIndex,1, str(time.time()-start)+" seconds")
G.outputIndex+=2
#output data to excel for every object in the topology
for j in range(len(G.TopologyList)):
G.TopologyList[j].outputResultsXL(G.maxSimTime)
G.outputFile.save("output.xls")
print "execution time="+str(time.time()-start)
if __name__ == '__main__': main()
\ No newline at end of file
'''
Created on 8 Nov 2012
@author: George
'''
'''
Models a machine that can also have failures
'''
from SimPy.Simulation import *
from Failure import Failure
import xlwt
import xlrd
from RandomNumberGenerator import RandomNumberGenerator
import scipy.stats as stat
#the Machine object
class Machine(Process):
#initialize the id the capacity, of the resource and the distribution
def __init__(self, id, name, capacity, dist, time, fDist, MTTF, MTTR, availability, repairman):
Process.__init__(self)
self.id=id
self.objName=name
self.capacity=capacity
self.distType=dist #the distribution that the procTime follows
self.failureDistType=fDist #the distribution that the failure follows
self.repairman=repairman
#self.xls = xlwt.Workbook() #create excel file
#self.sheet = self.xls.add_sheet('sheet ', cell_overwrite_ok=True) #create excel sheet
#self.xlindex=0
self.rng=RandomNumberGenerator(self, self.distType)
self.rng.avg=time[0]
self.rng.stdev=time[1]
self.rng.min=time[2]
self.rng.max=time[3]
self.MTTF=MTTF
self.MTTR=MTTR
self.availability=availability
self.next=[] #list with the next objects in the flow
self.previous=[] #list with the previous objects in the flow
self.type="Machine" #String that shows the type of object
#lists to hold statistics of multiple runs
self.Failure=[]
self.Working=[]
self.Blockage=[]
self.Waiting=[]
'''
self.Up=True #Boolean that shows if the machine is in failure ("Down") or not ("up")
self.currentEntity=None
self.totalBlockageTime=0 #holds the total blockage time
self.totalFailureTime=0 #holds the total failure time
self.totalWaitingTime=0 #holds the total waiting time
self.totalWorkingTime=0 #holds the total working time
self.completedJobs=0 #holds the number of completed jobs
self.timeLastEntityEnded=0 #holds the last time that an entity ended processing in the machine
self.nameLastEntityEnded="" #holds the name of the last entity that ended processing in the machine
self.timeLastEntityEntered=0 #holds the last time that an entity entered in the machine
self.nameLastEntityEntered="" #holds the name of the last entity that entered in the machine
self.downTimeInCurrentEntity=0 #holds the time that the machine was down while processing the current entity
self.timeLastFailure=0 #holds the time that the last failure of the machine started
self.downTimeInTryingToReleaseCurrentEntity=0 #holds the time that the machine was down while trying
#to release the current entity
self.waitToDispose=False #shows if the machine waits to dispose an entity
'''
'''
#if the failure distribution for the machine is fixed, activate the failure
if(self.failureDistType=="Fixed" or self.failureDistType=="Availability"):
MFailure=Failure(self, self.failureDistType, self.MTTF, self.MTTR, self.availability, self.id, self.repairman)
activate(MFailure,MFailure.Run())
'''
#self.initializeForRun()
def initialize(self):
Process.__init__(self)
self.Up=True #Boolean that shows if the machine is in failure ("Down") or not ("up")
self.currentEntity=None
self.totalBlockageTime=0 #holds the total blockage time
self.totalFailureTime=0 #holds the total failure time
self.totalWaitingTime=0 #holds the total waiting time
self.totalWorkingTime=0 #holds the total working time
self.completedJobs=0 #holds the number of completed jobs
self.timeLastEntityEnded=0 #holds the last time that an entity ended processing in the machine
self.nameLastEntityEnded="" #holds the name of the last entity that ended processing in the machine
self.timeLastEntityEntered=0 #holds the last time that an entity entered in the machine
self.nameLastEntityEntered="" #holds the name of the last entity that entered in the machine
self.downTimeInCurrentEntity=0 #holds the time that the machine was down while processing the current entity
self.timeLastFailure=0 #holds the time that the last failure of the machine started
self.downTimeInTryingToReleaseCurrentEntity=0 #holds the time that the machine was down while trying
#to release the current entity
self.waitToDispose=False #shows if the machine waits to dispose an entity
#if the failure distribution for the machine is fixed, activate the failure
if(self.failureDistType=="Fixed" or self.failureDistType=="Availability"):
MFailure=Failure(self, self.failureDistType, self.MTTF, self.MTTR, self.availability, self.id, self.repairman)
activate(MFailure,MFailure.Run())
self.Res=Resource(self.capacity)
#the main process of the machine
def Run(self):
#execute all through simulation time
while 1:
failureTime=0
yield waituntil, self, self.canAcceptAndIsRequested #wait until the machine can accept an entity
#and one predecessor requests it
self.getEntity() #get the entity from the predecessor
#self.previous[0].removeEntity()
self.outputTrace("got into "+self.objName)
self.currentEntity=self.Res.activeQ[0] #entity is the current entity processed in Machine
self.timeLastEntityEntered=now() #this holds the last time that an entity got into Machine
self.nameLastEntityEntered=self.currentEntity.name #this holds the name of the last entity that got into Machine
timeEntered=now()
tinMStart=self.rng.generateNumber() #get the processing time
tinM=tinMStart
interruption=False
processingEndedFlag=True
failureTime=0
#this loop is repeated until the processing time is expired with no failure
while processingEndedFlag:
tBefore=now()
yield hold,self,tinM #getting processed
if self.interrupted(): #if a failure occurs while processing the machine is interrupted.
self.outputTrace("Interrupted at "+self.objName)
tinM=tinM-(now()-tBefore) #the processing time left
if(tinM==0): #sometimes the failure may happen exactly at the time that the processing would finish
#this may produce ina ccordance to the simul8 because in both SimPy and Simul8
#it seems to be random which happens 1st
#this should not appear often to stochastic models though where times are random
interruption=True
breakTime=now()
yield passivate,self #if there is a failure in the machine it is passivated
self.downTimeInCurrentEntity+=now()-breakTime
failureTime+=now()-breakTime
self.outputTrace("passivated in "+self.objName+" for "+str(now()-breakTime))
else:
processingEndedFlag=False #if no interruption occurred the processing in M1 is ended
self.outputTrace("ended processing in "+self.objName)
self.waitToDispose=True
self.totalWorkingTime+=tinMStart #the total processing time for this entity is what the distribution initially gave
self.timeLastEntityEnded=now() #this holds the last time that an entity ended processing in Machine
self.nameLastEntityEnded=self.currentEntity.name #this holds the name of the last entity that ended processing in Machine
self.completedJobs+=1 #Machine completed one more Job
self.downTimeInCurrentEntity=0
reqTime=now() #entity has ended processing in Machine and requests for the next object
self.downTimeInTryingToReleaseCurrentEntity=0
notBlockageTime=0
while 1:
yield waituntil, self, self.ifCanDisposeOrHaveFailure #wait until the next Object #is available or machine has failure
if self.Up: #if Next object available break
break
else: #if M1 had failure, we want to wait until it is fixed and also count the failure time.
failTime=now()
yield waituntil, self, self.checkIfMachineIsUp
failureTime+=now()-failTime
self.downTimeInTryingToReleaseCurrentEntity+=now()-failTime
totalTime=now()-timeEntered
blockageTime=totalTime-(tinMStart+failureTime)
self.totalBlockageTime+=totalTime-(tinMStart+failureTime) #the time of blockage is derived from
#the whole time in the machine
#minus the processing time and the failure time
#sets the routing in and out elements for the queue
def defineRouting(self, p, n):
self.next=n
self.previous=p
#checks if the waitQ of the machine is empty
def checkIfWaitQEmpty(self):
return len(self.M.waitQ)==0
#checks if the activeQ of the machine is empty
def checkIfActiveQEmpty(self):
return len(self.M.activeQ)==0
#checks if the machine is Up
def checkIfMachineIsUp(self):
return self.Up
#checks if the machine can accept an entity
def canAccept(self):
return self.Up and len(self.Res.activeQ)==0
#checks if the machine can accept an entity and there is an entity waiting for it
def canAcceptAndIsRequested(self):
return self.Up and len(self.Res.activeQ)==0 and self.previous[0].haveToDispose()
#checks if the machine down or it can dispose the object
def ifCanDisposeOrHaveFailure(self):
return self.Up==False or self.next[0].canAccept() or len(self.Res.activeQ)==0 #the last part is added so that it is not removed and stack
#gotta think of it again
#checks if the Machine can dispose an entity to the following object
def haveToDispose(self):
return len(self.Res.activeQ)>0 and self.waitToDispose and self.Up
#removes an entity from the Machine
def removeEntity(self):
self.outputTrace("releases "+self.objName)
self.waitToDispose=False
self.Res.activeQ.pop(0)
self.downTimeInTryingToReleaseCurrentEntity=0
#self.outputTrace("got blocked in M"+str(self.id)+" for "
# +str(self.totalBlockageTime))
#gets an entity from the predecessor
def getEntity(self):
self.Res.activeQ.append(self.previous[0].Res.activeQ[0]) #get the entity from the predecessor
self.previous[0].removeEntity()
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
alreadyAdded=False #a flag that shows if the blockage time has already been added
#if there is an entity that finished processing in a Machine but did not get to reach
#the following Object
#till the end of simulation, we have to add this blockage to the percentage of blockage in Machine
#we should exclude the failure time in current entity though!
if (len(self.next[0].Res.activeQ)>0) and ((self.nameLastEntityEntered == self.nameLastEntityEnded)):
self.totalBlockageTime+=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity)
#X=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity)
if self.Up==False:
self.totalBlockageTime-=now()-self.timeLastFailure
#X-=now()-self.timeLastFailure
alreadyAdded=True
#if Machine is currently processing an entity we should count this working time
if(len(self.Res.activeQ)>0) and (not (self.nameLastEntityEnded==self.nameLastEntityEntered)):
#if Machine is down we should add this last failure time to the time that it has been down in current entity
if(len(self.Res.activeQ)>0) and (self.Up==False):
self.downTimeInCurrentEntity+=now()-self.timeLastFailure
self.totalWorkingTime+=now()-self.timeLastEntityEntered-self.downTimeInCurrentEntity
#if Machine is down we have to add this failure time to its total failure time
#we also need to add the last blocking time to total blockage time
if(self.Up==False):
self.totalFailureTime+=now()-self.timeLastFailure
#we add the value only if it hasn't already been added
if((len(self.next[0].Res.activeQ)>0) and (self.nameLastEntityEnded==self.nameLastEntityEntered) and (not alreadyAdded)):
#self.totalBlockageTime+=self.timeLastFailure-self.timeLastEntityEnded
self.totalBlockageTime+=(now()-self.timeLastEntityEnded)-(now()-self.timeLastFailure)-self.downTimeInTryingToReleaseCurrentEntity
#Machine was idle when it was not in any other state
self.totalWaitingTime=MaxSimtime-self.totalWorkingTime-self.totalBlockageTime-self.totalFailureTime
if self.totalBlockageTime<0 and self.totalBlockageTime>-0.00001: #to avoid some effects of getting negative cause of rounding precision
self.totalBlockageTime=0
if self.totalWaitingTime<0 and self.totalWaitingTime>-0.00001: #to avoid some effects of getting negative cause of rounding precision
self.totalWaitingTime=0
self.Failure.append(100*self.totalFailureTime/MaxSimtime)
self.Blockage.append(100*self.totalBlockageTime/MaxSimtime)
self.Waiting.append(100*self.totalWaitingTime/MaxSimtime)
self.Working.append(100*self.totalWorkingTime/MaxSimtime)
#outputs message to the trace.xls. Format is (Simulation Time | Entity Name | message)
def outputTrace(self, message):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1,self.Res.activeQ[0].name)
G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation)
if(G.traceIndex==65536):
G.traceIndex=0
G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
#outputs the the "output.xls"
def outputResultsXL(self, MaxSimtime):
from Globals import G
if(G.numberOfReplications==1): #if we had just one replication output the results to excel
G.outputSheet.write(G.outputIndex,0, "The percentage of Failure of " +self.objName+ " is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalFailureTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of Working of " +self.objName+ " is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWorkingTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of Blockage of " +self.objName+ " is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalBlockageTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of Waiting of " +self.objName+ " is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWaitingTime/MaxSimtime)
G.outputIndex+=1
else: #if we had multiple replications we output confidence intervals to excel
#for some outputs the results may be the same for each run (eg model is stochastic but failures fixed
#so failurePortion will be exactly the same in each run). That will give 0 variability and errors.
#so for each output value we check if there was difference in the runs' results
#if yes we output the Confidence Intervals. if not we output just the fix value
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Failure of "+ self.objName+" is:")
if self.checkIfArrayHasDifValues(self.Failure):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Failure, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Failure, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Failure, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Failure[0])
G.outputSheet.write(G.outputIndex,2,self.Failure[0])
G.outputSheet.write(G.outputIndex,3,self.Failure[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Working of "+ self.objName+" is:")
if self.checkIfArrayHasDifValues(self.Working):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Working[0])
G.outputSheet.write(G.outputIndex,2,self.Working[0])
G.outputSheet.write(G.outputIndex,3,self.Working[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Blockage of "+ self.objName+" is:")
if self.checkIfArrayHasDifValues(self.Blockage):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Blockage[0])
G.outputSheet.write(G.outputIndex,2,self.Blockage[0])
G.outputSheet.write(G.outputIndex,3,self.Blockage[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Waiting of "+ self.objName+" is:")
if self.checkIfArrayHasDifValues(self.Waiting):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Waiting[0])
G.outputSheet.write(G.outputIndex,2,self.Waiting[0])
G.outputSheet.write(G.outputIndex,3,self.Waiting[0])
G.outputIndex+=1
G.outputIndex+=1
#takes the array and checks if all its values are identical (returns false) or not (returns true)
#needed because if somebody runs multiple runs in deterministic case it would crash!
def checkIfArrayHasDifValues(self, array):
difValuesFlag=False
for i in range(1, len(array)):
if(array[i]!=array[1]):
difValuesFlag=True
return difValuesFlag
\ No newline at end of file
'''
Created on 6 Feb 2013
@author: George
'''
'''
models a part entity that flows through the system
'''
from SimPy.Simulation import *
from Globals import G
#The entity object
class Part(object):
type="Part"
def __init__(self, name):
self.name=name
self.currentStop=None #contains the current object that the material is in
self.creationTime=0
self.startTime=0 #holds the startTime for the lifespan
'''
Created on 8 Nov 2012
@author: George
'''
'''
Models a FIFO queue where entities can wait in order to get into a server
'''
from SimPy.Simulation import *
#the Queue object
class Queue(Process):
def __init__(self, id, name, capacity, dummy):
Process.__init__(self)
self.id=id
self.objName=name
self.capacity=capacity
self.nameLastEntityEntered="" #keeps the name of the last entity that entered in the queue
self.timeLastEntityEntered=0 #keeps the time of the last entity that entered in the queue
self.next=[] #list with the next objects in the flow
self.previous=[] #list with the previous objects in the flow
self.type="Queue" #String that shows the type of object
self.isDummy=dummy #Boolean that shows if it is the dummy first Queue
def initialize(self):
Process.__init__(self)
self.Res=Resource(self.capacity)
self.nameLastEntityEntered="" #keeps the name of the last entity that entered in the queue
self.timeLastEntityEntered=0 #keeps the time of the last entity that entered in the queue
def Run(self):
while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity
#and one predecessor requests it
self.getEntity()
#if entity just got to the dummyQ set its startTime as the current time
if self.isDummy:
self.Res.activeQ[0].startTime=now()
#sets the routing in and out elements for the queue
def defineRouting(self, p, n):
self.next=n
self.previous=p
#checks if the Q has one available place
def checkIfQHasPlace(self):
return len(self.Q.activeQ)<self.capacity
#checks if the Queue can accept an entity
def canAccept(self):
return len(self.Res.activeQ)<self.capacity
#checks if the Queue can dispose an entity to the following object
def haveToDispose(self):
return len(self.Res.activeQ)>0
#checks if the Queue can accept an entity and there is an entity waiting for it
def canAcceptAndIsRequested(self):
return len(self.Res.activeQ)<self.capacity and self.previous[0].haveToDispose()
#gets an entity from the predecessor
def getEntity(self):
self.Res.activeQ.append(self.previous[0].Res.activeQ[0]) #get the entity from the previous object
self.previous[0].removeEntity() #remove the entity from the previous object
#removes an entity from the Queue (this is FIFO for now)
def removeEntity(self):
self.Res.activeQ.pop(0)
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
pass #no actions for the Queue
#outputs message to the trace.xls. Format is (Simulation Time | Entity Name | message)
def outputTrace(self, message):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1,self.Res.activeQ[0].name)
G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation)
if(G.traceIndex==65536):
G.traceIndex=0
G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
#outputs data to "output.xls"
def outputResultsXL(self, MaxSimtime):
pass
\ No newline at end of file
'''
Created on 15 Feb 2013
@author: George
'''
'''
Models a LIFO queue where entities can wait in order to get into a server
'''
from Queue import Queue
class QueueLIFO(Queue):
#gets an entity from the predecessor
def getEntity(self):
self.Res.activeQ=[self.previous[0].Res.activeQ[0]]+self.Res.activeQ #get the entity from the previous object
#and put it in front of the activeQ
self.previous[0].removeEntity() #remove the entity from the previous object
\ No newline at end of file
'''
Created on 14 Feb 2013
@author: George
'''
'''
holds methods for generations of numbers from different distributions
'''
class RandomNumberGenerator(object):
def __init__(self, obj, type):
self.distType=type
self.avg=0
self.stdev=0
self.min=0
self.max=0
#self.availability=0
self.alpha=0
self.beta=0
self.object=obj
def generateNumber(self):
from Globals import G
number=0
if(self.distType=="Fixed"): #if the distribution is Fixed
number=self.avg
elif(self.distType=="Exp"): #if the distribution is Exponential
number=G.Rnd.expovariate(1.0/(self.avg))
elif(self.distType=="Normal"): #if the distribution is Normal
while 1:
number=G.Rnd.normalvariate(self.avg, self.stdev)
if number>self.max or number<self.min and max!=0: #if the number is out of bounds repeat the process #if max=0 this means that we did not have time "time" bounds
continue
else: #if the number is in the limits stop the process
break
elif self.distType=="Erlang": #if the distribution is erlang
number=G.Rnd.gammavariate(self.alpha,self.beta)
else:
print "unknown distribution error in "+str(self.object.type)+str(self.object.id)
return number
\ No newline at end of file
'''
Created on 14 Nov 2012
@author: George
'''
'''
models a repairman that can fix a machine when it gets failures
'''
from SimPy.Simulation import *
import xlwt
import scipy.stats as stat
#the resource that repairs the machines
class Repairman(object):
def __init__(self, id, name, capacity):
self.id=id
self.objName=name
self.capacity=capacity #repairman is an instance of resource
self.type="Repairman"
#lists to hold statistics of multiple runs
self.Waiting=[]
self.Working=[]
def initialize(self):
self.totalWorkingTime=0 #holds the total working time
self.totalWaitingTime=0 #holds the total waiting time
self.timeLastRepairStarted=0 #holds the time that the last repair was started
self.Res=Resource(self.capacity)
#checks if the worker is available
def checkIfWorkerIsAvailable(self):
return len(self.W.activeQ)<self.capacity
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
#if the repairman is currently working we have to count the time of this work
if len(self.Res.activeQ)>0:
self.totalWorkingTime+=now()-self.timeLastRepairStarted
#Repairman was idle when he was not in any other state
self.totalWaitingTime=MaxSimtime-self.totalWorkingTime
self.Waiting.append(100*self.totalWaitingTime/MaxSimtime)
self.Working.append(100*self.totalWorkingTime/MaxSimtime)
#outputs data to "output.xls"
def outputResultsXL(self, MaxSimtime):
from Globals import G
if(G.numberOfReplications==1): #if we had just one replication output the results to excel
G.outputSheet.write(G.outputIndex,0, "The percentage of working of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWorkingTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of waiting of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWaitingTime/MaxSimtime)
G.outputIndex+=1
else: #if we had multiple replications we output confidence intervals to excel
#for some outputs the results may be the same for each run (eg model is stochastic but failures fixed
#so failurePortion will be exactly the same in each run). That will give 0 variability and errors.
#so for each output value we check if there was difference in the runs' results
#if yes we output the Confidence Intervals. if not we output just the fix value
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Working of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Working):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Working[0])
G.outputSheet.write(G.outputIndex,2,self.Working[0])
G.outputSheet.write(G.outputIndex,3,self.Working[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Waiting of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Waiting):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Waiting[0])
G.outputSheet.write(G.outputIndex,2,self.Waiting[0])
G.outputSheet.write(G.outputIndex,3,self.Waiting[0])
G.outputIndex+=1
G.outputIndex+=1
#takes the array and checks if all its values are identical (returns false) or not (returns true)
#needed because if somebody runs multiple runs in deterministic case it would crash!
def checkIfArrayHasDifValues(self, array):
difValuesFlag=False
for i in range(1, len(array)):
if(array[i]!=array[1]):
difValuesFlag=True
return difValuesFlag
\ No newline at end of file
'''
Created on 8 Nov 2012
@author: George
'''
'''
models the source object that generates the entities
'''
from SimPy.Simulation import *
from Part import Part
from RandomNumberGenerator import RandomNumberGenerator
#The Source object is a Process
class Source(Process):
def __init__(self, id, name, dist, time, item):
Process.__init__(self)
self.id=id
self.objName=name
self.distType=dist #label that sets the distribution type
self.interArrivalTime=time #the mean interarrival time
self.totalInterArrivalTime=0 #the total interarrival time
self.numberOfArrivals=0 #the number of entities that were created
self.next=[] #list with the next objects in the flow
self.type="Source" #String that shows the type of object
#self.waitToDispose=False
self.rng=RandomNumberGenerator(self, self.distType)
self.rng.avg=time
self.item=item #the type of object that the Source will generate
#self.Res=Resource(capacity=infinity)
def initialize(self):
Process.__init__(self)
self.Res=Resource(capacity=infinity)
self.Res.activeQ=[]
self.Res.waitQ=[]
def Run(self):
i=0
if(self.distType=="Fixed"): #if the distribution type is fixed
from Globals import G
while 1:
#self.waitToDispose=True
self.numberOfArrivals+=1 #we have one new arrival
#entity=Entity("Ent"+str(i))
entity=self.item(self.item.type+str(i)) #create the Entity object and assign its name
entity.creationTime=now() #assign the current simulation time as the Entity's creation time
self.outputTrace(self.item.type+str(i)) #output the trace
self.Res.activeQ.append(entity) #append the entity to the resource
i+=1
#yield hold,self,self.interArrivalTime #one entity at every interArrivalTime
yield hold,self,self.rng.generateNumber()
elif(self.distType=="Exp"): #if the distribution type is exponential
from Globals import G
while 1:
#self.waitToDispose=True
self.numberOfArrivals+=1 #we have one new arrival
#entity=Entity("Ent"+str(i)) #create the Entity object and assign its name
entity=self.item(self.item.type+str(i)) #create the Entity object and assign its name
entity.creationTime=now() #assign the current simulation time as the Entity's creation time
self.outputTrace(self.item.type+str(i)) #output the trace
i+=1
self.Res.activeQ.append(entity) #append the entity to the resource
timeTillNextArrival=G.Rnd.expovariate(1.0/(self.interArrivalTime)) #create a random number that follows the
#exponential distribution
#yield hold,self,timeTillNextArrival #one entity at every interArrivalTime
yield hold,self,self.rng.generateNumber()
self.totalInterArrivalTime+=timeTillNextArrival
else: #if the distribution type is something else it is an error
print "Distribution Error in Source "+str(self.id)
#sets the routing out element for the Source
def defineRouting(self, n):
self.next=n
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
pass #no actions for the Source
#checks if the Source can dispose an entity to the following object
def haveToDispose(self):
#return self.waitToDispose
return len(self.Res.activeQ)>0
#removes an entity from the Source
def removeEntity(self):
self.Res.activeQ.pop(0)
#if(len(self.Res.activeQ)==0):
#self.waitToDispose=False
#outputs message to the trace.xls. Format is (Simulation Time | Entity Name | "generated")
def outputTrace(self, message):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1,message)
G.traceSheet.write(G.traceIndex,2,"generated")
G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation)
if(G.traceIndex==65536):
G.traceIndex=0
G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
#outputs data to "output.xls"
def outputResultsXL(self, MaxSimtime):
pass
File added
'''
Created on 8 Nov 2012
@author: George
'''
'''
script for making the project into a standalone .exe file
this fails since I used sciPy
'''
from distutils.core import setup
import py2exe
setup(
options = {
"py2exe":{
#"dll_excludes": [ "HID.DLL", "libmmd.dll","w9xpopen.exe"],
#"MSVCP90.dll","libifcoremd.dll",
}
},
console=['Line01.py'])
File added
File added
File added
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment