Commit e7f6217f authored by Jibril Mammeri's avatar Jibril Mammeri Committed by bliss administrator
Browse files

Setup first draft

parent 088a5c04
This diff is collapsed.
This diff is collapsed.
......@@ -8,12 +8,13 @@ import PyTango
import bliss
from bliss import global_map
from bliss.common import session
from bliss.common.logtools import log_info,log_debug
from bliss.common.logtools import log_info, log_debug
from bliss.shell.cli.user_dialog import UserChoice, Container, UserYesNo, UserFloatInput
from bliss.shell.cli.pt_widgets import display, BlissDialog
from tomo.TomoParameters import TomoParameters
class TomoOptic(TomoParameters):
"""
Base class for all tomo optic objects.
......@@ -50,43 +51,43 @@ class TomoOptic(TomoParameters):
tomo : Tomo object (ex: HrTomo)
contains all info about tomo (hardware, parameters)
"""
def __init__(self, name, config, param_name=None, param_defaults=None):
# init logging
self.log_name = name+".optic"
self.log_name = name + ".optic"
global_map.register(self, tag=self.log_name)
log_info(self,"__init__() entering")
log_info(self, "__init__() entering")
self.__name = name
self.__config = config
# Initialise the TomoParameters class
super().__init__(param_name, param_defaults)
try:
self.__scintillators = config["scintillator"]
self.__scintillators = config["scintillator"]
except:
self.__scintillators = None
try:
self.__image_flipping_hor = config["image_flipping_hor"]
self.__image_flipping_hor = config["image_flipping_hor"]
except:
self.__image_flipping_hor = False
self.__image_flipping_hor = False
try:
self.__image_flipping_vert = config["image_flipping_vert"]
except:
self.__image_flipping_vert = False
try:
self.__rotc_mot = config["rotc_motor"]
except:
self.__rotc_mot = None
try:
self.__focus_mot = config["focus_motor"]
except:
self.__focus_mot = None
try:
self.__focus_type = config["focus_type"]
except:
......@@ -100,36 +101,46 @@ class TomoOptic(TomoParameters):
except:
self.__focus_scan_steps = 0
try:
self.__focus_lim_pos = config["focus_lim_pos"]
self.__focus_lim_pos = config["focus_lim_pos"]
except:
self.__focus_lim_pos = 0
self.__focus_lim_pos = 0
try:
self.__focus_lim_neg = config["focus_lim_neg"]
self.__focus_lim_neg = config["focus_lim_neg"]
except:
self.__focus_lim_neg = 0
self.__manual_pixel_size = False
self.__unbinned_pixel_size = 0
self.__image_pixel_size = 0
self.__scintillator = None
log_info(self,"__init__() leaving")
self.__focus_lim_neg = 0
try:
self.__manual_pixel_size = config["manual_pixel_size"]
except:
self.__manual_pixel_size = False
try:
self.__unbinned_pixel_size = config["unbinned_pixel_size"]
except:
self.__unbinned_pixel_size = 0
try:
self.__image_pixel_size = config["image_pixel_size"]
except:
self.__image_pixel_size = 0
try:
self.__scintillator = config["scintillator"]
except:
self.__scintillator = None
log_info(self, "__init__() leaving")
def manual_pixel_size_setup(self):
"""
User dialog which allows to enter manually pixel size in micrometers
"""
dlg1 = UserYesNo(label='Do you want to set pixel size manually?')
ret = display( dlg1, title="Manual Pixel Size" )
dlg1 = UserYesNo(label="Do you want to set pixel size manually?")
ret = display(dlg1, title="Manual Pixel Size")
if ret != False:
self.manual_pixel_size = True
dlg1 = UserFloatInput(label='Unbinned pixel size in um', defval=self.unbinned_pixel_size)
ct1 = Container( [dlg1], title="Unbinned Pixel Size" )
ret = BlissDialog( [ [ct1], ], title='Pixel Size Setup').show()
dlg1 = UserFloatInput(
label="Unbinned pixel size in um", defval=self.unbinned_pixel_size
)
ct1 = Container([dlg1], title="Unbinned Pixel Size")
ret = BlissDialog([[ct1]], title="Pixel Size Setup").show()
if ret != False:
self.unbinned_pixel_size = ret[dlg1]
return True
......@@ -139,29 +150,53 @@ class TomoOptic(TomoParameters):
else:
self.manual_pixel_size = False
return False
def correct_pixel_size_setup(self, tomo_ccd):
def correct_pixel_size_setup(self, detector):
"""
User dialog which allows to modify pixel size (entered manually by user or deduced from optic magnification)
"""
tomo_ccd.calculate_image_pixel_size(self)
dlg1 = UserYesNo(label=f'Do you want to correct this value? ({self.image_pixel_size} um)')
ret = display( dlg1, title="Correct Pixel Size" )
if ret != False:
dlg1 = UserFloatInput(label='Corrected unbinned pixel size in um', defval=self.unbinned_pixel_size)
ct1 = Container( [dlg1], title="Corrected Pixel Size" )
ret = BlissDialog( [ [ct1], ], title='Pixel Size Setup').show()
if ret != False:
"""
self.calculate_image_pixel_size(detector)
dlg1 = UserYesNo(
label=f"Do you want to correct this value? ({self.image_pixel_size} um)"
)
ret = display(dlg1, title="Correct Pixel Size")
if ret is False:
dlg1 = UserFloatInput(
label="Corrected unbinned pixel size in um",
defval=self.unbinned_pixel_size,
)
ct1 = Container([dlg1], title="Corrected Pixel Size")
ret = BlissDialog([[ct1]], title="Pixel Size Setup").show()
if ret is False:
self.unbinned_pixel_size = ret[dlg1]
else:
self.unbinned_pixel_size = self.image_pixel_size / tomo_ccd.det_proxy.image_bin[1]
self.image_pixel_size = self.unbinned_pixel_size * tomo_ccd.det_proxy.image_bin[1]
self.unbinned_pixel_size = (
self.image_pixel_size / detector.proxy.image_bin[1]
)
self.image_pixel_size = self.unbinned_pixel_size * detector.proxy.image_bin[1]
def calculate_image_pixel_size(self, detector):
"""
Calculate the sample image pixel size.
Needs detector parameters and the optics magnification
"""
ccd_ps = detector.proxy.camera_pixelsize[0]
if detector.camera_type.lower() == "frelon":
# conversion in microns
ccd_ps *= 1e6
if self.manual_pixel_size:
self.magnification = round(ccd_ps / self.unbinned_pixel_size, 3)
else:
self.unbinned_pixel_size = round(ccd_ps / self.magnification, 3)
ccd_bin = detector.proxy.image_bin[1]
self.image_pixel_size = self.unbinned_pixel_size * ccd_bin
def select_scintillator_setup(self):
"""
User dialog which allows to select a scintillator among list of scintillators defined in optic config file
......@@ -169,39 +204,41 @@ class TomoOptic(TomoParameters):
if self.__scintillators is not None:
value_list = []
for i in self.__scintillators:
value_list.append( (i, str(i)) )
value_list.append((i, str(i)))
# get the actual scintillator name as default
default1 = 0
for i in range (0, len(value_list)):
if self.scintillator is not None and self.scintillator == value_list[i][0]:
for i in range(0, len(value_list)):
if (
self.scintillator is not None
and self.scintillator == value_list[i][0]
):
default1 = i
dlg1 = UserChoice(values=value_list, defval=default1)
ct1 = Container( [dlg1], title="Scintillator" )
ret = BlissDialog( [ [ct1], ], title='Scintillator Setup').show()
ct1 = Container([dlg1], title="Scintillator")
ret = BlissDialog([[ct1]], title="Scintillator Setup").show()
if ret != False:
# get the scintillator chosen
# get the scintillator chosen
self.scintillator = ret[dlg1]
else:
self.scintillator = 'None'
self.scintillator = "None"
@property
def name(self):
"""
The name of the optic
"""
return self.__name
@property
def config(self):
"""
The configuration of the optic
"""
return self.__config
@property
def description(self):
"""
......@@ -209,7 +246,7 @@ class TomoOptic(TomoParameters):
Musst be implemented for every optic.
"""
pass
@property
def type(self):
"""
......@@ -217,95 +254,101 @@ class TomoOptic(TomoParameters):
Musst be implemented for every optic.
"""
pass
@property
def scintillator(self):
"""
Returns the name of the scintillator associated with the optic
"""
return self.__scintillator
@scintillator.setter
def scintillator(self,value):
def scintillator(self, value):
"""
Sets the name of the scintillator associated with the optic
"""
self.__scintillator = value
@property
def manual_pixel_size(self):
"""
Returns if pixel size is manually set or not
"""
return self.__manual_pixel_size
@manual_pixel_size.setter
def manual_pixel_size(self,value):
def manual_pixel_size(self, value):
"""
Sets if pixel size is manually set or not
"""
self.__manual_pixel_size = value
@property
def unbinned_pixel_size(self):
"""
Returns pixel size value without binnning
"""
return self.__unbinned_pixel_size
@unbinned_pixel_size.setter
def unbinned_pixel_size(self,value):
def unbinned_pixel_size(self, value):
"""
Sets pixel size without binnning to value
"""
self.__unbinned_pixel_size = value
@property
def image_pixel_size(self):
"""
Returns pixel size value without binnning
"""
return self.__image_pixel_size
@image_pixel_size.setter
def image_pixel_size(self,value):
def image_pixel_size(self, value):
"""
Sets pixel size without binnning to value
"""
self.__image_pixel_size = value
@property
@property
def magnification(self):
"""
Returns the magnification of the current optic used.
Musst be implemented for every optic.
"""
pass
@magnification.setter
def magnification(self,value):
@magnification.setter
def magnification(self, value):
"""
Sets the magnification of the current optic used
Musst be implemented for every optic.
"""
pass
@property
@property
def image_flipping(self):
"""
Returns the implied horizontal and vertical image flipping as a list
"""
return [self.__image_flipping_hor, self.__image_flipping_vert]
def setup(self):
def optic_setup(self):
pass
def setup(self, detector):
"""
Set-up the optic
Musst be implemented for every optic
"""
pass
self.optic_setup()
self.manual_pixel_size_setup()
self.select_scintillator_setup()
self.correct_pixel_size_setup(detector)
def status(self):
"""
Prints the current ojective in use and its magnification.
......@@ -313,7 +356,7 @@ class TomoOptic(TomoParameters):
Musst be implemented for every optic
"""
pass
@property
def objective(self):
"""
......@@ -321,7 +364,7 @@ class TomoOptic(TomoParameters):
Must be implemented for optics with more than one objective.
"""
return 1
@objective.setter
def objective(self, value):
"""
......@@ -329,46 +372,44 @@ class TomoOptic(TomoParameters):
Must be implemented for optics with more than one objective.
"""
pass
def rotc_motor (self):
def rotc_motor(self):
"""
Returns the Bliss Axis object of the rotation motor to be used for the current objective
"""
return self.__rotc_mot
def set_focus_motor(self, motor):
"""
Sets the current focus motor for optics with several focus motors
"""
self.__focus_mot = motor
def focus_motor (self):
def focus_motor(self):
"""
Returns the Bliss Axis object of the focus motor to be used for the current optic
"""
return self.__focus_mot
def focus_scan_parameters(self):
"""
Returns a dictionary with the paramters for a focus scan
"""
if self.__focus_mot == None:
raise ValueError ("No focus motor defined for the optic!")
raise ValueError("No focus motor defined for the optic!")
scan_params = {}
scan_params['focus_type'] = self.__focus_type
scan_params['focus_scan_range'] = self.__focus_scan_range
scan_params['focus_scan_steps'] = self.__focus_scan_steps
scan_params['focus_lim_pos'] = self.__focus_lim_pos
scan_params['focus_lim_neg'] = self.__focus_lim_neg
scan_params["focus_type"] = self.__focus_type
scan_params["focus_scan_range"] = self.__focus_scan_range
scan_params["focus_scan_steps"] = self.__focus_scan_steps
scan_params["focus_lim_pos"] = self.__focus_lim_pos
scan_params["focus_lim_neg"] = self.__focus_lim_neg
return scan_params
def __info__(self):
info_str = f"{self.name} optic info:\n"
info_str = f"{self.name} optic info:\n"
info_str += f" description = {self.description}\n"
info_str += f" objective = {self.objective} \n"
info_str += f" magnification = {self.magnification} \n"
......@@ -381,5 +422,5 @@ class TomoOptic(TomoParameters):
else:
info_str += f" focus motor = {self.focus_motor().name} \n"
info_str += f" focus scan = {self.focus_scan_parameters()} \n"
return info_str
......@@ -2,14 +2,12 @@ import sys
import gevent
import numpy as np
import time
from bliss.common.standard import *
from bliss.common.standard import info
from bliss.common.logtools import log_info,log_debug
from bliss.common.logtools import log_info, log_debug
from bliss.config.settings import ParametersWardrobe
class TomoParameters:
"""
Base class for all tomo classes to handle persistant parameters.
......@@ -23,20 +21,19 @@ class TomoParameters:
parameters : Bliss parameter wardrobe object
parameter object saved in Redis
"""
def __init__(self, param_name=None, param_defaults=None):
self.param_name = param_name
if self.param_name != None:
self.param_name = param_name
if self.param_name is not None:
self.parameters = ParametersWardrobe(self.param_name)
if param_defaults != None:
if param_defaults is not None:
parameters_dict = self.parameters.to_dict(export_properties=True)
for k,v in param_defaults.items():
for k, v in param_defaults.items():
if k not in parameters_dict:
self.parameters.add(k,v)
self.parameters.add(k, v)
def save_scan_config(self, directory):
"""
Allows to save in a file a parameter set.
......@@ -44,8 +41,7 @@ class TomoParameters:
if self.param_name != None:
file_name = directory + "/" + self.param_name
self.parameters.to_file(file_name)
def load_scan_config(self, directory):
"""
Allows to load from a file a parameter set.
......@@ -53,23 +49,21 @@ class TomoParameters:
if self.param_name != None:
file_name = directory + "/" + self.param_name
self.parameters.from_file(file_name, "default")
def show_config(self):
"""
Prints the parameters of the object.
"""
if self.param_name != None:
print(info(self.parameters))
print(info(self.parameters))
def reset(self):
"""
Deletes all parameters of the object from Redis.
to re-start with the default values.
"""
if self.param_name != None:
#
# remove all parameters one by one.
......@@ -78,5 +72,4 @@ class TomoParameters:
#
parameters_dict = self.parameters.to_dict()
for k in parameters_dict.items():
self.parameters.remove("."+k[0])
self.parameters.remove("." + k[0])
......@@ -12,10 +12,11 @@ from bliss.shell.cli.pt_widgets import BlissDialog
from bliss import global_map
from bliss import setup_globals
from bliss.common.logtools import log_info,log_debug
from bliss.common.logtools import log_info, log_debug
from tomo.TomoOptic import TomoOptic
class UserOptic(TomoOptic):
"""
Class to handle standard optics with one objective.
......@@ -55,7 +56,6 @@ class UserOptic(TomoOptic):
package: id19.tomo.beamline.ID19.UserOptics
"""
def __init__(self, name, config):
"""
Parameters
......@@ -63,95 +63,114 @@ class UserOptic(TomoOptic):
name : str
The Bliss object name
"""
self.__name = name
#
# Define the necessary set of persistant parameters.
# Initialize the parameter set name and the necessary default values
param_name = self.__name+':optic_parameters'
param_name = self.__name + ":optic_parameters"
param_defaults = {}
param_defaults ['name'] = "Manual"
param_defaults ['magnification'] = 1
param_defaults ['image_flipping_hor'] = False
param_defaults ['image_flipping_vert'] = False
param_defaults ['rotc_motor'] = None
param_defaults ['focus_motor'] = None
param_defaults ['focus_type'] = "rotation"
param_defaults ['focus_scan_range'] = 20
param_defaults ['focus_scan_steps'] = 20
param_defaults ['focus_lim_pos'] = 1000
param_defaults ['focus_lim_neg'] = -1000