In [ ]:
# hide all code by default via JavaScript
from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
The raw code for this Jupyter notebook is by default hidden for easier reading.
To toggle on/off the raw code, click <a href="javascript:code_toggle()">here</a>.''')
In [ ]:
#########################
# defs and imports
#########################
import logging
import os
import shutil
import json
import threading
import traceback
import numpy as np
from numpy.linalg import inv
from nis_util import *
from simple_detection import *
from skimage.transform import AffineTransform
from skimage.io import imread
from xmlrpc.client import ServerProxy
from annotation import manually_correct_rois
from automation import WidgetProgressIndicator
In [ ]:
###################
# set up the environment, nis, and image saving path
###################
import resources
# Wrapper for default values
class WingScannerSettings:
def __init__(self):
# value is (description, value)
self.path_to_nis = ('Path to NIS .exe', 'C:\\Program Files\\NIS-Elements\\nis_ar.exe')
self.save_base_path = ('Local Temp Folder', 'C:\\Users\\Nikon\\Documents\\automation_temp')
self.save_server_path_local = ('Destination Folder on Server (Network Share)', 'Y:\\results')
self.save_server_path_remote = ('Destination Folder on Server (On Server)', '/data/wing-scanner/results')
# location of the calibration files
self.calib_left = ('Calibration File (left)', resources.left_calib)
self.calib_mid = ('Calibration File (mid)', resources.mid_calib)
self.calib_right = ('Calibration File (right)', resources.right_calib)
# detail images z settings
self.z_drive= ('Z device for detail stacks', 'NIDAQ Piezo Z')
self.z_range = ('Z range (um)', 50)
self.z_step= ('Z steps (um)', 2)
# plot size
%matplotlib inline
plt.rcParams['figure.figsize'] = [10,10]
In [ ]:
#################
# do the scans
#################
style = {'description_width': 'initial'}
from ipywidgets import Layout, HBox, VBox, Box, Checkbox, Text, BoundedFloatText, Button, FloatProgress, Label, Dropdown, Tab, Layout
from IPython.display import display
import automation
from copy import copy
logging.basicConfig(format='%(asctime)s - %(levelname)s in %(funcName)s: %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)
settings = WingScannerSettings()
# this will fail on systems without nis -> use dummy values
try:
pos = get_position(settings.path_to_nis[1])
color = is_color_camera(settings.path_to_nis[1])
ocs = get_optical_confs(settings.path_to_nis[1])
except FileNotFoundError as e:
pos = (0, 0, 0, 0)
color = False
ocs = ['oc_1', 'oc_2']
if color:
settings.calib_left = ('Calibration File (left)', resources.left_color_calib)
settings.calib_mid = ('Calibration File (mid)', resources.mid_color_calib)
settings.calib_right = ('Calibration File (right)', resources.right_color_calib)
# Tab 1: basic settings
selection_oc_ov = Dropdown(
options=ocs,
value=ocs[0],
disabled=False,
description='Overview OC:',
style=style
)
selection_oc_det_dia = Dropdown(
options=ocs,
value=ocs[0],
disabled=False,
description='detailed DIA OC:',
style=style
)
selection_oc_det_fluo_vb = Box(
[Checkbox(description='',indent=False),
Dropdown(
options=ocs,
value=ocs[0],
description='Detail fluo OC :',
disabled=False,
style=style )])
manual_annot_check = Checkbox(description='Manually correct detections?')
detection_first_check = Checkbox(description='Do all overviews/detections first')
hbox_ocs_mendatory = VBox([selection_oc_ov, selection_oc_det_dia])
hbox_ocs_optionnal = VBox([selection_oc_det_fluo_vb, manual_annot_check, detection_first_check])
sub_folder = Text(description='subfolder name:', style=style)
left = HBox([Checkbox(description='left slide'), Text(description='prefix:'),
Checkbox(description='manual focus position', value=True), BoundedFloatText(description='z', value=float(pos[2]), min=0, max=5000, step=10)])
mid = HBox([Checkbox(description='mid slide'), Text(description='prefix:'),
Checkbox(description='manual focus position', value=True), BoundedFloatText(description='z', value=float(pos[2]), min=0, max=5000, step=10)])
right = HBox([Checkbox(description='right slide'), Text(description='sample name:'),
Checkbox(description='manual focus position', value=True), BoundedFloatText(description='z', value=float(pos[2]), min=0, max=5000, step=10)])
status_main = HBox([FloatProgress(), Label()])
status_detail = HBox([FloatProgress(), Label()])
go = Button(description='GO')
tab1 = VBox([ hbox_ocs_mendatory, hbox_ocs_optionnal, sub_folder, left, mid, right, status_main, status_detail, go])
settings_textboxes = [Text(description=v[0], value=str(v[1]), layout=Layout(width='80%'), style=style) for _,v in vars(settings).items()]
tab2 = VBox([
Label('Expert settings, only change if you know what you are doing')
] + settings_textboxes )
tabs = Tab(children=[tab1, tab2])
tabs.set_title(0, 'Wing Scanner')
tabs.set_title(1, 'Expert Settings')
display(tabs)
status = WidgetProgressIndicator(status_detail.children[0], status_detail.children[1])
def onclick_go(btn):
btn.disabled = True
# update settings object
for i, k in enumerate(settings.__dict__):
settings.__dict__[k] = (settings_textboxes[i].description, settings_textboxes[i].value)
# NB: we change the calibration if we use the color cam
# TODO: respect user choice for custom calibration
try:
set_optical_configuration(settings.path_to_nis[1], selection_oc_ov.value)
color = is_color_camera(settings.path_to_nis[1])
if color:
settings.calib_left = ('Calibration File (left)', resources.left_color_calib)
settings.calib_mid = ('Calibration File (mid)', resources.mid_color_calib)
settings.calib_right = ('Calibration File (right)', resources.right_color_calib)
else:
settings.calib_left = ('Calibration File (left)', resources.left_calib)
settings.calib_mid = ('Calibration File (mid)', resources.mid_calib)
settings.calib_right = ('Calibration File (right)', resources.right_calib)
except Exception as e:
pass
save_path_local = settings.save_server_path_local[1]
save_path_remote = settings.save_server_path_remote[1]
if sub_folder.value:
save_path_local = os.path.join(save_path_local, sub_folder.value)
save_path_remote = (os.path.join(save_path_remote, sub_folder.value)).replace(os.sep, '/')
logger.info('Saving files to (local drive) %s '%(save_path_local))
logger.info('Saving files to (server) %s '%(save_path_remote))
oc_overview = selection_oc_ov.value
ocs_detail = [selection_oc_det_dia.value]
if selection_oc_det_fluo_vb.children[0].value:
logger.info('Imaging also a second channel')
ocs_detail.append(selection_oc_det_fluo_vb.children[1].value)
slide_left = left.children[1].value if left.children[0].value else None
slide_mid = mid.children[1].value if mid.children[0].value else None
slide_right = right.children[1].value if right.children[0].value else None
z_left = float(left.children[3].value) if left.children[2].value else None
z_mid = float(mid.children[3].value) if mid.children[2].value else None
z_right = float(right.children[3].value) if right.children[2].value else None
status_main.children[0].value = 0
status_main.children[1].value = 'scanning left'
# TODO: set meaningful default in automation
config = automation.CommonParameters()
config.path_to_nis = settings.path_to_nis[1]
config.prefix = 'experiment'
config.progress_indicator = status
config.save_base_path = settings.save_base_path[1]
config.server_path_local = save_path_local
config.server_path_remote = save_path_remote
ov_param = automation.OverviewParameters()
ov_param.export_as_tiff = True
ov_param.field_def_file = None
ov_param.manual_z = z_left
ov_param.oc_overview = oc_overview
ov_param.return_overview_img = True
det_param = automation.DetectionParameters()
# TODO: add to settings
#det_param.detector_adress
det_param.do_manual_annotation = manual_annot_check.value
#det_param.object_filter = {}
det_param.plot_detection = True
detail_param = automation.DetailParameters()
detail_param.auto_focus_detail = True
detail_param.channel_for_autofocus = 0
detail_param.channel_for_stitch = 0
detail_param.dry_run_details = False
detail_param.ocs_detail = ocs_detail
detail_param.projection_params = True
#detail_param.stitcher_adress
detail_param.tiff_export_details = True
detail_param.z_drive = settings.z_drive[1]
detail_param.z_range = int(settings.z_range[1])
detail_param.z_step = int(settings.z_step[1])
# TODO: add callback to set
configs = []
ov_params = []
det_params = []
detail_params = []
do_scan_left = slide_left != None
if do_scan_left:
logger.info('Scanning left scan.')
config_l = copy(config)
config_l.prefix = slide_left
ov_param_l = copy(ov_param)
ov_param_l.field_def_file = settings.calib_left[1]
configs.append(config_l)
ov_params.append(ov_param_l)
det_params.append(det_param)
detail_params.append(detail_param)
'''
do_scan(settings.calib_left[1], oc_overview, ocs_detail, settings.path_to_nis[1], settings.save_base_path[1],
slide_left, save_path_local, save_path_remote,
manual_z_overview=z_left, z_drive=settings.z_drive[1],
z_range=int(settings.z_range[1]), z_step=int(settings.z_step[1]), progress_indicator=status,
manual_annotation_check = manual_annot_check.value )
'''
else:
logger.info('Skipping left slide.')
# mid slide
status_main.children[0].value = 33
status_main.children[1].value = 'scanning mid'
do_scan_mid = slide_mid != None
if do_scan_mid:
logger.info('Scanning mid scan.')
config_m = copy(config)
config_m.prefix = slide_mid
ov_param_m = copy(ov_param)
ov_param_m.field_def_file = settings.calib_mid[1]
configs.append(config_m)
ov_params.append(ov_param_m)
det_params.append(det_param)
detail_params.append(detail_param)
'''
do_scan(settings.calib_mid[1], oc_overview, ocs_detail, settings.path_to_nis[1], settings.save_base_path[1],
slide_mid, save_path_local, save_path_remote,
manual_z_overview=z_mid, z_drive=settings.z_drive[1],
z_range=int(settings.z_range[1]), z_step=int(settings.z_step[1]), progress_indicator=status,
manual_annotation_check = manual_annot_check.value)
'''
else:
logger.info('Skipping middle slide.')
status_main.children[0].value = 66
status_main.children[1].value = 'scanning right'
# right slide
do_scan_right = slide_right != None
if do_scan_right:
logger.info('Scanning right scan.')
config_r = copy(config)
config_r.prefix = slide_right
ov_param_r = copy(ov_param)
ov_param_r.field_def_file = settings.calib_right[1]
configs.append(config_r)
ov_params.append(ov_param_r)
det_params.append(det_param)
detail_params.append(detail_param)
'''
do_scan(settings.calib_right[1], oc_overview, ocs_detail, settings.path_to_nis[1], settings.save_base_path[1],
slide_right, save_path_local, save_path_remote,
manual_z_overview=z_right, z_drive=settings.z_drive[1],
z_range=int(settings.z_range[1]), z_step=int(settings.z_step[1]), progress_indicator=status,
manual_annotation_check = manual_annot_check.value)
'''
else:
logger.info('Skipping right slide.')
status_main.children[0].value = 100
status_main.children[1].value = 'Done'
if not detection_first_check.value:
automation.do_scan(configs, ov_params, det_params, detail_params)
else:
automation.do_scan_detection_first(configs, ov_params, det_params, detail_params)
btn.disabled = False
go.on_click(onclick_go)
If you want to manually focus on a slide, tick manual focus and enter the z-focus position (in microns)