Source code for mxcubecore.HardwareObjects.MD3UP

import logging
import math
import time

import numpy

from mxcubecore import HardwareRepository as HWR
from mxcubecore.HardwareObjects import Microdiff
from mxcubecore.HardwareObjects.sample_centring import CentringMotor


[docs]class MD3UP(Microdiff.Microdiff): def __init__(self, *args, **kwargs): Microdiff.Microdiff.__init__(self, *args, **kwargs)
[docs] def init(self): Microdiff.Microdiff.init(self) phiy_ref = self["centringReferencePosition"].get_property("phiy") self.centringPhi = CentringMotor(self.phiMotor, direction=1) self.centringPhiz = CentringMotor(self.phizMotor) self.centringPhiy = CentringMotor( self.phiyMotor, direction=-1, reference_position=phiy_ref ) self.centringSamplex = CentringMotor(self.sampleXMotor, direction=-1) self.centringSampley = CentringMotor(self.sampleYMotor) self.scan_nb_frames = 1 # Raster scan attributes self.nb_frames = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "nbframes", }, "ScanNumberOfFrames", ) self.scan_range = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "scan_range", }, "ScanRange", ) self.scan_exposure_time = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "exposure_time", }, "ScanExposureTime", ) self.scan_start_angle = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "start_angle", }, "ScanStartAngle", ) self.scan_detector_gate_pulse_enabled = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "detector_gate_pulse_enabled", }, "DetectorGatePulseEnabled", ) self.scan_detector_gate_pulse_readout_time = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "detector_gate_pulse_readout_time", }, "DetectorGatePulseReadoutTime", )
def set_rotation_axis_position(self, value: float, motor_name="phiy"): self._set_rotation_axis_position(value, motor_name="phiy") # def getBeamPosX(self): # return self.beam_info.get_beam_position_on_screen()[0] # # def getBeamPosY(self): # return self.beam_info.get_beam_position_on_screen()[1] def setNbImages(self, number_of_images): self.scan_nb_frames = number_of_images def oscilScan(self, start, end, exptime, number_of_images, wait=False): if self.in_plate_mode(): scan_speed = math.fabs(end - start) / exptime low_lim, hi_lim = map(float, self.scanLimits(scan_speed)) if start < low_lim: raise ValueError("Scan start below the allowed value %f" % low_lim) elif end > hi_lim: raise ValueError("Scan end abobe the allowed value %f" % hi_lim) dead_time = HWR.beamline.detector.get_deadtime() self.scan_detector_gate_pulse_enabled.set_value(True) self.scan_detector_gate_pulse_readout_time.set_value(dead_time * 1000) if self.get_property("md_set_number_of_frames", False): self.nb_frames.set_value(number_of_images) else: self.nb_frames.set_value(1) scan_params = "1\t%0.3f\t%0.3f\t%0.4f\t1" % (start, (end - start), exptime) scan = self.add_command( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "start_scan", }, "startScanEx", ) scan(scan_params) print("oscil scan started at ----------->", time.time()) if wait: self._wait_ready(20 * 60) # Timeout of 20 min print("finished at ---------->", time.time()) def oscilScan4d( self, start, end, exptime, number_of_images, motors_pos, wait=False ): if self.in_plate_mode(): scan_speed = math.fabs(end - start) / exptime low_lim, hi_lim = map(float, self.scanLimits(scan_speed)) if start < low_lim: raise ValueError("Scan start below the allowed value %f" % low_lim) elif end > hi_lim: raise ValueError("Scan end abobe the allowed value %f" % hi_lim) if self.get_property("md_set_number_of_frames", False): self.nb_frames.set_value(number_of_images) else: self.nb_frames.set_value(1) params = "%0.3f\t%0.3f\t%f\t" % (start, (end - start), exptime) params += "%0.3f\t" % motors_pos["1"]["phiz"] params += "%0.3f\t" % motors_pos["1"]["phiy"] params += "%0.3f\t" % motors_pos["1"]["sampx"] params += "%0.3f\t" % motors_pos["1"]["sampy"] params += "%0.3f\t" % motors_pos["2"]["phiz"] params += "%0.3f\t" % motors_pos["2"]["phiy"] params += "%0.3f\t" % motors_pos["2"]["sampx"] params += "%0.3f" % motors_pos["2"]["sampy"] scan = self.add_command( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "start_scan4d", }, "startScan4DEx", ) scan(params) if wait: # Timeout of 15 min self._wait_ready(900) def oscilScanMesh( self, start, end, exptime, dead_time, mesh_num_lines, mesh_total_nb_frames, mesh_center, mesh_range, wait=False, ): self.scan_detector_gate_pulse_enabled.set_value(True) dead_time = HWR.beamline.detector.get_deadtime() self.scan_detector_gate_pulse_readout_time.set_value(dead_time * 1000) self.move_motors(mesh_center.as_dict()) positions = self.get_positions() params = "%0.3f\t" % (end - start) params += "%0.3f\t" % mesh_range["vertical_range"] params += "%0.3f\t" % (-mesh_range["horizontal_range"]) params += "%0.3f\t" % start params += "%0.3f\t" % positions["phiz"] params += "%0.3f\t" % positions["phiy"] params += "%0.3f\t" % positions["sampx"] params += "%0.3f\t" % positions["sampy"] params += "%d\t" % mesh_num_lines params += "%d\t" % (mesh_total_nb_frames / mesh_num_lines) params += "%0.3f\t" % (exptime / mesh_num_lines) params += "%r\t" % True params += "%r\t" % True params += "%r\t" % True scan = self.add_command( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "start_raster_scan", }, "startRasterScanEx", ) scan(params) if wait: # Timeout of 30 min self._wait_ready(1800)
[docs] def timeresolved_mesh_scan(self, timeout=900): """Start timeresolved mesh. Args: timeout(float): Timeout to wait the execution of the scan [s]. Default value is 15 min """ scan = self.add_command( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "start_timeresolved_mesh", }, "startContinuousTimeResolvedRasterScan", ) scan() # wait for the execution of the scan self._wait_ready(timeout)
[docs] def get_timeresolved_mesh_nbframes(self): """Get the calculated number of frames for the continuous timeresolved mesh scan. Returns: (int): Number of frames. """ cmd = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "timeresolved_mesh_nbframes", }, "ContinuousTimeResolvedRasterScanNbFrames", ) return cmd.get_value()
[docs] def get_timeresolved_mesh_exptime(self): """Get the calculated exposure time for the continuous timeresolved mesh scan. Returns: (float): Exposure time [s]. """ cmd = self.add_channel( { "type": "exporter", "exporter_address": self.exporter_addr, "name": "timeresolved_mesh_exptime", }, "ContinuousTimeResolvedRasterScanExposureTime", ) return cmd.get_value()
def get_centred_point_from_coord(self, x, y, return_by_names=None): self.pixelsPerMmY, self.pixelsPerMmZ = self.getCalibrationData( self.zoomMotor.get_value() ) if None in (self.pixelsPerMmY, self.pixelsPerMmZ): return 0, 0 beam_pos_x, beam_pos_y = HWR.beamline.beam.get_beam_position_on_screen() dx = (x - beam_pos_x) / self.pixelsPerMmY dy = (y - beam_pos_y) / self.pixelsPerMmZ phi_angle = math.radians( self.centringPhi.direction * self.centringPhi.get_value() ) sampx = -self.centringSamplex.direction * self.centringSamplex.get_value() sampy = self.centringSampley.direction * self.centringSampley.get_value() phiy = -self.centringPhiy.direction * self.centringPhiy.get_value() phiz = self.centringPhiz.direction * self.centringPhiz.get_value() rotMatrix = numpy.matrix( [ [math.cos(phi_angle), -math.sin(phi_angle)], [math.sin(phi_angle), math.cos(phi_angle)], ] ) invRotMatrix = numpy.array(rotMatrix.I) dsampx, dsampy = numpy.dot(numpy.array([dx, dy]), invRotMatrix) chi_angle = math.radians(-self.chiAngle) chiRot = numpy.matrix( [ [math.cos(chi_angle), -math.sin(chi_angle)], [math.sin(chi_angle), math.cos(chi_angle)], ] ) sx, sy = numpy.dot(numpy.array([dsampx, dsampy]), numpy.array(chiRot)) sampx = sampx + sx sampy = sampy + sy phiz = phiz + dy return { "phi": self.centringPhi.get_value(), "phiz": float(phiz), "phiy": float(phiy), "sampx": float(sampx), "sampy": float(sampy), } def motor_positions_to_screen(self, centred_positions_dict): self.pixelsPerMmY, self.pixelsPerMmZ = self.getCalibrationData( self.zoomMotor.get_value() ) if None in (self.pixelsPerMmY, self.pixelsPerMmZ): return 0, 0 phi_angle = math.radians( self.centringPhi.direction * self.centringPhi.get_value() ) sampx = self.centringSamplex.direction * ( centred_positions_dict["sampx"] - self.centringSamplex.get_value() ) sampy = self.centringSampley.direction * ( centred_positions_dict["sampy"] - self.centringSampley.get_value() ) phiy = self.centringPhiy.direction * ( centred_positions_dict["phiy"] - self.centringPhiy.get_value() ) phiz = self.centringPhiz.direction * ( centred_positions_dict["phiz"] - self.centringPhiz.get_value() ) rotMatrix = numpy.matrix( [ math.cos(phi_angle), -math.sin(phi_angle), math.sin(phi_angle), math.cos(phi_angle), ] ) rotMatrix.shape = (2, 2) invRotMatrix = numpy.array(rotMatrix.I) dsx, dsy = numpy.dot(numpy.array([sampx, sampy]), invRotMatrix) chi_angle = math.radians(self.chiAngle) chiRot = numpy.matrix( [ math.cos(chi_angle), -math.sin(chi_angle), math.sin(chi_angle), math.cos(chi_angle), ] ) chiRot.shape = (2, 2) sx, sy = numpy.dot(numpy.array([0, dsy]), numpy.array(chiRot)) beam_pos_x, beam_pos_y = HWR.beamline.beam.get_beam_position_on_screen() x = (sx + phiy) * self.pixelsPerMmY + beam_pos_x y = (sy + phiz) * self.pixelsPerMmZ + beam_pos_y return float(x), float(y) def move_to_beam(self, x, y): self.pixelsPerMmY, self.pixelsPerMmZ = self.getCalibrationData( self.zoomMotor.get_value() ) if None in (self.pixelsPerMmY, self.pixelsPerMmZ): return 0, 0 beam_pos_x, beam_pos_y = HWR.beamline.beam.get_beam_position_on_screen() dx = (x - beam_pos_x) / self.pixelsPerMmY dy = (y - beam_pos_y) / self.pixelsPerMmZ phi_angle = math.radians( self.centringPhi.direction * self.centringPhi.get_value() ) sampx = -self.centringSamplex.direction * self.centringSamplex.get_value() sampy = self.centringSampley.direction * self.centringSampley.get_value() phiz = self.centringPhiz.direction * self.centringPhiz.get_value() rotMatrix = numpy.matrix( [ [math.cos(phi_angle), -math.sin(phi_angle)], [math.sin(phi_angle), math.cos(phi_angle)], ] ) invRotMatrix = numpy.array(rotMatrix.I) dsampx, dsampy = numpy.dot(numpy.array([dx, 0]), invRotMatrix) chi_angle = math.radians(-self.chiAngle) chiRot = numpy.matrix( [ [math.cos(chi_angle), -math.sin(chi_angle)], [math.sin(chi_angle), math.cos(chi_angle)], ] ) sx, sy = numpy.dot(numpy.array([dsampx, dsampy]), numpy.array(chiRot)) sampx = sampx + sx sampy = sampy + sy phiz = phiz + dy try: self.centringSamplex.set_value(sampx) self.centringSampley.set_value(sampy) self.centringPhiz.set_value(phiz) except Exception: msg = "MiniDiff: could not center to beam, aborting" logging.getLogger("HWR").exception(msg)