Commit 85d07291 authored by Georgios Dagkakis's avatar Georgios Dagkakis

batch plugins moved to new location

parent e4638f49
from copy import copy
import json
import time
import random
import operator
import datetime
from dream.plugins import plugin
class AddBatchStations(plugin.InputPreparationPlugin):
""" Input preparation
checks if the Batch Station processes Batchs or SubBatches and in the former case adds a decomposition/reassembly
to set to the working batch
"""
def preprocess(self, data):
nodes=copy(data['graph']['node'])
edges=copy(data['graph']['edge'])
# get the number of units for a standard batch
standardBatchUnits=0
for node_id, node in nodes.iteritems():
if node['_class']=='Dream.BatchSource':
standardBatchUnits=int(node['batchNumberOfUnits'])
# loop in BatchScrapMachines to change the classes if need be
for node_id, node in nodes.iteritems():
if node['_class']=='Dream.BatchScrapMachine':
# get the first successor. If it is BatchReassembly set the class to M3
successorIdList=self.getSuccessors(data, node_id)
if successorIdList:
successorId=successorIdList[0]
successorClass=nodes[successorId]['_class']
if successorClass=='Dream.BatchReassembly':
data['graph']['node'][node_id]['_class']='Dream.M3'
# get the first predecessor. If it is BatchDecomposition set the class to BatchScrapMachineAfterDecompose
predecessorIdList=self.getPredecessors(data, node_id)
if predecessorIdList:
predecessorId=predecessorIdList[0]
predecessorClass=nodes[predecessorId]['_class']
if predecessorClass=='Dream.BatchDecomposition':
data['graph']['node'][node_id]['_class']='Dream.BatchScrapMachineAfterDecompose'
# loop through the nodes to find the machines that do need addition
machinesThatNeedAddition={}
for node_id, node in nodes.iteritems():
if node['_class']=='Dream.BatchScrapMachine' and self.checkIfMachineNeedsAddition(data,node_id,standardBatchUnits):
machinesThatNeedAddition[node_id]=node
# loop in BatchDecompositions to change the classes to BatchDecompositionBlocking
for node_id, node in nodes.iteritems():
if node['_class']=='Dream.BatchDecomposition':
data['graph']['node'][node_id]['_class']='Dream.BatchDecompositionBlocking'
# loop in BatchReassemblies to change the classes to BatchReassemblyBlocking
for node_id, node in nodes.iteritems():
if node['_class']=='Dream.BatchReassembly':
data['graph']['node'][node_id]['_class']='Dream.BatchReassemblyBlocking'
data['graph']['node'][node_id]['outputResults']=1
# loop in BatchDecompositions to change the classes to BatchDecompositionStartTime for the ones that
# are just after the source
# XXX this is not generic. In the future the user may have to define it
for node_id, node in nodes.iteritems():
if node['_class']=='Dream.BatchDecompositionBlocking':
predecessorId=self.getPredecessors(data, node_id)[0]
predecessorClass=nodes[predecessorId]['_class']
if predecessorClass=='Dream.BatchSource':
data['graph']['node'][node_id]['_class']='Dream.BatchDecompositionStartTime'
# loop through the nodes
for node_id, node in machinesThatNeedAddition.iteritems():
# find BatchScrapMachines that process batches
import math
workingBatchSize=int((node.get('workingBatchSize')))
numberOfSubBatches=int((math.ceil((standardBatchUnits/float(workingBatchSize)))))
#create a batchDecomposition
batchDecompositionId=node_id+'_D'
data['graph']['node'][batchDecompositionId]={
"name": batchDecompositionId,
"processingTime": {
"Fixed": {
"mean": 0
}
},
"numberOfSubBatches": numberOfSubBatches,
"wip": [],
"element_id": "DreamNode_39",
"_class": "Dream.BatchDecompositionBlocking",
"id": batchDecompositionId
}
#put the batchDecomposition between the predecessor and the node
for edge_id, edge in edges.iteritems():
if edge['destination']==node_id:
source=edge['source']
# remove the edge
data['graph']['edge'].pop(edge_id,None)
# add an edge from source to batchDecomposition
self.addEdge(data, source, batchDecompositionId)
# add an edge from batchDecomposition machine
self.addEdge(data, batchDecompositionId, node_id)
#create a batchReassembly
batchReassemblyId=node_id+'_R'
data['graph']['node'][batchReassemblyId]={
"name": batchReassemblyId,
"processingTime": {
"Fixed": {
"mean": 0
}
},
"outputResults": 1,
"numberOfSubBatches": numberOfSubBatches,
"wip": [],
"_class": "Dream.BatchReassemblyBlocking",
"id": batchReassemblyId
}
#put the batchReassembly between the node and the successor
for edge_id, edge in edges.iteritems():
if edge['source']==node_id:
destination=edge['destination']
# remove the edge
data['graph']['edge'].pop(edge_id,None)
# add an edge from machine to batchReassembly
self.addEdge(data, node_id, batchReassemblyId)
# add an edge from batchReassembly to destination
self.addEdge(data, batchReassemblyId, destination)
# set all the Queue types to gether wip data
for node in data["graph"]["node"].values():
if node['_class'] in ['Dream.Queue', 'Dream.LineClearance', 'Dream.RoutingQueue']:
node['gatherWipStat'] = 1
return data
# returns true if it is needed to add decomposition/reassembly
def checkIfMachineNeedsAddition(self, data, machineId,standardBatchUnits):
nodes=copy(data['graph']['node'])
workingBatchSize=(nodes[machineId].get('workingBatchSize',standardBatchUnits))
if workingBatchSize:
workingBatchSize=int(workingBatchSize)
else: # if the workingBatchSize is not defined by the user set it to standardBatchUnits
workingBatchSize=standardBatchUnits
# if the workingBatchSize is equal or higher to standardBatchUnits we do not need to add decomposition/reassembly
if workingBatchSize>=standardBatchUnits:
return False
# loop in the predecessors
currentId=machineId
while 1:
predecessorIdsList=self.getPredecessors(data, currentId)
# get the first. In this model every machine is fed by one point
if predecessorIdsList:
predecessorId=predecessorIdsList[0]
# if there is no predecessor, i.e. the start was reached break
else:
break
predecessorClass=nodes[predecessorId]['_class']
# if BatchDecomposition is reached we are in subline so return False
if predecessorClass=='Dream.BatchDecomposition':
return False
# if BatchReassembly is reached we are not in subline so return True
elif predecessorClass=='Dream.BatchReassembly':
return True
currentId=predecessorId
return True
\ No newline at end of file
from datetime import datetime
import random
from pprint import pformat
from dream.plugins import plugin
from dream.plugins.TimeSupport import TimeSupportMixin
import datetime
from copy import copy
class BatchesOperatorGantt(plugin.OutputPreparationPlugin, TimeSupportMixin):
def postprocess(self, data):
"""Post process the data for Gantt gadget
"""
strptime = datetime.datetime.strptime
# read the current date and define dateFormat from it
try:
now = strptime(data['general']['currentDate'], '%Y/%m/%d %H:%M')
data['general']['dateFormat']='%Y/%m/%d %H:%M'
except ValueError:
now = strptime(data['general']['currentDate'], '%Y/%m/%d')
data['general']['dateFormat']='%Y/%m/%d'
maxSimTime=data['general']['maxSimTime']
self.initializeTimeSupport(data)
date_format = '%d-%m-%Y %H:%M'
resultElements=data['result']['result_list'][-1]['elementList']
task_dict = {}
# loop in the results to find Operators
colorList=['blue','green','red',
'gold','black','Aqua',
'DarkRed','Fuchsia','Gray',
'magenta','yellow','Olive',
'orange','purple','pink']
# create a dictionary so that all stations have their own color
colorDict={}
nodes=data['graph']['node']
i=0
for node_id, node in nodes.iteritems():
if node['_class'].startswith('Dream.BatchScrapMachine') or node['_class']=='Dream.M3':
colorDict[node_id]=colorList[i]
i+=1
if i==len(colorList):
i=0
# set off-shift color to white
colorDict['off-shift']='white'
for element in resultElements:
if element['_class']=="Dream.Operator":
operatorId=element['id']
# add the operator in the task_dict
task_dict[element['id']] = dict(
id=operatorId,
text=operatorId,
type='operator',
open=False)
schedule=copy(element['results']['schedule'])
# in the cases the operator exits and the enters in the same station merge those records
k=0
for record in schedule:
for nextRecord in schedule[k+1:]:
if nextRecord['stationId']==record['stationId']\
and nextRecord['entranceTime']==record['exitTime']\
and not record is schedule[-1]:
nextExitTime=nextRecord.get('exitTime',maxSimTime)
record['exitTime']=nextExitTime
schedule.remove(nextRecord)
else:
continue
k+=1
# loop though the records
k=1
for record in schedule:
entranceTime=record['entranceTime']
exitTime=record.get('exitTime',None)
if not exitTime:
exitTime=maxSimTime
k+=1
task_dict[operatorId+record['stationId']+str(k)] = dict(
id=operatorId+record['stationId']+str(k),
parent=operatorId,
text=record['stationId'],
start_date=self.convertToRealWorldTime(
entranceTime).strftime(date_format),
stop_date=self.convertToRealWorldTime(
exitTime).strftime(date_format),
open=False,
entranceTime=entranceTime,
duration=exitTime-entranceTime,
color=colorDict[record['stationId']]
)
# return the result to the gadget
result = data['result']['result_list'][-1]
result[self.configuration_dict['output_id']] = dict(
time_unit=self.getTimeUnitText(),
subscales=[dict(unit="hour", step=1, date="%H:%i")],
task_list=sorted(task_dict.values(),
key=lambda task: (task.get('parent'),
task.get('type') == 'project',
task.get('entranceTime'),task.get('id'))))
return data
from dream.plugins import plugin
import xlwt
import StringIO
class BatchesOperatorSpreadsheet(plugin.OutputPreparationPlugin):
""" Output the schedule of operators in an Excel file to be downloaded
"""
def postprocess(self, data):
rowIndex=0
scheduleFile = xlwt.Workbook()
scheduleSheet = scheduleFile.add_sheet('Operator Schedule', cell_overwrite_ok=True)
headingStyle=xlwt.easyxf("font: bold on; borders: bottom dashed;font: color red;")
PBstyle=xlwt.easyxf("font: bold on;font: color red;")
scheduleSheet.write(rowIndex,0,'Operator',headingStyle)
scheduleSheet.write(rowIndex,1,'Machine',headingStyle)
scheduleSheet.write(rowIndex,2,'Start Time',headingStyle)
scheduleSheet.write(rowIndex,3,'End Time',headingStyle)
rowIndex+=1
# get the result the the router gives
for element in data['result']['result_list'][-1]['elementList']:
if element['_class']=='Dream.SkilledRouter':
solutionList=element['results']['solutionList']
# create a list with all the operator ids that were at least in one allocation
operatorList=[]
for record in solutionList:
for key in record['allocation']:
if key not in operatorList:
operatorList.append(key)
# create for every operator a list like [time,machineId]. If the operator is not in the solution latter is to None
normalizedSchedule={}
for operator in operatorList:
operatorSchedule=[]
normalizedSchedule[operator]=[]
for record in solutionList:
time=record['time']
allocation=record['allocation']
machineId=None
if operator in allocation.keys():
machineId=allocation[operator]
operatorSchedule.append([time,machineId])
# now create a normalized schedule for the operator like [MachineId, EntranceTime, ExitTime]
k=0
for record in operatorSchedule:
normalizedSchedule[operator].append([record[1],record[0]])
for nextRecord in operatorSchedule[k+1:]:
if nextRecord[1]==record[1]:
operatorSchedule.remove(nextRecord)
else:
normalizedSchedule[operator][-1].append(nextRecord[0])
break
k+=1
# output the results in excel
for operator in normalizedSchedule.keys():
scheduleSheet.write(rowIndex,0,operator,PBstyle)
for record in normalizedSchedule[operator]:
# skip the records that have 'None'
if not record[0]:
continue
scheduleSheet.write(rowIndex,1,record[0])
scheduleSheet.write(rowIndex,2,record[1])
scheduleSheet.write(rowIndex,3,record[2])
rowIndex+=1
# return the workbook as encoded
scheduleStringIO = StringIO.StringIO()
scheduleFile.save(scheduleStringIO)
encodedScheduleFile=scheduleStringIO.getvalue().encode('base64')
data['result']['result_list'][-1][self.configuration_dict['output_id']] = {
'name': 'Operator_Schedule.xls',
'mime_type': 'application/vnd.ms-excel',
'data': encodedScheduleFile
}
return data
from dream.plugins import plugin
from copy import copy
class BatchesOperatorUtilization(plugin.OutputPreparationPlugin):
""" Output the station utilization metrics in a format compatible with
"""
def postprocess(self, data):
result = data['result']['result_list'][-1]
ticks = []
working_data = []
waiting_data = []
off_shift_data = []
options = {
"xaxis": {
"minTickSize": 1,
"ticks": ticks
},
"yaxis": {
"max": 100
},
"series": {
"bars": {
"show": True,
"barWidth": 0.8,
"align": "center"
},
"stack": True
}
}
series = [{
"label": "Working",
"data": working_data
}, {
"label": "Waiting",
"data": waiting_data
},
{
"label": "Off_shift",
"data": off_shift_data
}];
out = result[self.configuration_dict['output_id']] = {
"series": series,
"options": options
}
i = 0
for obj in result['elementList']:
if obj.get('_class') == 'Dream.Operator':
if obj['results']['working_ratio']:
working_data.append((i, obj['results']['working_ratio'][0]))
if obj['results']['waiting_ratio']:
waiting_data.append((i, obj['results']['waiting_ratio'][0]))
if obj['results']['off_shift_ratio']:
off_shift_data.append((i, obj['results']['off_shift_ratio'][0]))
ticks.append((i, obj.get('name', self.getNameFromId(data, obj['id']))))
i += 1
return data
from copy import copy
import json
import time
import random
import operator
import datetime
from dream.plugins import plugin
from dream.plugins.TimeSupport import TimeSupportMixin
from dream.plugins.ReadShiftFromSpreadsheet import ReadShiftFromSpreadsheet
class BatchesShift(ReadShiftFromSpreadsheet):
""" Input prepration
extends standard ReadShiftFromSpreadsheet to accept 'All' to define all stations
sets also the attributes of shifts to objects
XXX to be extended to operators
"""
def preprocess(self, data):
nodes=data['graph']['node']
machineshiftData=data['input'].get('machine_shift_spreadsheet', None)
operatorshiftData=data['input'].get('operator_shift_spreadsheet', None)
# create a string with all station ids separated by commas
allString=''
for node_id, node in nodes.iteritems():
if node['_class'].startswith('Dream.BatchScrapMachine') or node['_class']=='Dream.M3':
allString+=node_id
allString+=','
# if in machine shift there is a
for element in machineshiftData:
if element[1] in ['ALL','All','all']:
element[1]=allString
# create a string with all operator ids separated by commas
allString=''
for node_id, node in nodes.iteritems():
if node['_class']=='Dream.Operator':
allString+=node_id
allString+=','
# if in machine shift there is a
for element in operatorshiftData:
if element[1] in ['ALL','All','all']:
element[1]=allString
# run the standard shift plugin
data=ReadShiftFromSpreadsheet.preprocess(self, data)
# set attributes to shifts
for node_id, node in nodes.iteritems():
interruptions=node.get('interruptions',None)
if interruptions:
shift=interruptions.get('shift',None)
if shift:
interruptions['shift']['thresholdTimeIsOnShift']=0
interruptions['shift']['receiveBeforeEndThreshold']=7
interruptions['shift']['endUnfinished']=1
return data
from dream.plugins import plugin
from copy import copy
class BatchesStationUtilization(plugin.OutputPreparationPlugin):
""" Output the station utilization metrics in a format compatible with
"""
def postprocess(self, data):
result = data['result']['result_list'][-1]
ticks = []
working_data = []
waiting_data = []
failure_data = []
blockage_data = []
off_shift_data = []
options = {
"xaxis": {
"minTickSize": 1,
"ticks": ticks
},
"yaxis": {
"max": 100
},
"series": {
"bars": {
"show": True,
"barWidth": 0.8,
"align": "center"
},
"stack": True
}
}
series = [{
"label": "Working",
"data": working_data
}, {
"label": "Waiting",
"data": waiting_data
}, {
"label": "Failures",
"data": failure_data
}, {
"label": "Blockage",
"data": blockage_data
},
{
"label": "off_shift",
"data": off_shift_data
}];
out = result[self.configuration_dict['output_id']] = {
"series": series,
"options": options
}
i = 0
for obj in result['elementList']:
if obj.get('_class').startswith('Dream.BatchScrapMachine') or obj.get('_class')=='Dream.M3':
nextId=self.getSuccessors(data, obj['id'])[0]
nextClass=data['graph']['node'][nextId]['_class']
objResults=copy(obj['results'])
# if a station is before batch-reassembly then the blockage of reassembly is added to the station
# and reducted from its waiting
nextResults={}
if nextClass.startswith('Dream.BatchReassembly'):
for nextObj in result['elementList']:
if nextObj['id']==nextId:
nextResults=nextObj["results"]
if nextResults:
nextBlockage=nextResults['blockage_ratio'][0]
objResults['blockage_ratio'][0]=nextBlockage
objResults['waiting_ratio'][0]-=nextBlockage
if objResults['working_ratio']:
working_data.append((i, objResults['working_ratio'][0]))
if objResults['waiting_ratio']:
waiting_data.append((i, objResults['waiting_ratio'][0]))
if objResults['failure_ratio']:
failure_data.append((i, objResults['failure_ratio'][0]))
if objResults['blockage_ratio']:
blockage_data.append((i, objResults['blockage_ratio'][0]))
if objResults['off_shift_ratio']:
off_shift_data.append((i, objResults['off_shift_ratio'][0]))
ticks.append((i, obj.get('name', self.getNameFromId(data, obj['id']))))
i += 1
return data
from copy import copy
import json
import time
import random
import operator
import StringIO
import xlrd
import numpy
from dream.plugins import plugin
class BatchesTabularExit(plugin.OutputPreparationPlugin):
""" Output the exit stats in a tab
"""
def postprocess(self, data):
numberOfReplications=int(data['general']['numberOfReplications'])
confidenceLevel=float(data['general']['confidenceLevel'])
maxSimTime=data['general']['maxSimTime']
timeUnit=data['general']['timeUnit']
if numberOfReplications==1:
# create the titles of the columns
data['result']['result_list'][0]['exit_output'] = [['KPI','Unit','Value']]
# loop the results and search for elements that have 'Exit' as family
for record in data['result']['result_list'][-1]['elementList']:
family=record.get('family',None)
# when found, add a row with the results of the specific exit
if family=='Exit':
batchesThroughput=record['results']['throughput'][0]
data['result']['result_list'][0]['exit_output'].append(['Number of batches produced','Batches',
batchesThroughput])
unitsThroughput=record['results'].get('unitsThroughput',None)
if unitsThroughput:
unitsThroughput=unitsThroughput[0]
if not unitsThroughput:
unitsThroughput=batchesThroughput
data['result']['result_list'][0]['exit_output'].append(['Number of units produced','Units',
unitsThroughput])
lineThroughput=batchesThroughput/float(maxSimTime)
data['result']['result_list'][0]['exit_output'].append(['Line throughput','Batches/'+timeUnit,
"%.2f" % lineThroughput])
unitDepartureRate=unitsThroughput/float(maxSimTime)
data['result']['result_list'][0]['exit_output'].append(['Average Unit Departure Rate',
'Units/'+timeUnit,
"%.2f" % unitDepartureRate])
avgCycleTime=record['results']['lifespan'][0]
data['result']['result_list'][0]['exit_output'].append(['Average Cycle Time',
timeUnit,
"%.2f" % avgCycleTime])
elif numberOfReplications>1:
# create the titles of the columns
data['result']['result_list'][0]['exit_output'] = [['KPI','Unit','Average','Std Dev','Min','Max',
str(float(confidenceLevel)*100)+'% CI LB ',
str(float(confidenceLevel)*100)+'% CI UB']]
for record in data['result']['result_list'][0]['elementList']:
family=record.get('family',None)
# when found, add a row with the results of the specific exit
if family=='Exit':
batchesThroughputList=record['results']['throughput']
batchesThroughputCI=self.getConfidenceInterval(batchesThroughputList,confidenceLevel)
data['result']['result_list'][0]['exit_output'].append(['Number of batches produced','Batches',
"%.2f" % self.getAverage(batchesThroughputList),
"%.2f" % self.getStDev(batchesThroughputList),
min(batchesThroughputList),
max(batchesThroughputList),
"%.2f" % batchesThroughputCI['lb'],
"%.2f" % batchesThroughputCI['ub']]
)
unitsThroughputList=record['results'].get('unitsThroughput',None)
if not unitsThroughputList:
unitsThroughputList=batchesThroughputList
unitsThroughputList=record['results']['unitsThroughput']
unitsThroughputCI=self.getConfidenceInterval(unitsThroughputList,confidenceLevel)
data['result']['result_list'][0]['exit_output'].append(['Number of units produced','Units',
"%.2f" % self.getAverage(unitsThroughputList),
"%.2f" % self.getStDev(unitsThroughputList),
min(unitsThroughputList),
max(unitsThroughputList),
"%.2f" % unitsThroughputCI['lb'],
"%.2f" % unitsThroughputCI['ub']]
)
lineThroughputList=[x/float(maxSimTime) for x in batchesThroughputList]
lineThroughputCI=self.getConfidenceInterval(lineThroughputList,confidenceLevel)
data['result']['result_list'][0]['exit_output'].append(['Line throughput','Batches/'+timeUnit,
"%.2f" % self.getAverage(lineThroughputList),
"%.2f" % self.getStDev(lineThroughputList),
"%.2f" % min(lineThroughputList),
"%.2f" % max(lineThroughputList),
"%.2f" % lineThroughputCI['lb'],
"%.2f" % lineThroughputCI['ub']]
)
unitDepartureRateList=[x/float(maxSimTime) for x in unitsThroughputList]
unitDepartureRateCI=self.getConfidenceInterval(unitDepartureRateList,confidenceLevel)
data['result']['result_list'][0]['exit_output'].append(['Unit Departure Rate',
'Units/'+timeUnit,
"%.2f" % self.getAverage(unitDepartureRateList),
"%.2f" % self.getStDev(unitDepartureRateList),
"%.2f" % min(unitDepartureRateList),
"%.2f" % max(unitDepartureRateList),
"%.2f" % unitDepartureRateCI['lb'],
"%.2f" % unitDepartureRateCI['ub']]
)
avgCycleTime=record['results']['lifespan']
avgCycleTimeList=record['results']['lifespan']
avgCycleTimeCI=self.getConfidenceInterval(avgCycleTimeList,confidenceLevel)
data['result']['result_list'][0]['exit_output'].append(['Cycle Time',timeUnit,
"%.2f" % self.getAverage(avgCycleTimeList),
"%.2f" % self.getStDev(avgCycleTimeList),
"%.2f" % min(avgCycleTimeList),
"%.2f" % max(avgCycleTimeList),
"%.2f" % avgCycleTimeCI['lb'],
"%.2f" % avgCycleTimeCI['ub']]
)
return data
\ No newline at end of file
from copy import copy
import json
import time
import random
import operator
import StringIO
import xlrd
import math
from dream.plugins import plugin
class BatchesTabularQueues(plugin.OutputPreparationPlugin):
""" Output the exit stats in a tab
"""
def postprocess(self, data):
numberOfReplications=int(data['general']['numberOfReplications'])
confidenceLevel=float(data['general']['confidenceLevel'])
maxSimTime=float(data['general']['maxSimTime'])
if numberOfReplications==1:
# create the titles of the columns
data['result']['result_list'][-1]['buffer_output'] = [['Buffer','Final Value','Average',
'Std Dev','Min','Max',]]
# loop the results and search for elements that have 'Exit' as family
for record in data['result']['result_list'][-1]['elementList']:
family=record.get('family',None)
# when found, add a row with the results of the specific exit
if family=='Buffer':
bufferId=record['id']
wip_stat_list=record['results']['wip_stat_list'][0]
bufferLevels=[int(x[1]) for x in wip_stat_list]
maxLevel=max(bufferLevels)
finalValue=wip_stat_list[-1][1]
timeListDict=self.createTimeListDict(wip_stat_list,maxSimTime)
totalLevel=0
minLevel=float('inf')
# count the minimum that has no zero duration
for level, duration in timeListDict.iteritems():
if duration and (level<minLevel):
minLevel=level
for level, duration in timeListDict.iteritems():
totalLevel+=level*duration
averageLevel=totalLevel/float(maxSimTime)
totalDistance=0
for level, duration in timeListDict.iteritems():
totalDistance+=((level-averageLevel)*(level-averageLevel))*duration
stdevLevel=math.sqrt(totalDistance/float(maxSimTime-1))
data['result']['result_list'][-1]['buffer_output'].append([bufferId,finalValue,
"%.2f" % averageLevel,
"%.2f" % stdevLevel,
minLevel,maxLevel])
elif numberOfReplications>1:
# create the titles of the columns
pass
return data
# takes the time list that ManPy outputs and creates a dict so that it is easier to get avg etc
def createTimeListDict(self, timeList,maxSimTime):
timeListDict={}
i=0
for record in timeList:
time=record[0]
level=int(record[1])
try:
nextTime=timeList[i+1][0]
except IndexError:
nextTime=maxSimTime
i+=1
if not (level in timeListDict.keys()):
timeListDict[level]=0
timeListDict[level]+=nextTime-time
return timeListDict
This diff is collapsed.
from copy import copy
import json
import time
import random
import operator
from datetime import datetime
from dream.plugins import plugin
class ReadSkilledOperators(plugin.InputPreparationPlugin):
""" Input prepration
reads the operators and their skills from the spreadsheet and adds them to the model
"""
def preprocess(self, data):
""" Set the WIP in queue from spreadsheet data.
"""
PBData=data['input'].get('operator_skill_spreadsheet', None)
node=data['graph']['node']
operatorPresent = False
if PBData:
PBData.pop(0) # pop the column names
for PBitem in PBData:
PBId=PBitem[0]
# in case there is no id, do not process the element
if not PBId:
continue
skills=PBitem[1].split(',')
node[PBId]={
"_class": "Dream.Operator",
"capacity": 1,
"name":PBId,
"skills":skills,
"ouputSchedule" : 1
}
operatorPresent = True
# if there is at least one operator
if operatorPresent:
nodes=data['graph']['node']
for station_id,station in nodes.iteritems():
# set the operation type of all machines to MT-Load-Processing
if station['_class'] in ['Dream.BatchScrapMachine','Dream.BatchScrapMachineBeforeReassembly',
'Dream.BatchScrapMachineAfterDecompose','Dream.M3']:
station["operationType"]="MT-Load-Processing"
# add EventGenerator for the allocation every 10 minutes
node['EV123454321']={ #(random id)
"name": "Allocator",
"argumentDict": "{}",
"interval": 40,
"stop": -1,
"id": "EV123454321",
"start": 0,
"interruptions": {},
"_class": "Dream.EventGenerator",
"method": "Dream.ManPyObject.requestAllocation"
}
# add EventGenerator for the allocation every 10 minutes
node['SkilledRouter01']={ #(random id)
"_class": "dream.simulation.SkilledOperatorRouter.SkilledRouter",
"name": "SkilledRouter01",
"outputSolutions":1,
"checkCondition":1
}
return data
# ===========================================================================
# Copyright 2013 University of Limerick
#
# This file is part of DREAM.
#
# DREAM is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DREAM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DREAM. If not, see <http://www.gnu.org/licenses/>.
# ===========================================================================
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
\ No newline at end of file
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