Tools for Adaptive Feedback Microscopy
"""
Author: Sebastian Rhode
Date: 2016_11_29
File: Wizard_RareEventDetection_DLLs.czmac
Version: 4.1
Optimzed for the use with Celldiscoverer 7 and DF2.
Please adapt Focussing commands, especially FindSurface when using with other stands
1) - Select Overview Scan Experiment
2) - Select appropriate Image Analysis Pipeline
3) - Select Detailed Scan Experiment
4) - Specify the output folder for the image and data tables
Requires the following DLLs to be found inside the Zen program folder:
- RETools.dll
- TileTools.dll
"""
# import custom DLLs required for Rare Event Detection
import clr
clr.AddReference('RETools.dll')
clr.AddReference('TileTools.dll')
import RETools
import Tiles
ZEN Blue Python Script for Rare Event Detection
# Activate Zen.Application
RareEventDialog = ZenWindow()
RareEventDialog.Initialize('Rare Event Detection - Version : ' + str(version), 650, 750, True, True)
# add components to dialog
RareEventDialog.AddLabel('1) Select Overview Experiment ------------------------------')
RareEventDialog.AddDropDown('overview_exp', 'Overview Scan Experiment', expfiles, 0)
RareEventDialog.AddDropDown('objectiveOV', 'Objective OvervIew Scan', objectives.Names, 1)
RareEventDialog.AddDropDown('optovarOV', 'After-Mag OverViewScan', optovars.Names, 2)
RareEventDialog.AddCheckbox('SWAF_before_overview', 'OPTION - (Find Surface) & SWAF before Overview', True)
RareEventDialog.AddLabel('2) Select Image Analysis to detect objects -----------------')
RareEventDialog.AddDropDown('ip_pipe', 'Image Analysis Pieline', ipfiles, 0)
RareEventDialog.AddLabel('3) Select Detail Scan Experiment ---------------------------')
RareEventDialog.AddDropDown('detailed_exp', 'Detailed Scan Experiment', expfiles, 1)
RareEventDialog.AddDropDown('objectiveDT', 'Objective Detailed Scan', objectives.Names, 2)
RareEventDialog.AddDropDown('optovarDT', 'After-Mag Detailed Scan', optovars.Names, 2)
RareEventDialog.AddCheckbox('checkoffset', 'OPTION - Check offset between FS and SWAF', False)
RareEventDialog.AddCheckbox('manualoffset', 'OPTION - Enter Offset manually', False)
RareEventDialog.AddDoubleRange('offsetvalue', 'Enter manual Offset [micron]', 0, 0, 100)
RareEventDialog.AddLabel('4) Specify Output Folder to save the images -----------------')
RareEventDialog.AddFolderBrowser('outfolder','Output Folder for Images and Data Tables', imgfolder)
# show the window
result = RareEventDialog.Show()
if result.HasCanceled:
message = 'Macro was canceled by user.'
print message
raise SystemExit
# use the correct objective and optovar for the overview scan
RETools.RareEventTools.SetObjectivebyName(objOV, False)
RETools.RareEventTools.SetOptovarbyName(optoOV, False)
if SWAF_beforeOV==True:
try:
# initial focussing via FindSurface to assure a good starting position
# requires DF2 for Obsever or Celldiscoverer 7 --> otherwise comment line !!!
Zen.Acquisition.FindSurface()
except:
print 'Was not able to run Find Surface.'
try:
# run the SWAF using the settings from the OVScan --> check SWAF for overview experiment !!!
Zen.Acquisition.FindAutofocus(OVScan)
except:
print 'Was not able to run SWAF using the seetings: ', OverViewExpName
# get the resulting z-position
znew = Zen.Devices.Focus.ActualPosition
# try to adapt the Tile Experiment with new Z-Position
try:
Tiles.TileTools.ModifyTileRegionsZonly(OVScan, znew)
print 'Adapted Z-Position of Tile OverView. New Z = ',znew
except:
print 'Was not able to adapt Z-Position of Overview Scan Experiment.'
# execute detailed experiment at the position of every detected object
for i in range(0, num_POI, 1):
# get the object information from the position table
POI_ID = SingleObj.GetValue(i,0) # get the ID of the object - IDs start with 2 !!!
xpos = SingleObj.GetValue(i,colID['BCcolx']) # get X-stage position from table
ypos = SingleObj.GetValue(i,colID['BCcoly']) # get Y-stage position from table
# move to the current position
Zen.Devices.Stage.MoveTo(xpos + dx_LSM, ypos + dy_LSM) # comment this, if one uses a simulated experiment
print 'Moving Stage to Object ID:', POI_ID, ' at :', round(xpos,2), round(ypos,2)
if useRecallFocus == False:
# Initial FindSurface before the Detail Scan starts
try:
Zen.Acquisition.FindSurface()
except:
'Was not able to run Find Surface.'
# calculate new focus position plus offset and move z-drive
zpos = Zen.Devices.Focus.ActualPosition + dzFS
print 'Move to Z-Position: ', round(zpos,2)
Zen.Devices.Focus.MoveTo(zpos)
elif useRecallFocus == True:
# alternative solution - use RecallFocus
try:
Zen.Acquisition.RecallFocus()
except:
print 'Was not able to run Recall Focus.'
zpos = Zen.Devices.Focus.ActualPosition
print 'New z-position after Recall Focus: ', zpos
# load the predefined detailed scan experiment
DetailScan = Zen.Acquisition.Experiments.GetByName(DetailExpName)
# only modify the Tile Properties if required IAS features BoundWidth and BoundHeight were found
# if experiment is a Tile Experiment
if DetailIsTileExp == True:
# Modify tile center position - get bounding rectangle width & height in microns
bcwidth = SingleObj.GetValue(i, colID['BCWidthcolx'])
bcheight = SingleObj.GetValue(i, colID['BCHeightcoly'])
print 'Width and Height : ', str(round(bcwidth,2)), str(round(bcheight,2))
print 'Modifying Tile Properties XYZ Position and width & height.'
# Modify the XYZ position of the tile region on-the-fly
Tiles.TileTools.ModifyTileRegionsXYZ(DetailScan, xpos, ypos, zpos)
# Modify ConturSize for the tile according to the size of the bounding rectangle
Tiles.TileTools.ModifyTileRegionsSize(DetailScan, bcwidth, bcheight)
print 'New Tile Properties: ', round(xpos,2), round(ypos,2), round(zpos,2), round(bcwidth,2), round(bcheight,2)
# execute the experiment
print 'Running Detail Scan Experiment at new XYZ position.'
# run the Detail Scan
output_detailscan = Zen.Acquisition.Execute(DetailScan)
DetailScan.Close()
# get the image data name
dtscan_name = output_detailscan.Name
# save the image data to the selected folder and close the image
output_detailscan.Save(OutputFolder + '\\' + output_detailscan.Name)
output_detailscan.Close()
# rename the CZI regarding to the object ID - Attention - IDs start with 2 !!!
newname_dtscan = 'DTScan_ID' + str(POI_ID) + '.czi'
if verbose:
print 'Renaming File: ' + dtscan_name + ' to: ' + newname_dtscan + '\n'
File.Move(OutputFolder + '\\' + dtscan_name, OutputFolder + '\\' + newname_dtscan)
import csv
from System import Array
import sys
sys.path.append(r'c:\Projects\OAD\External_Python_Scripts_for_OAD')
import FijiTableTools as ft
from System.IO import File, Directory, Path
# define the resulr file to be read
txtfile = r'c:\Projects\RareEvent\Overview_10X_GFP_Results_Fiji.txt'
# initialize ZenTable object
table = ZenTable()
# read the result table and convert into a Zentable
table = ft.ReadResultTable(txtfile, 1, '\t', 'FijiTable', table)
# change the name of the table
table.Name = Path.GetFileNameWithoutExtension(Path.GetFileName(txtfile))
# show the table
Zen.Application.Documents.Add(table)
# clear all tile regions and positions
ZenExperimentExtensions.AddEllipseTileRegion(experiment, centerX, centerY, width, height, z)
# add a rectangular tile region to the experiment
ZenExperimentExtensions.AddPolygonTileRegion(experiment, polygonPoints, z)
# add an elipsoid tile region to the experiment
ZenExperimentExtensions.AddRectangleTileRegion(experiment, centerX, centerY, width, height, z)
# add a polygon tile region to the experiment using a point list
ZenExperimentExtensions.AddSinglePosition(experiment, x, y, z)
# add a single XYZ position
ZenExperimentExtensions.ClearTileRegionsAndPositions(experiment)
# modify the z-position of the
ZenExperimentExtensions.GetTileRegionInfos(experiment)
# get a lits with all the ZEN experiments
ZenExperimentExtensions.GetZenExperimentFileNames(documentsFolder)
# check if an experiments contains tiles
ZenExperimentExtensions.IsTilesExperiment(experiment)
# modify the size of the tile regions
ZenExperimentExtensions.ModifyTileRegionsSize(experiment, newWidth, newHeight)
# modify the z-positions for the tile regions
ZenExperimentExtensions.ModifyTileRegionsZ(experiment, newZ)
namespace MyFirstExtension
{
using Zeiss.Micro;
using Zeiss.Micro.Reflection;
using Zeiss.Micro.Scripting;
using Zeiss.Micro.Application.Configuration;
using Zeiss.Micro.Diagnostics;
[ApplicationExtension("6CB9D0FC-0EFA-4B74-A8D4-17411DB835CF", "MyFirstExtension",
ExtensionFlags.Free | ExtensionFlags.SetupUI, "First Extension for Demo")]
internal class MyFirstExtension : ApplicationExtension
{
readonly ZenWrapperLM zen = ZenWrapperLM.Instance;
const string ExtensionName = "MyFirstExtension";
const string MyControlName = "First Extension";
MyControlViewModel myControlViewModel;
// The functions to Initialize/Uninitialize the Extension are responsible to add and remove ZEN-specific WPF windows.
// Therefore we have to add as many controls and their Action Classes to the project as we will need.
protected override void InitializeCore(object application,
ExtensionInitializeMode extensionInitializeMode,
object parameters)
{
this.myControlViewModel = new MyControlViewModel();
// add extension to ZEN when activated inside the extension manager
UIToolItem toolAction = zen.Windows.AddToolWindow
(ExtensionName, MyControlName, "MyFirstExtension; MyFirstExtension.MyControl", this.myControlViewModel);
// this parameter manages whether the control will be expanded when the extension is started
toolAction.IsExpanded = true;
}
protected override void UninitializeCore(ExtensionUninitializeMode extensionUninitializeMode)
{
// add extension to ZEN when activated inside the extension manager
zen.Windows.RemoveToolWindow(ExtensionName, MyControlName);
}
}
}
### -------------------- PreScript ---------------------------------------------- ###
from System import Array
posx = []
posy = []
posz = []
intensities = []
# adapt experiment experiment parameters
numZ = 15
# create header fo logfile
logfile = ZenService.Xtra.System.AppendLogLine('S\tT\tZ\tID\tMaxInt\tX\tY')
# extract the XYZ values for the brightest object from the lists
def getIDfromIntensities(intensities, posx, posy, posz):
max_value = max(intensities)
max_index = intensities.index(max_value)
posx_bright = posx[max_index]
posy_bright = posy[max_index]
posz_bright = posz[max_index]
return max_index, posx_bright, posy_bright, posz_bright
### -------------------- LoopScript --------------------------------------------- ###
# get the current time point
currT = ZenService.Experiment.CurrentTimePointIndex
# the scene index is still 1-based!
currSceneIndex = ZenService.Experiment.CurrentSceneIndex
# get total number of objects and frame number
numobj = ZenService.Analysis.All.RegionsCount
zindex = ZenService.Experiment.CurrentZSliceIndex
# add current z-position to list
posz.append(ZenService.HardwareActions.ReadFocusPosition())
# get current object positions and intensity arrays for all detected objects
positionsX = ZenService.Analysis.Single.BoundCenterXStage
positionsY = ZenService.Analysis.Single.BoundCenterYStage
curr_intensities = ZenService.Analysis.Single.IntensityMean_mCher
try:
maxint = max(curr_intensities) # get the maximum intensity value and append the list
intensities.append(maxint)
# get ID of the brightest detected particle, append position list with the XY positions
ID = Array.IndexOf(curr_intensities, max(curr_intensities))
posx.append(positionsX[ID])
posy.append(positionsY[ID])
except:
maxint = 0.0
intensities.append(maxint) # in case no object was detected set values
ID = -1
posx.append(-1)
posy.append(-1)
### -------------------CONTINUE - LoopScript ------------------------------------ ###
# when the last zplane of the stack was reached do something
if zindex == numZ:
index_brightest_plane, posx_bright, posy_bright, posz_bright = getIDfromIntensities(intensities, posx, posy, posz)
logfile = ZenService.Xtra.System.AppendLogLine('Brightest Plane:\tX=' + str(posx_bright) + \
'\tY=' + str(posy_bright)+ '\tZ=' + str(posz_bright))
posx = []
posy = []
posz = []
intensities = []
# do the update for the current position
ZenService.Actions.MoveTileRegion(currSceneIndex-1, posx_bright, posy_bright)
# log action to file
logfile = ZenService.Xtra.System.AppendLogLine('Move Scene: ' + str(currSceneIndex) + \
'\tX=' + str(posx_bright) + '\tY=' + str(posy_bright))
### -------------------- PostScript --------------------------------------------- ###
# show logfile at the end
ZenService.Xtra.System.ExecuteExternalProgram(r'C:\Program Files (x86)\Notepad++\notepad++.exe', logfile)
Tools for Adaptive Feedback Microscopy
By Sebastian Rhode
Tools for Adaptive Feedback Microscopy
- 1,910