Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
dream
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
dream
Commits
85d07291
Commit
85d07291
authored
Mar 26, 2015
by
Georgios Dagkakis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
batch plugins moved to new location
parent
e4638f49
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1072 additions
and
0 deletions
+1072
-0
dream/plugins/Batches/AddBatchStations.py
dream/plugins/Batches/AddBatchStations.py
+167
-0
dream/plugins/Batches/BatchesOperatorGantt.py
dream/plugins/Batches/BatchesOperatorGantt.py
+105
-0
dream/plugins/Batches/BatchesOperatorSpreadsheet.py
dream/plugins/Batches/BatchesOperatorSpreadsheet.py
+79
-0
dream/plugins/Batches/BatchesOperatorUtilization.py
dream/plugins/Batches/BatchesOperatorUtilization.py
+63
-0
dream/plugins/Batches/BatchesShift.py
dream/plugins/Batches/BatchesShift.py
+59
-0
dream/plugins/Batches/BatchesStationUtilization.py
dream/plugins/Batches/BatchesStationUtilization.py
+92
-0
dream/plugins/Batches/BatchesTabularExit.py
dream/plugins/Batches/BatchesTabularExit.py
+114
-0
dream/plugins/Batches/BatchesTabularQueues.py
dream/plugins/Batches/BatchesTabularQueues.py
+75
-0
dream/plugins/Batches/BatchesWIPSpreadsheet.py
dream/plugins/Batches/BatchesWIPSpreadsheet.py
+228
-0
dream/plugins/Batches/ReadSkilledOperators.py
dream/plugins/Batches/ReadSkilledOperators.py
+66
-0
dream/plugins/Batches/__init__.py
dream/plugins/Batches/__init__.py
+24
-0
No files found.
dream/plugins/Batches/AddBatchStations.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesOperatorGantt.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesOperatorSpreadsheet.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesOperatorUtilization.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesShift.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesStationUtilization.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesTabularExit.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesTabularQueues.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/BatchesWIPSpreadsheet.py
0 → 100644
View file @
85d07291
This diff is collapsed.
Click to expand it.
dream/plugins/Batches/ReadSkilledOperators.py
0 → 100644
View file @
85d07291
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
dream/plugins/Batches/__init__.py
0 → 100644
View file @
85d07291
# ===========================================================================
# 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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment