"""Staining and cover-slip processes."""
from typing import TYPE_CHECKING
from ..specimens import Batch, Priority, Slide, Specimen
from .core import (BatchingProcess, CollationProcess, DeliveryProcess,
RunnerDurations, register_process)
if TYPE_CHECKING:
from ..model import Model
[docs]
def register_processes(env: 'Model') -> None:
"""Register processes to the simulation environment."""
register_process(env, Specimen, staining_start)
register_process(env, Batch[Slide], staining_regular)
register_process(env, Batch[Slide], staining_megas)
register_process(env, Specimen, post_staining)
# Staining machine batches
env.processes['batcher.staining_regular'] = BatchingProcess[Slide](
'batcher.staining_regular',
batch_size=env.batch_sizes.staining_regular,
out_process='staining_regular',
env=env
)
env.processes['batcher.staining_megas'] = BatchingProcess[Slide](
'batcher.staining_megas',
batch_size=env.batch_sizes.staining_megas,
out_process='staining_megas',
env=env
)
# Collation
env.processes['collate.staining.slides'] = CollationProcess(
'collate.staining.slides',
counter_name='num_slides',
out_process='collate.staining.blocks',
env=env
)
env.processes['collate.staining.blocks'] = CollationProcess(
'collate.staining.blocks',
counter_name='num_blocks',
out_process='post_staining',
env=env
)
# Delivery
env.processes['batcher.staining_to_labelling'] = BatchingProcess[Specimen](
'batcher.staining_to_labelling',
batch_size=env.batch_sizes.deliver_staining_to_labelling,
out_process='staining_to_labelling',
env=env
)
env.processes['staining_to_labelling'] = DeliveryProcess(
'staining_to_labelling',
runner=env.resources.microtomy_staff,
durations=RunnerDurations(
env.runner_times.extra_loading,
env.runner_times.staining_labelling,
env.runner_times.extra_unloading,
env.runner_times.staining_labelling # FUTURE: different outbound and return times?
),
out_process='labelling',
env=env
)
[docs]
def staining_start(self: Specimen) -> None:
"""Separate specimen slides and send to batching process for staining."""
self.env.wips.in_staining.value += 1
self.timestamp('staining_start')
for block in self.blocks:
for slide in block.slides:
slide.enter_sorted(
self.env.processes[
'batcher.staining_megas'
if slide.data['slide_type'] == 'megas'
else 'batcher.staining_regular'
].in_queue,
self.prio
)
[docs]
def staining_regular(self: Batch[Slide]) -> None:
"""Stain and cover-slip a batch of regular-sized slides."""
# LOAD
self.request(self.env.resources.staining_staff, self.env.resources.staining_machine)
self.hold(self.env.task_durations.load_staining_machine_regular)
self.release(self.env.resources.staining_staff)
# STAIN
self.hold(self.env.task_durations.staining_regular)
# TRANSFER TO COVERSLIP MACHINE
self.request(self.env.resources.staining_staff)
self.hold(self.env.task_durations.unload_staining_machine_regular)
self.release()
self.request(self.env.resources.staining_staff, self.env.resources.coverslip_machine)
self.hold(self.env.task_durations.load_coverslip_machine_regular)
self.release(self.env.resources.staining_staff)
# COVERSLIP
self.hold(self.env.task_durations.coverslip_regular)
# UNLOAD COVERSLIP MACHINE
self.request(self.env.resources.staining_staff)
self.hold(self.env.task_durations.unload_coverslip_machine_regular)
self.release() # release all
for slide in self.items:
slide.enter(self.env.processes['collate.staining.slides'].in_queue)
[docs]
def staining_megas(self: Batch[Slide]) -> None:
"""Stain and cover-slip a batch of mega slides."""
# LOAD
self.request(self.env.resources.staining_staff, self.env.resources.staining_machine)
self.hold(self.env.task_durations.load_staining_machine_megas)
self.release(self.env.resources.staining_staff)
# STAIN
self.hold(self.env.task_durations.staining_megas)
# UNLOAD
self.request(self.env.resources.staining_staff)
self.hold(self.env.task_durations.unload_staining_machine_megas)
self.release(self.env.resources.staining_machine)
# Keep staining staff for coverslipping tasks
for slide in self.items:
# MANUAL COVERSLIPPING FOR MEGA SLIDES
self.hold(self.env.task_durations.coverslip_megas)
slide.enter(self.env.processes['collate.staining.slides'].in_queue)
self.release() # release all
[docs]
def post_staining(self: Specimen) -> None:
"""Post-staining tasks."""
self.env.wips.in_staining.value -= 1
self.timestamp('staining_end')
if self.prio == Priority.URGENT:
self.enter_sorted(self.env.processes['staining_to_labelling'].in_queue, Priority.URGENT)
else:
self.enter(self.env.processes['batcher.staining_to_labelling'].in_queue)