def data_collection_hook(self, data_collect_parameters): if self._metadataClient is None: self._metadataClient = MXCuBEMetadataClient(self) self._metadataClient.start(data_collect_parameters)
class ESRFMultiCollect(AbstractMultiCollect, HardwareObject): def __init__(self, name): AbstractMultiCollect.__init__(self) HardwareObject.__init__(self, name) self._centring_status = None self._metadataClient = None self.__mesh_steps = None self._mesh_range = None @property def _mesh_steps(self): return self.__mesh_steps @_mesh_steps.setter def _mesh_steps(self, steps): self.__mesh_steps = steps self._detector._mesh_steps = steps def execute_command(self, command_name, *args, **kwargs): wait = kwargs.get("wait", True) cmd_obj = self.get_command_object(command_name) return cmd_obj(*args, wait=wait) def init(self): self._detector = HWR.beamline.detector self.setControlObjects( diffractometer=self.get_object_by_role("diffractometer"), sample_changer=self.get_object_by_role("sample_changer"), lims=self.get_object_by_role("dbserver"), safety_shutter=self.get_object_by_role("safety_shutter"), machine_current=self.get_object_by_role("machine_current"), cryo_stream=self.get_object_by_role("cryo_stream"), energy=self.get_object_by_role("energy"), resolution=self.get_object_by_role("resolution"), detector_distance=self.get_object_by_role("detector_distance"), transmission=self.get_object_by_role("transmission"), undulators=self.get_object_by_role("undulators"), flux=self.get_object_by_role("flux"), detector=self.get_object_by_role("detector"), beam_info=self.get_object_by_role("beam_info"), ) try: undulators = self["undulator"] except KeyError: undulators = [] beam_div_hor, beam_div_ver = HWR.beamline.beam.get_beam_divergence() self.setBeamlineConfiguration( synchrotron_name="ESRF", directory_prefix=self.get_property("directory_prefix"), default_exposure_time=HWR.beamline.detector.get_property( "default_exposure_time"), minimum_exposure_time=HWR.beamline.detector.get_property( "minimum_exposure_time"), detector_fileext=HWR.beamline.detector.get_property("file_suffix"), detector_type=HWR.beamline.detector.get_property("type"), detector_manufacturer=HWR.beamline.detector.get_property( "manufacturer"), detector_model=HWR.beamline.detector.get_property("model"), detector_binning_mode=HWR.beamline.detector.get_property( "binning_mode"), detector_px=HWR.beamline.detector.get_property("px"), detector_py=HWR.beamline.detector.get_property("py"), undulators=undulators, focusing_optic=self.get_property("focusing_optic"), monochromator_type=self.get_property("monochromator"), beam_divergence_vertical=beam_div_ver, beam_divergence_horizontal=beam_div_hor, polarisation=self.get_property("polarisation"), maximum_phi_speed=self.get_property("maximum_phi_speed"), minimum_phi_oscillation=self.get_property( "minimum_phi_oscillation"), input_files_server=self.get_property("input_files_server"), ) # self._detector.init(HWR.beamline.detector, self) self.emit("collectConnected", (True, )) self.emit("collectReady", (True, )) @task def take_crystal_snapshots(self, number_of_snapshots): HWR.beamline.diffractometer.take_snapshots(number_of_snapshots, wait=True) @task def data_collection_hook(self, data_collect_parameters): if self._metadataClient is None: self._metadataClient = MXCuBEMetadataClient(self) self._metadataClient.start(data_collect_parameters) @task def data_collection_end_hook(self, data_collect_parameters): self._metadataClient.end(data_collect_parameters) def prepare_oscillation( self, start, osc_range, exptime, number_of_images, shutterless, npass, first_frame, ): if shutterless: end = start + osc_range * number_of_images exptime = (exptime + self._detector.get_deadtime()) * number_of_images if first_frame: self.do_prepare_oscillation(start, end, exptime, npass) else: if osc_range < 1e-4: # still image end = start else: end = start + osc_range self.do_prepare_oscillation(start, end, exptime, npass) return start, end @task def no_oscillation(self, exptime): self.open_fast_shutter() time.sleep(exptime) self.close_fast_shutter() @task def do_oscillation(self, start, end, exptime, number_of_images, shutterless, npass, first_frame): still = math.fabs(end - start) < 1e-4 if shutterless: if first_frame: exptime = (exptime + self._detector.get_deadtime()) * number_of_images # only do this once per collect # make oscillation an asynchronous task => do not wait here if still: self.oscillation_task = self.no_oscillation(exptime, wait=False) else: self.oscillation_task = self.oscil(start, end, exptime, 1, wait=False) if self.oscillation_task.ready(): self.oscillation_task.get() else: if still: self.no_oscillation(exptime) else: self.oscil(start, end, exptime, npass) @task def oscil(self, start, end, exptime, npass, wait=False): if math.fabs(end - start) < 1e-4: self.open_fast_shutter() time.sleep(exptime) self.close_fast_shutter() else: return self.execute_command("do_oscillation", start, end, exptime, npass) def set_wavelength(self, wavelength): if HWR.beamline.tunable_wavelength: return HWR.beamline.energy.set_wavelength(wavelength) else: return def set_energy(self, energy): if HWR.beamline.tunable_wavelength: return HWR.beamline.energy.set_value(energy) else: return @task def data_collection_cleanup(self): try: self.stop_oscillation() HWR.beamline.diffractometer.set_phase("Centring", wait=True, timeout=200) finally: self.close_fast_shutter() @task def close_fast_shutter(self): self.execute_command("close_fast_shutter") @task def open_fast_shutter(self): self.execute_command("open_fast_shutter") @task def move_motors(self, motor_position_dict): # We do not wnta to modify the input dict motor_positions_copy = motor_position_dict.copy() for motor in motor_positions_copy.keys(): # iteritems(): position = motor_positions_copy[motor] if isinstance(motor, string_types): # find right motor object from motor role in diffractometer obj. motor_role = motor motor = HWR.beamline.diffractometer.get_deviceby_role( motor_role) del motor_positions_copy[motor_role] if motor is None: continue motor_positions_copy[motor] = position logging.getLogger("HWR").info("Moving motor '%s' to %f", motor.get_motor_mnemonic(), position) motor.set_value(position) while any([motor.motorIsMoving() for motor in motor_positions_copy]): logging.getLogger("HWR").info("Waiting for end of motors motion") time.sleep(0.02) def open_safety_shutter(self): try: HWR.beamline.safety_shutter.set_value( HWR.beamline.safety_shutter.VALUES.OPEN, timeout=10) except Exception: logging.getLogger("HWR").exception("") def safety_shutter_opened(self): state = False try: state = HWR.beamline.safety_shutter.get_state().name == "OPENED" except Exception: logging.getLogger("HWR").exception("") state = True return state @task def close_safety_shutter(self): try: HWR.beamline.safety_shutter.set_value( HWR.beamline.safety_shutter.VALUES["CLOSED"]) except Exception: logging.getLogger("HWR").exception("") @task def prepare_intensity_monitors(self): try: self.execute_command("adjust_gains") except AttributeError: pass @task def prepare_acquisition( self, take_dark, start, osc_range, exptime, npass, number_of_images, comment="", trigger_mode=None, ): energy = HWR.beamline.energy.get_value() self._detector.prepare_acquisition( take_dark, start, osc_range, exptime, npass, number_of_images, comment, energy, trigger_mode, ) @task def set_detector_filenames(self, frame_number, start, filename, shutterless): if frame_number == 1 or not shutterless: return self._detector.set_detector_filenames( frame_number, start, filename) def stop_oscillation(self): HWR.beamline.diffractometer.abort_cmd() @task def start_acquisition(self, exptime, npass, first_frame, shutterless): if first_frame: return self._detector.start_acquisition() @task def write_image(self, last_frame): if last_frame: return self._detector.wait_ready() def last_image_saved(self): return self._detector.last_image_saved() def stop_acquisition(self): return self._detector.stop_acquisition() def reset_detector(self): return self._detector.reset_detector() def prepare_input_files(self, files_directory, prefix, run_number, process_directory): i = 1 while True: xds_input_file_dirname = "xds_%s_run%s_%d" % (prefix, run_number, i) autoprocessing_input_file_dirname = "autoprocessing_%s_run%s_%d" % ( prefix, run_number, i, ) autoprocessing_directory = os.path.join( process_directory, autoprocessing_input_file_dirname) if not os.path.exists(autoprocessing_directory): break i += 1 mosflm_input_file_dirname = "mosflm_%s_run%s_%d" % (prefix, run_number, i) hkl2000_dirname = "hkl2000_%s_run%s_%d" % (prefix, run_number, i) self.raw_data_input_file_dir = os.path.join(files_directory, "process", xds_input_file_dirname) self.mosflm_raw_data_input_file_dir = os.path.join( files_directory, "process", mosflm_input_file_dirname) self.raw_hkl2000_dir = os.path.join(files_directory, "process", hkl2000_dirname) for dir in ( self.raw_data_input_file_dir, self.mosflm_raw_data_input_file_dir, self.raw_hkl2000_dir, autoprocessing_directory, ): self.create_directories(dir) logging.info("Creating processing input file directory: %s", dir) os.chmod(dir, 0o777) try: try: os.symlink(files_directory, os.path.join(process_directory, "links")) except os.error as e: if e.errno != errno.EEXIST: raise except Exception: logging.exception("Could not create processing file directory") return autoprocessing_directory, "", "" @task def write_input_files(self, collection_id): # assumes self.xds_directory and self.mosflm_directory are valid conn = HTTPConnection(self.bl_config.input_files_server) # hkl input files input_file_dir = self.raw_hkl2000_dir file_prefix = "../.." hkl_file_path = os.path.join(input_file_dir, "def.site") conn.request("GET", "/def.site/%d?basedir=%s" % (collection_id, file_prefix)) hkl_file = open(hkl_file_path, "w") r = conn.getresponse() if r.status != 200: logging.error("Could not create hkl input file") else: hkl_file.write(r.read().decode()) hkl_file.close() os.chmod(hkl_file_path, 0o666) for input_file_dir, file_prefix in ( (self.raw_data_input_file_dir, "../.."), (self.xds_directory, "../links"), ): xds_input_file = os.path.join(input_file_dir, "XDS.INP") conn.request( "GET", "/xds.inp/%d?basedir=%s" % (collection_id, file_prefix)) xds_file = open(xds_input_file, "w") res = conn.getresponse() if res.status != 200: logging.error("Could not create xds input file") else: xds_file.write(res.read().decode()) xds_file.close() os.chmod(xds_input_file, 0o666) input_file_dir = self.mosflm_raw_data_input_file_dir file_prefix = "../.." mosflm_input_file = os.path.join(input_file_dir, "mosflm.inp") conn.request( "GET", "/mosflm.inp/%d?basedir=%s" % (collection_id, file_prefix)) mosflm_file = open(mosflm_input_file, "w") mosflm_file.write(conn.getresponse().read().decode()) mosflm_file.close() os.chmod(mosflm_input_file, 0o666) # also write input file for STAC for stac_om_input_file_name, stac_om_dir in ( ("xds.descr", self.xds_directory), ("mosflm.descr", self.mosflm_raw_data_input_file_dir), ("xds.descr", self.raw_data_input_file_dir), ): stac_om_input_file = os.path.join(stac_om_dir, stac_om_input_file_name) conn.request("GET", "/stac.descr/%d" % collection_id) stac_om_file = open(stac_om_input_file, "w") stac_template = conn.getresponse().read().decode() if stac_om_input_file_name.startswith("xds"): om_type = "xds" if stac_om_dir == self.raw_data_input_file_dir: om_filename = os.path.join(stac_om_dir, "CORRECT.LP") else: om_filename = os.path.join(stac_om_dir, "xds_fastproc", "CORRECT.LP") else: om_type = "mosflm" om_filename = os.path.join(stac_om_dir, "bestfile.par") stac_om_file.write( stac_template.format( omfilename=om_filename, omtype=om_type, phi=HWR.beamline.diffractometer.phiMotor.get_value(), sampx=HWR.beamline.diffractometer.sampleXMotor.get_value(), sampy=HWR.beamline.diffractometer.sampleYMotor.get_value(), phiy=HWR.beamline.diffractometer.phiyMotor.get_value(), )) stac_om_file.close() os.chmod(stac_om_input_file, 0o666) def get_wavelength(self): return HWR.beamline.energy.get_wavelength() def get_undulators_gaps(self): all_gaps = {"Unknown": None} _gaps = {} try: _gaps = HWR.beamline.undulators except Exception: logging.getLogger("HWR").exception("Could not get undulator gaps") all_gaps.clear() for key in _gaps: if "_Position" in key: nkey = key[:-9] all_gaps[nkey] = _gaps[key] else: all_gaps = _gaps return all_gaps def get_resolution_at_corner(self): return self.execute_command("get_resolution_at_corner") def get_beam_size(self): return ( self.execute_command("get_beam_size_x"), self.execute_command("get_beam_size_y"), ) def get_slit_gaps(self): return ( self.execute_command("get_slit_gap_h"), self.execute_command("get_slit_gap_v"), ) def get_beam_shape(self): return self.execute_command("get_beam_shape") # def get_measured_intensity(self): # try: # val = self.get_channel_object("image_intensity").getValue() # return float(val) # except Exception: # return 0 def get_machine_current(self): if HWR.beamline.machine_info: try: return HWR.beamline.machine_info.get_current() except Exception: return -1 else: return 0 def get_machine_message(self): if HWR.beamline.machine_info: return HWR.beamline.machine_info.getMessage() else: return "" def get_machine_fill_mode(self): if HWR.beamline.machine_info: return HWR.beamline.machine_info.getFillMode() else: "" def get_cryo_temperature(self): while True: logging.info("Reading cryostream temperature") try: T = HWR.beamline.cryo_stream.getTemperature() except Exception: time.sleep(0.1) continue else: return T def get_current_energy(self): return HWR.beamline.energy.get_value() def get_beam_centre(self): return ( self.execute_command("get_beam_centre_x"), self.execute_command("get_beam_centre_y"), ) def getBeamlineConfiguration(self, *args): # TODO: change this to stop using a dictionary at the other end return self.bl_config._asdict() def is_connected(self): return True def is_ready(self): return True def sampleChangerHO(self): return HWR.beamline.sample_changer def diffractometer(self): return HWR.beamline.diffractometer def dbServerHO(self): return HWR.beamline.lims def sanityCheck(self, collect_params): return def setBrick(self, brick): return def directoryPrefix(self): return self.bl_config.directory_prefix def store_image_in_lims(self, frame, first_frame, last_frame): if first_frame or last_frame: return True @task def generate_image_jpeg(self, filename, jpeg_path, jpeg_thumbnail_path): directories = filename.split(os.path.sep) try: if directories[1] == "data" and directories[2] == "gz": if directories[3] == "visitor": proposal = directories[4] beamline = directories[5] elif directories[4] == "inhouse": proposal = directories[5] beamline = directories[3] else: proposal = "unknown" beamline = "unknown" elif directories[2] == "visitor": beamline = directories[4] proposal = directories[3] else: beamline = directories[2] proposal = directories[4] except Exception: beamline = "unknown" proposal = "unknown" host, port = self.get_property("bes_jpeg_hostport").split(":") conn = HTTPConnection(host, int(port)) params = urlencode({ "image_path": filename, "jpeg_path": jpeg_path, "jpeg_thumbnail_path": jpeg_thumbnail_path, "initiator": beamline, "externalRef": proposal, "reuseCase": "true", }) conn.request( "POST", "/BES/bridge/rest/processes/CreateThumbnails/RUN?%s" % params, headers={"Accept": "text/plain"}, ) conn.getresponse() """ getOscillation Description: Returns the parameters (and results) of an oscillation. Type : method Arguments : oscillation_id (int; the oscillation id, the last parameters of the collectOscillationStarted signal) Returns : tuple; (blsampleid,barcode,location,parameters) """ def getOscillation(self, oscillation_id): return self.oscillations_history[oscillation_id - 1] def sampleAcceptCentring(self, accepted, centring_status): self.sample_centring_done(accepted, centring_status) def setCentringStatus(self, centring_status): self._centring_status = centring_status """ getOscillations Description: Returns the history of oscillations for a session Type : method Arguments : session_id (int; the session id, stored in the "sessionId" key in each element of the parameters list in the collect method) Returns : list; list of all oscillation_id for the specified session """ def getOscillations(self, session_id): # TODO return [] def set_helical(self, helical_on): self.get_channel_object("helical").set_value(1 if helical_on else 0) def set_helical_pos(self, helical_oscil_pos): self.get_channel_object("helical_pos").set_value(helical_oscil_pos) def get_archive_directory(self, directory): pt = PathTemplate() pt.directory = directory return pt.get_archive_directory() def setMeshScanParameters(self, mesh_steps, mesh_range): """ Descript. : """ self._mesh_steps = mesh_steps self._mesh_range = mesh_range