Ejemplo n.º 1
0
    def init(self):
        self.ready_event = gevent.event.Event()

        self.ruche_hwo = self.get_object_by_role("ruche")

        self.fluodet_hwo = self.get_object_by_role("fluodet")
        self.px1env_hwo = self.get_object_by_role("px1environment")

        self.mono_dp = DeviceProxy(self.get_property("mono_dev"))
        self.ble_dp = DeviceProxy(self.get_property("ble_dev"))
        self.fp_dp = DeviceProxy(self.get_property("fp_dev"))

        test_data_file = self.get_property("test_data")

        self.log.debug(" using test data %s" % test_data_file)

        self.test_data_mode = False

        if test_data_file:
            self.simul_data = self.load_data_file(test_data_file)
            if len(self.simul_data):
                self.test_data_mode = True

        # USING TEST. UNCOMMENT NEXT LINE TO USE REAL DATA IN ALL CASES
        # self.test_data_mode = False

        normdiode = self.get_property("normalization_diode")
        self.norm_diode_dev = DeviceProxy(normdiode)

        self.number_of_steps = self.get_property("number_of_steps")
        if self.number_of_steps is None:
            self.number_of_steps = self.default_steps
Ejemplo n.º 2
0
    def init(self):

        self.moving = False

        self.doBacklashCompensation = False

        self.current_energy = None
        self.current_state = None

        try:
            self.monodevice = DeviceProxy(self.getProperty("mono_device"))
        except BaseException:
            self.errorDeviceInstance(self.getProperty("mono_device"))

        # Nom du device bivu (Energy to gap) : necessaire pour amelioration du
        # positionnement de l'onduleur (Backlash)
        self.und_device = DeviceProxy(self.getProperty("undulator_device"))
        self.doBacklashCompensation = self.getProperty("backlash")

        # parameters for polling
        self.isConnected()

        self.energy_chan = self.getChannelObject("energy")
        self.energy_chan.connectSignal("update", self.energyChanged)

        self.stop_cmd = self.getCommandObject("stop")

        self.state_chan = self.getChannelObject("state")
        self.state_chan.connectSignal("update", self.stateChanged)
Ejemplo n.º 3
0
    def init(self):
        """
        Init method
        """

        self.collect_devname = self.get_property("tangoname")
        self.collect_device = DeviceProxy(self.collect_devname)

        self.collect_state_chan = self.get_channel_object("state")

        self.px1env_hwobj = self.get_object_by_role("environment")

        self.frontend_hwobj = self.get_object_by_role("frontend")

        self.lightarm_hwobj = self.get_object_by_role("lightarm")

        self.mxlocal_object = self.get_object_by_role("beamline_configuration")

        self.img2jpeg = self.get_property("imgtojpeg")
        undulators = self.get_undulators()

        self.exp_type_dict = {"Mesh": "raster", "Helical": "Helical"}

        det_px, det_py = HWR.beamline.detector.get_pixel_size()
        beam_div_hor, beam_div_ver = HWR.beamline.beam.get_beam_divergence()

        self.set_beamline_configuration(
            synchrotron_name="SOLEIL",
            directory_prefix=self.get_property("directory_prefix"),
            default_exposure_time=HWR.beamline.detector.
            get_default_exposure_time(),
            minimum_exposure_time=HWR.beamline.detector.
            get_minimum_exposure_time(),
            detector_fileext=HWR.beamline.detector.get_file_suffix(),
            detector_type=HWR.beamline.detector.get_detector_type(),
            detector_manufacturer=HWR.beamline.detector.get_manufacturer(),
            detector_model=HWR.beamline.detector.get_model(),
            detector_px=det_px,
            detector_py=det_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"),
            input_files_server=self.get_property("input_files_server"),
        )

        self.emit("collectConnected", (True, ))
        self.emit("collectReady", (True, ))
Ejemplo n.º 4
0
    def init(self):

        self.moving = False

        self.doBacklashCompensation = False

        self.current_energy = None
        self.current_state = None

        try:
            self.monodevice = DeviceProxy(self.getProperty("mono_device"))
        except BaseException:
            self.errorDeviceInstance(self.getProperty("mono_device"))

        # Nom du device bivu (Energy to gap) : necessaire pour amelioration du
        # positionnement de l'onduleur (Backlash)
        self.und_device = DeviceProxy(self.getProperty("undulator_device"))
        self.doBacklashCompensation = self.getProperty("backlash")

        # parameters for polling
        self.isConnected()

        self.energy_chan = self.getChannelObject("energy")
        self.energy_chan.connectSignal("update", self.energyChanged)

        self.stop_cmd = self.getCommandObject("stop")

        self.state_chan = self.getChannelObject("state")
        self.state_chan.connectSignal("update", self.stateChanged)
Ejemplo n.º 5
0
    def _init(self):
        self.devices = self.getDevices()
        for dev in self.devices:
            try:
                logging.getLogger("HWR").info("Device found: %s" %
                                              dev.tangoname)
            except:
                pass
            #logging.getLogger("HWR").info("Device found: %s" % dev.tangoname)

        try:
            self.guillot = HRDvProxy(self.getProperty("tangoname_guillot"))
            self.microglide = HRDvProxy(
                self.getProperty("tangoname_microglide"))

            try:
                currentAuthorization = self.getChannelObject(
                    'GonioMovementAuthorized').getValue()
                self.authorizationChanged(currentAuthorization)
            except:
                import traceback
                traceback.print_exc()

            try:
                self.authorizationChannel = self.getChannelObject(
                    'GonioMovementAuthorized')
                self.authorizationChannel.connectSignal(
                    'update', self.authorizationChanged)
            except:
                import traceback
                traceback.print_exc()

            #print "---------------- SC ROBOT ------------------"
            #print self.authorizationChannel
            #print "--------------------------------------------"
            self.kappa = self.getDeviceByRole("kappa")
            self.phi = self.getDeviceByRole("phi")
            self.omega = self.getDeviceByRole("omega")
            self.lightarm = self.getDeviceByRole("lightarm")
            self.zoom = self.getDeviceByRole("zoom")
            self.obx = self.getDeviceByRole("obx")
            self.detdist = self.getDeviceByRole("detectordist")
        except:
            #            self.errorDeviceInstance(self.getProperty("tangoname2"))
            logging.getLogger("HWR").error("%s: unknown device name",
                                           self.getProperty("tangoname"))
Ejemplo n.º 6
0
    def init(self):

        self.device = DeviceProxy(self.getProperty("tangoname"))

        try:
            self.state_chan = self.get_channel_object("State")
            self.state_chan.connectSignal("update", self.stateChanged)

        except KeyError:
            logging.getLogger().warning("%s: cannot report State", self.name())

        try:
            self.chanAuth = self.get_channel_object("beamlineMvtAuthorized")
            self.chanAuth.connectSignal("update", self.setAuthorizationFlag)
            # state = self.state_chan.getValue()

        except KeyError:
            logging.getLogger().warning("%s: cannot report State", self.name())

        try:
            self.usingCapillaryChannel = self.get_channel_object(
                "usingCapillary")
            self.setUsingCapillary(True)
        except BaseException:
            self.usingCapillaryChannel = None

        try:
            self.beamstopPositionChannel = self.get_channel_object(
                "beamstopPosition")
        except BaseException:
            self.beamstopPositionChannel = None

        if self.device is not None:
            self.setIsReady(True)

            self.cmds = {
                EnvironmentPhase.TRANSFER:
                self.device.GoToTransfertPhase,
                EnvironmentPhase.CENTRING:
                self.device.GoToCentringPhase,
                EnvironmentPhase.COLLECT:
                self.device.GoToCollectPhase,
                EnvironmentPhase.DEFAULT:
                self.device.GoToDefaultPhase,
                # EnvironmentPhase.BEAMVIEW: self.device.GoToBeamViewPhase,
                EnvironmentPhase.FLUOX:
                self.device.GoToFluoXPhase,
                EnvironmentPhase.MANUALTRANSFER:
                self.device.GoToManualTransfertPhase,
                EnvironmentPhase.VISUSAMPLE:
                self.device.GoToVisuSamplePhase,
            }
Ejemplo n.º 7
0
    def init(self):
        self.ready_event = gevent.event.Event()

        self.session_hwo = self.getObjectByRole("session")
        self.ruche_hwo = self.getObjectByRole("ruche")
        self.db_connection_hwo = self.getObjectByRole("dbserver")

        self.fluodet_hwo = self.getObjectByRole("fluodet")
        self.fastshut_hwo = self.getObjectByRole("fast_shutter")
        self.safety_shutter_hwo = self.getObjectByRole("safety_shutter")
        self.px1env_hwo = self.getObjectByRole("px1environment")
        self.beaminfo_hwo = self.getObjectByRole("beaminfo")

        self.mono_dp = DeviceProxy(self.getProperty("mono_dev"))
        self.ble_dp = DeviceProxy(self.getProperty("ble_dev"))
        self.fp_dp = DeviceProxy(self.getProperty("fp_dev"))

        test_data_file = self.getProperty("test_data")

        self.log.debug(" using test data %s" % test_data_file)

        self.test_data_mode = False

        if test_data_file:
            self.simul_data = self.load_data_file(test_data_file)
            if len(self.simul_data):
                self.test_data_mode = True

        # USING TEST. UNCOMMENT NEXT LINE TO USE REAL DATA IN ALL CASES
        # self.test_data_mode = False

        normdiode = self.getProperty('normalization_diode')
        self.norm_diode_dev = DeviceProxy(normdiode)

        self.number_of_steps = self.getProperty("number_of_steps")
        if self.number_of_steps is None:
            self.number_of_steps = self.default_steps
Ejemplo n.º 8
0
    def init(self):

        super(PX1Cryotong, self).init()

        self.cats_device = DeviceProxy(self.getProperty("cats_device"))

        self.environment = self.getObjectByRole("environment")

        if self.environment is None:
            logging.error(
                "PX1Cats. environment object not available. Sample changer cannot operate. Info.mode only"
            )
            self.infomode = True
        else:
            self.infomode = False

        for channel_name in (
                "_chnSoftAuth",
                "_chnHomeOpened",
                "_chnDryAndSoakNeeded",
                "_chnIncoherentGonioSampleState",
                "_chnSampleIsDetected",
                "_chnCountDown",
        ):
            setattr(self, channel_name, self.get_channel_object(channel_name))

        self._chnSoftAuth.connectSignal("update", self._softwareAuthorization)
        self._chnHomeOpened.connectSignal("update", self._updateHomeOpened)
        self._chnIncoherentGonioSampleState.connectSignal(
            "update", self._updateAckSampleMemory)
        self._chnDryAndSoakNeeded.connectSignal("update",
                                                self._dryAndSoakNeeded)
        self._chnSampleIsDetected.connectSignal("update",
                                                self._updateSampleIsDetected)
        self._chnCountDown.connectSignal("update", self._updateCountDown)

        self._cmdDrySoak = self.add_command(
            {
                "type": "tango",
                "name": "_cmdDrySoak",
                "tangoname": self.tangoname
            },
            "DryAndSoak",
        )
Ejemplo n.º 9
0
class GonioPositions(Equipment):

    stateDict = {
        "UNKNOWN": 0,
        "ALARM": 1,
        "STANDBY": 2,
        "READY": 2,
        "RUNNING": 4,
        "MOVING": 4,
        '0': 0,
        '1': 1,
        '2': 2,
        '4': 4
    }

    def __init__(self, name):
        #logging.getLogger("HWR").info("MSCEquipment.__init__ of device")
        Equipment.__init__(self, name)
        self.current_distance = 450

    def _init(self):
        self.devices = self.getDevices()
        for dev in self.devices:
            try:
                logging.getLogger("HWR").info("Device found: %s" %
                                              dev.tangoname)
            except:
                pass
            #logging.getLogger("HWR").info("Device found: %s" % dev.tangoname)

        try:
            self.guillot = HRDvProxy(self.getProperty("tangoname_guillot"))
            self.microglide = HRDvProxy(
                self.getProperty("tangoname_microglide"))

            try:
                currentAuthorization = self.getChannelObject(
                    'GonioMovementAuthorized').getValue()
                self.authorizationChanged(currentAuthorization)
            except:
                import traceback
                traceback.print_exc()

            try:
                self.authorizationChannel = self.getChannelObject(
                    'GonioMovementAuthorized')
                self.authorizationChannel.connectSignal(
                    'update', self.authorizationChanged)
            except:
                import traceback
                traceback.print_exc()

            #print "---------------- SC ROBOT ------------------"
            #print self.authorizationChannel
            #print "--------------------------------------------"
            self.kappa = self.getDeviceByRole("kappa")
            self.phi = self.getDeviceByRole("phi")
            self.omega = self.getDeviceByRole("omega")
            self.lightarm = self.getDeviceByRole("lightarm")
            self.zoom = self.getDeviceByRole("zoom")
            self.obx = self.getDeviceByRole("obx")
            self.detdist = self.getDeviceByRole("detectordist")
        except:
            #            self.errorDeviceInstance(self.getProperty("tangoname2"))
            logging.getLogger("HWR").error("%s: unknown device name",
                                           self.getProperty("tangoname"))

    def authorizationChanged(self, newvalue):
        self.emit("authorizationChanged", newvalue)
        logging.getLogger("HWR").debug(
            "%s: GonioEquipment. Authorization from SC changed. Now is %s.",
            self.name(), newvalue)

    def Loading(self):
        try:
            logging.getLogger("HWR").debug(
                "%s: GonioEquipment. Inserting Pilatus Guillotine.",
                self.name())
            try:
                self.guillot.Insert()
                self.microglide.Home()
                #self.current_distance = self.distance.position
                #if self.current_distance <= 450:
                #    self.distance.position = 450
            except:
                logging.getLogger("HWR").error(
                    "%s: GonioEquipment.. Error trying inserting Guillotine.",
                    self.name())
        except:
            pass

        if abs(self.kappa.getPosition() - 55.) > EPSILON:
            self.kappa.move(55.)
        if abs(self.omega.getPosition() + 17.) > EPSILON:
            self.omega.move(-17.)
        _obx = self.obx.getShutterState()
        print("OBX State = %s" % _obx)
        if _obx == "opened":
            self.obx.closeShutter()
        _zoom = self.zoom.getCurrentPositionName()
        if _zoom != "Zoom 1":
            self.zoom.moveToPosition("Zoom 1")
        _light = self.lightarm.getWagoState()
        print("LIGHT POSITION:", _light)
        if _light == "out":
            self.lightarm.wagoIn()
        self.state = "Centring"

#        elif "obx" in device.tangoname.lower():
#            print "OBX STATE:", device.getShutterState()
#            if device.getShutterState() == "opened":
#                device.closeShutter()
#        elif "zoom" in device.tangoname.lower():
#            _zoom = device.getCurrentPositionName()
#            print "ZOOM POSITION:", _zoom
#            if _zoom != "Zoom 1":
#                device.moveToPosition("Zoom 1")
#        elif device.username == "Resolution":
#            print "Detector Distance", device.currentDistance
#            if device.currentDistance <= 350:
#                device.move(350.)
#            print device.tangoname, device.username #, device.getPosition()
#            #print device.getState()

    def Centring(self):
        #try:
        #    if self.current_distance > 195:
        #        self.distance.position = self.current_distance
        #except:
        #    logging.getLogger("HWR").error("%s: GonioEquipment.. Error trying mv back detector.", self.name())

        if abs(self.kappa.getPosition()) > EPSILON:
            self.kappa.move(0.)
        if abs(self.omega.getPosition()) > EPSILON:
            self.omega.move(0.)
        _zoom = self.zoom.getCurrentPositionName()
        print("ZOOM POSITION:", _zoom)
        if _zoom != "Zoom 1":
            self.zoom.moveToPosition("Zoom 1")
        _light = self.lightarm.getWagoState()
        print("LIGHT POSITION:", _light)
        if _light == "out":
            self.lightarm.wagoIn()
        self.state = "Centring"

    def wagoOut(self):
        self.Centring()

    def wagoIn(self):
        self.Loading()

#    def initAll(self):
#        initState = self.ms.getState()
#        self.ms.initAll()
#        state = self.ms.getState()
#        while state == initState:
#            print 'waiting state change...', state
#            qApp.processEvents(100)
#            state = self.ms.getState()
#        while state in ("MOVING", "DONE"):
#            print 'processing events...', state
#            qApp.processEvents(100)
#            state = self.ms.getState()
#        if state == "READY":
#            print "-----> emit stateChanged..."
#            self.emit("stateChanged", ["Kappa", "READY"])
#            self.emit("stateChanged", ["phi", "READY"])
#            devices = self.getDevices()
#            for device in devices:
#                device.getMscServer(self.ms)
#                device.motorStateChanged("READY")

    def initGoniometer(self):
        print("EUREKA :!!!!!!!!!!!!!!!!!!!!!!!")

    def isSpecConnected(self):
        #logging.getLogger().debug("%s: MSCEquipment.isSpecConnected()" % self.name())
        return True

    def isConnected(self):
        #logging.getLogger().debug("%s: MSCEquipment.isConnected()" % self.name())
        return True

    def isDisconnected(self):
        #logging.getLogger().debug("%s: MSCEquipment.isDisconnected()" % self.name())
        return True

    def isReady(self):
        #logging.getLogger("HWR").info("%s: MSCEquipment.isReady", self.name())
        return True

    def SCKappaOn(self):
        logging.getLogger("HWR").info("%s: MSCEquipment.SCKappaOn",
                                      self.name())

    def SCKappaOff(self):
        logging.getLogger("HWR").info("%s: MSCEquipment.SCKappaOff",
                                      self.name())

    def getWagoState(self):
        if (abs(self.kappa.getPosition()) < EPSILON) and \
           (abs(self.omega.getPosition()) < EPSILON):
            self.state = "Centring"
            return self.state
        else:
            self.state = "Loading"
            return self.state
Ejemplo n.º 10
0
class PX1Energy(Device):

    energy_state = {
        "ALARM": "error",
        "FAULT": "error",
        "RUNNING": "moving",
        "MOVING": "moving",
        "STANDBY": "ready",
        "DISABLE": "error",
        "UNKNOWN": "unknown",
        "EXTRACT": "outlimits",
    }

    def init(self):

        self.moving = False

        self.doBacklashCompensation = False

        self.current_energy = None
        self.current_state = None

        try:
            self.monodevice = DeviceProxy(self.getProperty("mono_device"))
        except BaseException:
            self.errorDeviceInstance(self.getProperty("mono_device"))

        # Nom du device bivu (Energy to gap) : necessaire pour amelioration du
        # positionnement de l'onduleur (Backlash)
        self.und_device = DeviceProxy(self.getProperty("undulator_device"))
        self.doBacklashCompensation = self.getProperty("backlash")

        # parameters for polling
        self.isConnected()

        self.energy_chan = self.getChannelObject("energy")
        self.energy_chan.connectSignal("update", self.energyChanged)

        self.stop_cmd = self.getCommandObject("stop")

        self.state_chan = self.getChannelObject("state")
        self.state_chan.connectSignal("update", self.stateChanged)

    def connectNotify(self, signal):
        if signal == "energyChanged":
            logging.getLogger("HWR").debug(
                "PX1Energy. connectNotify. sending energy value %s" %
                self.get_energy())
            self.energyChanged(self.get_energy())

        if signal == "stateChanged":
            logging.getLogger("HWR").debug(
                "PX1Energy. connectNotify. sending state value %s" %
                self.get_state())
            self.stateChanged(self.get_state())

        self.setIsReady(True)

    def stateChanged(self, value):
        str_state = str(value)
        if str_state == "MOVING":
            self.moveEnergyCmdStarted()

        if self.current_state == "MOVING" or self.moving == True:
            if str_state != "MOVING":
                self.moveEnergyCmdFinished()

        self.current_state = str_state
        self.emit("stateChanged", self.energy_state[str_state])

    # function called during polling
    def energyChanged(self, value):

        if (self.current_energy is not None
                and abs(self.current_energy - value) < 0.0001):
            return

        self.current_energy = value

        wav = self.getCurrentWavelength()
        if wav is not None:
            self.emit("energyChanged", (value, wav))

    def isSpecConnected(self):
        return True

    def isConnected(self):
        return True

    def sConnected(self):
        self.emit("connected", ())

    def sDisconnected(self):
        self.emit("disconnected", ())

    def isDisconnected(self):
        return True

    # Definit si la beamline est a energie fixe ou variable
    def can_move_energy(self):
        return True

    def getPosition(self):
        return self.getCurrentEnergy()

    def getCurrentEnergy(self):
        return self.get_energy()

    def get_energy(self):
        return self.energy_chan.getValue()

    def getState(self):
        return self.get_state()

    def get_state(self):
        return str(self.state_chan.getValue())

    def getEnergyComputedFromCurrentGap(self):
        return self.und_device.energy

    def getCurrentUndulatorGap(self):
        return self.und_device.gap

    def get_wavelength(self):
        return self.monodevice.read_attribute("lambda").value

    def getCurrentWavelength(self):
        return self.get_wavelength()

    def getLimits(self):
        return self.getEnergyLimits()

    def get_energy_limits(self):
        chan_info = self.energy_chan.getInfo()
        return (float(chan_info.min_value), float(chan_info.max_value))

    def get_wavelength_limits(self):
        energy_min, energy_max = self.getEnergyLimits()

        # max is min and min is max
        max_lambda = self.energy_to_lambda(energy_min)
        min_lambda = self.energy_to_lambda(energy_max)

        return (min_lambda, max_lambda)

    def energy_to_lambda(self, value):
        # conversion is done by mono device
        self.monodevice.simEnergy = value
        return self.monodevice.simLambda

    def lambda_to_energy(self, value):
        # conversion is done by mono device
        self.monodevice.simLambda = value
        return self.monodevice.simEnergy

    def move_energy(self, value, wait=False):
        value = float(value)

        backlash = 0.1  # en mm
        gaplimite = 5.5  # en mm

        if self.get_state() != "MOVING":
            if self.doBacklashCompensation:
                try:
                    # Recuperation de la valeur de gap correspondant a l'energie souhaitee
                    # self.und_device.autoApplyComputedParameters = False
                    self.und_device.energy = value
                    newgap = self.und_device.computedGap
                    actualgap = self.und_device.gap

                    #                    self.und_device.autoApplyComputedParameters = True

                    while str(self.und_device.State()) == "MOVING":
                        time.sleep(0.2)

                    # On applique le backlash que si on doit descendre en gap
                    if newgap < actualgap + backlash:
                        # Envoi a un gap juste en dessous (backlash)
                        if newgap - backlash > gaplimite:
                            self.und_device.gap = newgap - backlash
                            while str(self.und_device.State()) == "MOVING":
                                time.sleep(0.2)

                            self.energy_chan.setValue(value)
                        else:
                            self.und_device.gap = gaplimite
                            self.und_device.gap = newgap + backlash
                        time.sleep(1)
                except BaseException:
                    logging.getLogger("HWR").error(
                        "%s: Cannot move undulator U20 : State device = %s",
                        self.name(),
                        str(self.und_device.State()),
                    )

            try:
                self.energy_chan.setValue(value)
                return value
            except BaseException:
                logging.getLogger("HWR").error(
                    "%s: Cannot move Energy : State device = %s",
                    self.name(),
                    self.get_state(),
                )

        else:
            logging.getLogger("HWR").error(
                "%s: Cannot move Energy : State device = %s",
                self.name(),
                self.get_state(),
            )

    def move_wavelength(self, value, wait=False):
        egy_value = self.lambda_to_energy(float(value))
        logging.getLogger("HWR").debug(
            "%s: Moving wavelength to : %s (egy to %s" %
            (self.name(), value, egy_value))
        self.move_energy(egy_value)
        return value

    def cancelMoveEnergy(self):
        self.stop_cmd()
        self.moving = False

    def energyLimitsChanged(self, limits):
        egy_min, egy_max = limits

        lambda_min = self.energy_to_lambda(egy_min)
        lambda_max = self.energy_to_lambda(egy_max)

        wav_limits = (lambda_min, lambda_max)

        self.emit("energyLimitsChanged", (limits, ))

        if None not in wav_limits:
            self.emit("wavelengthLimitsChanged", (wav_limits, ))
        else:
            self.emit("wavelengthLimitsChanged", (None, ))

    def moveEnergyCmdReady(self):
        if not self.moving:
            self.emit("moveEnergyReady", (True, ))

    def moveEnergyCmdNotReady(self):
        if not self.moving:
            self.emit("moveEnergyReady", (False, ))

    def moveEnergyCmdStarted(self):
        self.moving = True
        self.emit("moveEnergyStarted", ())

    def moveEnergyCmdFailed(self):
        self.moving = False
        self.emit("moveEnergyFailed", ())

    def moveEnergyCmdAborted(self):
        self.moving = False

    def moveEnergyCmdFinished(self):
        self.moving = False
        self.emit("moveEnergyFinished", ())

    def getPreviousResolution(self):
        return (None, None)

    def restoreResolution(self):
        return (False, "Resolution motor not defined")

    getEnergyLimits = get_energy_limits
    getWavelengthLimits = get_wavelength_limits
    canMoveEnergy = can_move_energy
    startMoveEnergy = move_energy
    startMoveWavelength = move_wavelength
Ejemplo n.º 11
0
    def init(self):
        """
        Init method
        """

        self.collect_devname = self.getProperty("tangoname")
        self.collect_device = DeviceProxy(self.collect_devname)

        self.collect_state_chan = self.getChannelObject("state")

        self.px1env_hwobj = self.getObjectByRole("environment")

        self.fastshut_hwobj = self.getObjectByRole("fastshut")
        self.frontend_hwobj = self.getObjectByRole("frontend")
        self.safshut_hwobj = self.getObjectByRole("safshut")

        self.lightarm_hwobj = self.getObjectByRole("lightarm")

        self.diffractometer_hwobj = self.getObjectByRole("diffractometer")
        self.mxlocal_object = self.getObjectByRole("beamline_configuration")

        self.omega_hwobj = self.getObjectByRole("omega")
        self.kappa_hwobj = self.getObjectByRole("kappa")
        self.phi_hwobj = self.getObjectByRole("phi")

        self.lims_client_hwobj = self.getObjectByRole("lims_client")
        self.machine_info_hwobj = self.getObjectByRole("machine_info")
        self.energy_hwobj = self.getObjectByRole("energy")
        self.resolution_hwobj = self.getObjectByRole("resolution")
        self.transmission_hwobj = self.getObjectByRole("transmission")
        self.detector_hwobj = self.getObjectByRole("detector")
        self.beam_info_hwobj = self.getObjectByRole("beam_info")
        # self.autoprocessing_hwobj = self.getObjectByRole("auto_processing")
        self.graphics_manager_hwobj = self.getObjectByRole("graphics_manager")
        self.flux_hwobj = self.getObjectByRole("flux")

        self.img2jpeg = self.getProperty("imgtojpeg")
        undulators = self.get_undulators()

        self.exp_type_dict = {"Mesh": "raster", "Helical": "Helical"}

        det_px, det_py = self.detector_hwobj.get_pixel_size()

        self.set_beamline_configuration(
            synchrotron_name="SOLEIL",
            directory_prefix=self.getProperty("directory_prefix"),
            default_exposure_time=self.detector_hwobj.get_default_exposure_time(),
            minimum_exposure_time=self.detector_hwobj.get_minimum_exposure_time(),
            detector_fileext=self.detector_hwobj.get_file_suffix(),
            detector_type=self.detector_hwobj.get_detector_type(),
            detector_manufacturer=self.detector_hwobj.get_manufacturer(),
            detector_model=self.detector_hwobj.get_model(),
            detector_px=det_px,
            detector_py=det_py,
            undulators=undulators,
            focusing_optic=self.getProperty("focusing_optic"),
            monochromator_type=self.getProperty("monochromator"),
            beam_divergence_vertical=self.beam_info_hwobj.get_beam_divergence_hor(),
            beam_divergence_horizontal=self.beam_info_hwobj.get_beam_divergence_ver(),
            polarisation=self.getProperty("polarisation"),
            input_files_server=self.getProperty("input_files_server"),
        )

        self.emit("collectConnected", (True,))
        self.emit("collectReady", (True,))
Ejemplo n.º 12
0
class PX1Collect(AbstractCollect, HardwareObject):
    """Main data collection class. Inherited from AbstractMulticollect
       Collection is done by setting collection parameters and
       executing collect command
    """

    adxv_host = "127.0.0.1"
    adxv_port = 8100
    adxv_interval = 2.0  # minimum time (in seconds) between image refresh on adxv

    goimg_dir = "/nfs/ruche/share-temp/Proxima/.goimgpx1"
    goimg_filename = "goimg.db"

    characterization_nb_merged_images = 10

    def __init__(self, name):
        """

        :param name: name of the object
        :type name: string
        """

        AbstractCollect.__init__(self)
        HardwareObject.__init__(self, name)

        self._error_msg = ""
        self.owner = None
        self.osc_id = None
        self._collecting = None

        self.diffractometer_hwobj = None
        self.omega_hwobj = None
        self.kappa_hwobj = None
        self.phi_hwobj = None
        self.lims_client_hwobj = None
        self.machine_info_hwobj = None
        self.energy_hwobj = None
        self.resolution_hwobj = None
        self.transmission_hwobj = None
        self.detector_hwobj = None
        self.beam_info_hwobj = None
        self.autoprocessing_hwobj = None
        self.graphics_manager_hwobj = None
        self.mxlocal = None

        self.helical_positions = None

    def init(self):
        """
        Init method
        """

        self.collect_devname = self.getProperty("tangoname")
        self.collect_device = DeviceProxy(self.collect_devname)

        self.collect_state_chan = self.getChannelObject("state")

        self.px1env_hwobj = self.getObjectByRole("environment")

        self.fastshut_hwobj = self.getObjectByRole("fastshut")
        self.frontend_hwobj = self.getObjectByRole("frontend")
        self.safshut_hwobj = self.getObjectByRole("safshut")

        self.lightarm_hwobj = self.getObjectByRole("lightarm")

        self.diffractometer_hwobj = self.getObjectByRole("diffractometer")
        self.mxlocal_object = self.getObjectByRole("beamline_configuration")

        self.omega_hwobj = self.getObjectByRole("omega")
        self.kappa_hwobj = self.getObjectByRole("kappa")
        self.phi_hwobj = self.getObjectByRole("phi")

        self.lims_client_hwobj = self.getObjectByRole("lims_client")
        self.machine_info_hwobj = self.getObjectByRole("machine_info")
        self.energy_hwobj = self.getObjectByRole("energy")
        self.resolution_hwobj = self.getObjectByRole("resolution")
        self.transmission_hwobj = self.getObjectByRole("transmission")
        self.detector_hwobj = self.getObjectByRole("detector")
        self.beam_info_hwobj = self.getObjectByRole("beam_info")
        # self.autoprocessing_hwobj = self.getObjectByRole("auto_processing")
        self.graphics_manager_hwobj = self.getObjectByRole("graphics_manager")
        self.flux_hwobj = self.getObjectByRole("flux")

        self.img2jpeg = self.getProperty("imgtojpeg")
        undulators = self.get_undulators()

        self.exp_type_dict = {"Mesh": "raster", "Helical": "Helical"}

        det_px, det_py = self.detector_hwobj.get_pixel_size()

        self.set_beamline_configuration(
            synchrotron_name="SOLEIL",
            directory_prefix=self.getProperty("directory_prefix"),
            default_exposure_time=self.detector_hwobj.get_default_exposure_time(),
            minimum_exposure_time=self.detector_hwobj.get_minimum_exposure_time(),
            detector_fileext=self.detector_hwobj.get_file_suffix(),
            detector_type=self.detector_hwobj.get_detector_type(),
            detector_manufacturer=self.detector_hwobj.get_manufacturer(),
            detector_model=self.detector_hwobj.get_model(),
            detector_px=det_px,
            detector_py=det_py,
            undulators=undulators,
            focusing_optic=self.getProperty("focusing_optic"),
            monochromator_type=self.getProperty("monochromator"),
            beam_divergence_vertical=self.beam_info_hwobj.get_beam_divergence_hor(),
            beam_divergence_horizontal=self.beam_info_hwobj.get_beam_divergence_ver(),
            polarisation=self.getProperty("polarisation"),
            input_files_server=self.getProperty("input_files_server"),
        )

        self.emit("collectConnected", (True,))
        self.emit("collectReady", (True,))

    def data_collection_hook(self):
        """Main collection hook
        """

        collection_type = self.current_dc_parameters["experiment_type"]

        logging.getLogger("HWR").info(
            "PX1Collect: Running PX1 data collection hook. Type is %s" % collection_type
        )

        if self.aborted_by_user:
            self.emit_collection_failed("Aborted by user")
            self.aborted_by_user = False
            return

        ready = self.prepare_devices_for_collection()

        if not ready:
            self.collection_failed("Cannot prepare collection")
            self.stop_collect()
            return

        if collection_type != "Characterization":  # standard
            prepare_ok = self.prepare_standard_collection()
        else:
            prepare_ok = self.prepare_characterization()

        self._collecting = True

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        # for progressBar brick
        self.emit("progressInit", "Collection", osc_seq["number_of_images"])

        #
        # Run
        #

        self.prepare_directories()

        if collection_type != "Characterization":  # standard
            self.start_standard_collection()
            self.follow_collection_progress()
        else:
            self.start_characterization()

        # includes

        self.data_collection_end()
        self.collection_finished()

    def prepare_standard_collection(self):

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]

        logging.getLogger("HWR").info("PX1Collect: fileinfo is %s " % str(fileinfo))
        imgname = fileinfo["template"] % osc_seq["start_image_number"]

        # move omega to start angle
        start_angle = osc_seq["start"]

        nb_images = osc_seq["number_of_images"]
        osc_range = osc_seq["range"]
        exp_time = osc_seq["exposure_time"]

        logging.getLogger("HWR").info(
            "PX1Collect:  nb_images: %s / osc_range: %s / exp_time: %s"
            % (nb_images, osc_range, exp_time)
        )

        self.collect_device.exposurePeriod = exp_time
        self.collect_device.numberOfImages = nb_images
        self.collect_device.imageWidth = osc_range

        # self.collect_device.collectAxis = "Omega"

        self.collect_device.startAngle = start_angle
        self.collect_device.triggerMode = 2

        self.collect_device.imagePath = basedir
        self.collect_device.imageName = imgname
        time.sleep(0.2)
        self.collect_device.PrepareCollect()
        ret = self.wait_collect_standby()
        if ret is False:
            logging.getLogger("user_level_log").info(
                "Collect server prepare error. Aborted"
            )
            return False

        self.prepare_headers()

        return True

    def start_standard_collection(self):
        self.emit("collectStarted", (self.owner, 1))
        self.detector_hwobj.start_collection()
        self.collect_device.Start()

    def follow_collection_progress(self):

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]
        archive_dir = fileinfo["archive_directory"]
        template = fileinfo["template"]

        jpeg_template = os.path.splitext(template)[0] + ".jpeg"
        thumb_template = os.path.splitext(template)[0] + ".thumb.jpeg"

        osc_range = osc_seq["range"]
        osc_start = osc_seq["start"]
        nb_images = osc_seq["number_of_images"]

        first_imgno = osc_seq["start_image_number"]
        first_image_fullpath = os.path.join(basedir, template % first_imgno)
        first_image_jpegpath = os.path.join(archive_dir, jpeg_template % first_imgno)
        first_image_thumbpath = os.path.join(archive_dir, thumb_template % first_imgno)

        last_imgno = first_imgno + nb_images - 1
        last_image_fullpath = os.path.join(basedir, template % last_imgno)
        last_image_jpegpath = os.path.join(archive_dir, jpeg_template % last_imgno)
        last_image_thumbpath = os.path.join(archive_dir, thumb_template % last_imgno)

        # wait for first image
        self.adxv_latest_refresh = 0
        self.is_firstimg = True

        self.file_waiting_display = first_image_fullpath  # for showing on adxv
        self.wait_image_on_disk(first_image_fullpath)
        thumbs_up = self.generate_thumbnails(
            first_image_fullpath, first_image_jpegpath, first_image_thumbpath
        )
        if thumbs_up:
            self.store_image_in_lims(first_imgno)

        # update display while collect is running
        while self.is_moving() or self.is_firstimg:
            self.adxv_show_latest(fileinfo)
            time.sleep(0.1)

        # wait for last image
        self.wait_image_on_disk(last_image_fullpath)
        thumbs_up = self.generate_thumbnails(
            last_image_fullpath, last_image_jpegpath, last_image_thumbpath
        )
        self.adxv_sync_image(first_image_fullpath)
        if thumbs_up:
            self.store_image_in_lims(last_imgno)

    def prepare_characterization(self):
        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]

        basedir = fileinfo["directory"]

        merged_images = self.characterization_nb_merged_images

        osc_range = float(osc_seq["range"]) / merged_images
        exp_time = float(osc_seq["exposure_time"]) / merged_images

        self.collect_device.numberOfImages = int(merged_images)
        self.collect_device.exposurePeriod = exp_time
        self.collect_device.imagePath = basedir
        self.collect_device.imageWidth = osc_range

        self.detector_hwobj.set_image_headers(["Angle_increment %.4f" % osc_range])

        return True

    def start_characterization(self):

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]

        start_angle = osc_seq["start"]
        nb_images = osc_seq["number_of_images"]
        merged_images = self.characterization_nb_merged_images
        wedge_range = osc_seq["range"] / merged_images

        image_template = fileinfo["template"]

        oscil_image_template = image_template[:3] + "_wdg" + image_template[3:]

        start = start_angle

        self.emit("collectStarted", (self.owner, 1))

        for imgno in range(nb_images):
            image_filename = image_template % (imgno + 1)
            image_fullpath = os.path.join(fileinfo["directory"], image_filename)

            series_first_image = oscil_image_template % (
                (start - start_angle) / wedge_range + 1
            )
            series_last_image = oscil_image_template % (
                (start - start_angle) / wedge_range + merged_images
            )
            series_last_fullpath = os.path.join(
                fileinfo["directory"], series_last_image
            )

            logging.info(
                "PX1Collect: start image series for angle %s - first image name is %s"
                % (start, series_first_image)
            )

            self.collect_device.imageName = series_first_image
            self.collect_device.startAngle = start
            self.wait_collect_ready()
            self.collect_device.prepareCollect()
            self.wait_collect_ready()

            self.detector_hwobj.set_image_headers(["Start_angle %.4f" % start])
            self.collect_device.Start()

            # file names to wait for

            # wait for completion
            self.wait_collect_ready()
            logging.info(
                "PX1Collect:   waiting to finish image series for angle %s - waiting for %s"
                % (start, series_last_fullpath)
            )
            self.wait_image_on_disk(series_last_fullpath)
            self.adxv_sync_image(series_last_fullpath)

            # merge images into one image
            merge_images(
                series_first_image,
                image_filename,
                fileinfo["directory"],
                start,
                osc_seq["range"],
                osc_seq["exposure_time"],
            )

            logging.info(
                "PX1Collect:   waiting for merged image to appear on disk %s - waiting for %s"
                % (start, image_fullpath)
            )
            self.wait_image_on_disk(image_fullpath)
            self.adxv_sync_image(image_fullpath)

            start += 90.0

    def data_collection_end(self):
        #
        # data collection end (or abort)
        #
        logging.getLogger("HWR").info("PX1Collect: finishing data collection ")
        self.omega_hwobj.stop()
        self.fastshut_hwobj.closeShutter()

        self.emit("progressStop")

    def data_collection_failed(self):
        logging.getLogger("HWR").info(
            "PX1Collect: Data collection failed. recovering sequence should go here"
        )

    def collect_finished(self, green):
        logging.info("PX1Collect: Data collection finished")

    def collect_failed(self, par):
        logging.exception("PX1Collect: Data collection failed")
        self.current_dc_parameters["status"] = "failed"
        exc_type, exc_value, exc_tb = sys.exc_info()
        failed_msg = "Data collection failed!\n%s" % exc_value
        self.emit(
            "collectOscillationFailed",
            (
                self.owner,
                False,
                failed_msg,
                self.current_dc_parameters.get("collection_id"),
                1,
            ),
        )

        self.detector_hwobj.stop_collection()
        self.omega_hwobj.stop()
        self.data_collection_end()

    def set_helical_pos(self, arg):
        """
        Descript. : 8 floats describe
        p1AlignmY, p1AlignmZ, p1CentrX, p1CentrY
        p2AlignmY, p2AlignmZ, p2CentrX, p2CentrY
        """
        self.helical_positions = [
            arg["1"]["phiy"],
            arg["1"]["phiz"],
            arg["1"]["sampx"],
            arg["1"]["sampy"],
            arg["2"]["phiy"],
            arg["2"]["phiz"],
            arg["2"]["sampx"],
            arg["2"]["sampy"],
        ]

    def setMeshScanParameters(self, num_lines, num_images_per_line, mesh_range):
        """
        Descript. :
        """
        pass

    def trigger_auto_processing(self, *args):
        pass

    ## generate snapshots and data thumbnails ##
    @task
    def _take_crystal_snapshot(self, filename):
        """
        Descript. :
        """
        if not self.is_sampleview_phase():
            self.go_to_sampleview()
            time.sleep(2)  # allow time to refresh display after

        self.lightarm_hwobj.adjustLightLevel()
        time.sleep(0.3)  # allow time to refresh display after

        self.graphics_manager_hwobj.save_scene_snapshot(filename)
        logging.getLogger("HWR").debug("PX1Collect:  - snapshot saved to %s" % filename)

    def generate_thumbnails(self, filename, jpeg_filename, thumbnail_filename):
        #
        # write info on LIMS

        try:
            logging.info("PX1Collect: Generating thumbnails for %s" % filename)
            logging.info("PX1Collect:       jpeg file: %s" % jpeg_filename)
            logging.info("PX1Collect:  thumbnail file: %s" % thumbnail_filename)

            self.wait_image_on_disk(filename)
            if os.path.exists(filename):
                subprocess.Popen([self.img2jpeg, filename, jpeg_filename, "0.4"])
                subprocess.Popen([self.img2jpeg, filename, thumbnail_filename, "0.1"])
                return True
            else:
                logging.info(
                    "PX1Collect: Oopps.  Trying to generate thumbs but  image is not on disk"
                )
                return False
        except BaseException:
            import traceback

            logging.error("PX1Collect: Cannot generate thumbnails for %s" % filename)
            logging.error(traceback.format_exc())
            return False

    ## generate snapshots and data thumbnails (END) ##

    ## FILE SYSTEM ##
    def wait_image_on_disk(self, filename, timeout=20.0):
        start_wait = time.time()
        while not os.path.exists(filename):
            if time.time() - start_wait > timeout:
                logging.info("PX1Collect: Giving up waiting for image. Timeout")
                break
            time.sleep(0.1)
        logging.info(
            "PX1Collect: Waiting for image %s ended in  %3.2f secs"
            % (filename, time.time() - start_wait)
        )

    def check_directory(self, basedir):
        if not os.path.exists(basedir):
            try:
                os.makedirs(basedir)
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise

    def prepare_directories(self):
        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]
        process_dir = basedir.replace("RAW_DATA", "PROCESSED_DATA")

        try:
            os.chmod(process_dir, 0o777)
        except BaseException:
            import traceback

            logging.getLogger("HWR").error(
                "PX1Collect: Error changing permissions for PROCESS directory"
            )
            logging.getLogger("HWR").error(traceback.format_exc())

        self.create_goimg_file(process_dir)

    def create_goimg_file(self, dirname):

        db_f = os.path.join(self.goimg_dir, self.goimg_filename)
        if os.path.exists(db_f):
            os.remove(db_f)

        with open(db_f, "w") as fd:
            fd.write(dirname)
        os.chmod(db_f, 0o777)

    def create_file_directories(self):
        """
        Method create directories for raw files and processing files.
        Directorie for xds.input and auto_processing are created
        """
        self.create_directories(
            self.current_dc_parameters["fileinfo"]["directory"],
            self.current_dc_parameters["fileinfo"]["process_directory"],
        )

        """create processing directories and img links"""
        xds_directory, auto_directory = self.prepare_input_files()
        try:
            # self.create_directories(xds_directory, auto_directory)
            # os.system("chmod -R 777 %s %s" % (xds_directory, auto_directory))
            """todo, create link of imgs for auto_processing
            try:
                os.symlink(files_directory, os.path.join(process_directory, "img"))
            except os.error, e:
                if e.errno != errno.EEXIST:
                    raise
            """
            pass
            # os.symlink(files_directory, os.path.join(process_directory, "img"))
        except BaseException:
            logging.exception("PX1Collect: Could not create processing file directory")
            return

        if xds_directory:
            self.current_dc_parameters["xds_dir"] = xds_directory

        if auto_directory:
            self.current_dc_parameters["auto_dir"] = auto_directory

    def prepare_input_files(self):
        """
        Descript. :
        """
        i = 1
        log = logging.getLogger("user_level_log")
        while True:
            xds_input_file_dirname = "xds_%s_%s_%d" % (
                self.current_dc_parameters["fileinfo"]["prefix"],
                self.current_dc_parameters["fileinfo"]["run_number"],
                i,
            )
            xds_directory = os.path.join(
                self.current_dc_parameters["fileinfo"]["process_directory"],
                xds_input_file_dirname,
            )
            if not os.path.exists(xds_directory):
                break
            i += 1
        self.current_dc_parameters["xds_dir"] = xds_directory

        mosflm_input_file_dirname = "mosflm_%s_run%s_%d" % (
            self.current_dc_parameters["fileinfo"]["prefix"],
            self.current_dc_parameters["fileinfo"]["run_number"],
            i,
        )
        mosflm_directory = os.path.join(
            self.current_dc_parameters["fileinfo"]["process_directory"],
            mosflm_input_file_dirname,
        )

        log.info("  - xds: %s / mosflm: %s" % (xds_directory, mosflm_directory))
        return xds_directory, mosflm_directory

    ## FILE SYSTEM (END) ##

    def prepare_devices_for_collection(self):

        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]

        self.check_directory(basedir)

        # check fast shutter closed. others opened
        shutok = self.check_shutters()
        shutok = True

        if not shutok:
            logging.getLogger("user_level_log").info(
                " Shutters not ready for collection. Aborted"
            )
            return False

        detok = self.detector_hwobj.prepare_collection(self.current_dc_parameters)
        if not detok:
            logging.getLogger("user_level_log").info(
                "Cannot prepare detector for collection. Aborted"
            )
            return False

        adxv_ok = self.adxv_connect()

        diff_ok = self.diffractometer_prepare_collection()
        if not diff_ok:
            logging.getLogger("user_level_log").info(
                "Cannot prepare diffractometer for collection. Aborted"
            )
            return False

        return True

    def diffractometer_prepare_collection(self):
        self.diffractometer_hwobj.wait_device_ready(timeout=10)

        # go to collect phase
        if not self.is_collect_phase():
            success = self.go_to_collect()
            if not success:
                logging.getLogger("HWR").info("PX1Collect: Cannot set COLLECT phase")
                return False
        return True

    def prepare_headers(self):
        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]

        ax, ay, bx, by = self.get_beam_configuration()

        dist = self.detector_hwobj.get_distance()
        wavlen = self.energy_hwobj.get_wavelength()

        start_angle = osc_seq["start"]
        nb_images = osc_seq["number_of_images"]
        img_range = osc_seq["range"]
        exp_time = osc_seq["exposure_time"]

        kappa_angle = self.kappa_hwobj.getPosition()

        _settings = [
            ["Wavelength %.5f", wavlen],
            ["Detector_distance %.4f", dist / 1000.0],
            ["Beam_x %.2f", ax * dist + bx],
            ["Beam_y %.2f", ay * dist + by],
            ["Alpha %.2f", 49.64],
            ["Start_angle %.4f", start_angle],
            ["Angle_increment %.4f", img_range],
            ["Oscillation_axis %s", "Omega"],
            ["Detector_2theta %.4f", 0.0],
            ["Polarization %.3f", 0.990],
            ["Kappa %.4f", kappa_angle],
        ]

        # if self.oscaxis == "Phi":
        # _settings.append(["Chi %.4f", self.omega_hwo.getPosition()])
        # _settings.append(["Phi %.4f", start])
        # elif self.oscaxis == "Omega":
        _settings.append(["Phi %.4f", self.phi_hwobj.getPosition()])
        _settings.append(["Chi %.4f", start_angle])
        self.detector_hwobj.set_image_headers(_settings)

    def check_shutters(self):
        # Check safety shutter
        if self.check_shutter_opened(
            self.safshut_hwobj, "Safety shutter"
        ) and self.check_shutter_opened(self.frontend_hwobj, "Front end"):
            return True
        else:
            return False

    def check_shutter_opened(self, shut_hwo, shutter_name="shutter"):
        if shut_hwo.isShutterOpened():
            return True

        if shut_hwo.getState() == "disabled":
            logging.getLogger("user_level_log").warning(
                "%s disabled. Collect cancelled" % shutter_name
            )
            return False
        elif shut_hwo.getState() in ["fault", "alarm", "error"]:
            logging.getLogger("user_level_log").warning(
                "%s is in fault state. Collect cancelled" % shutter_name
            )
            return False
        elif shut_hwo.isShutterClosed():
            shut_hwo.openShutter()
            return shut_hwo.waitShutter("opened")
        else:
            logging.getLogger("user_level_log").warning(
                "%s is in an unhandled state. Collect cancelled" % shutter_name
            )
            return False

    def close_fast_shutter(self):
        self.fastshut_hwobj.closeShutter()

    def close_safety_shutter(self):
        pass

    ## COLLECT SERVER STATE ##
    def wait_collect_standby(self, timeout=10):
        t0 = time.time()
        while not self.is_standby():
            elapsed = time.time() - t0
            if elapsed > timeout:
                break
            time.sleep(0.1)

    def wait_collect_moving(self, timeout=10):
        t0 = time.time()
        while not self.is_moving():
            elapsed = time.time() - t0
            if elapsed > timeout:
                break
            time.sleep(0.1)

    def wait_collect_ready(self, timeout=10):
        t0 = time.time()
        while self.is_moving():
            elapsed = time.time() - t0
            if elapsed > timeout:
                break
            time.sleep(0.1)

    def is_standby(self):
        return str(self.collect_state_chan.getValue()) == "STANDBY"

    def is_moving(self):
        return str(self.collect_state_chan.getValue()) in ["MOVING", "RUNNING"]

    ## COLLECT SERVER STATE (END) ##

    ## PX1 ENVIRONMENT PHASE HANDLING ##
    def is_collect_phase(self):
        return self.px1env_hwobj.isPhaseCollect()

    def go_to_collect(self, timeout=180):
        self.px1env_hwobj.gotoCollectPhase()
        gevent.sleep(0.5)

        t0 = time.time()
        while True:
            env_state = self.px1env_hwobj.getState()
            if env_state != "RUNNING" and self.is_collect_phase():
                break
            if time.time() - t0 > timeout:
                logging.getLogger("HWR").debug(
                    "PX1Collect: timeout sending supervisor to collect phase"
                )
                break
            gevent.sleep(0.5)

        return self.px1env_hwobj.isPhaseCollect()

    def is_sampleview_phase(self):
        return self.px1env_hwobj.isPhaseVisuSample()

    def go_to_sampleview(self, timeout=180):
        self.px1env_hwobj.gotoSampleViewPhase()

        gevent.sleep(0.5)

        t0 = time.time()
        while True:
            env_state = self.px1env_hwobj.getState()
            if env_state != "RUNNING" and self.is_sampleview_phase():
                break
            if time.time() - t0 > timeout:
                logging.getLogger("HWR").debug(
                    "PX1Collect: timeout sending supervisor to sample view phase"
                )
                break
            gevent.sleep(0.5)

        self.lightarm_hwobj.adjustLightLevel()
        return self.is_sampleview_phase()

    ## PX1 ENVIRONMENT PHASE HANDLING (END) ##

    ## OTHER HARDWARE OBJECTS ##
    def set_energy(self, value):
        """
        Descript. :
        """
        self.energy_hwobj.move_energy(value)

    def set_wavelength(self, value):
        """
        Descript. :
        """
        self.energy_hwobj.move_wavelength(value)

    def get_energy(self):
        return self.energy_hwobj.get_energy()

    def set_transmission(self, value):
        """
        Descript. :
        """
        self.transmission_hwobj.set_value(value)

    def set_resolution(self, value):
        """
        Descript. : resolution is a motor in out system
        """
        return
        self.resolution_hwobj.move(value)

    def move_detector(self, value):
        self.detector_hwobj.move_distance(value)

    @task
    def move_motors(self, motor_position_dict):
        """
        Descript. :
        """
        self.diffractometer_hwobj.move_motors(motor_position_dict)

    def get_wavelength(self):
        """
        Descript. :
            Called to save wavelength in lims
        """
        if self.energy_hwobj is not None:
            return self.energy_hwobj.get_wavelength()

    def get_detector_distance(self):
        """
        Descript. :
            Called to save detector_distance in lims
        """
        if self.detector_hwobj is not None:
            return self.detector_hwobj.get_distance()

    def get_resolution(self):
        """
        Descript. :
            Called to save resolution in lims
        """
        if self.resolution_hwobj is not None:
            return self.resolution_hwobj.getPosition()

    def get_transmission(self):
        """
        Descript. :
            Called to save transmission in lims
        """
        if self.transmission_hwobj is not None:
            return self.transmission_hwobj.getAttFactor()

    def get_undulators_gaps(self):
        """
        Descript. : return gaps as dict. In our case we have one gap,
                    others are 0
        """
        if self.energy_hwobj:
            try:
                u20_gap = self.energy_hwobj.getCurrentUndulatorGap()
                return {"u20": u20_gap}
            except BaseException:
                return {}
        else:
            return {}

    def get_beam_size(self):
        """
        Descript. :
        """
        if self.beam_info_hwobj is not None:
            return self.beam_info_hwobj.get_beam_size()

    def get_slit_gaps(self):
        """
        Descript. :
        """
        if self.beam_info_hwobj is not None:
            return self.beam_info_hwobj.get_slits_gap()
        return None, None

    def get_beam_shape(self):
        """
        Descript. :
        """
        if self.beam_info_hwobj is not None:
            return self.beam_info_hwobj.get_beam_shape()

    def get_measured_intensity(self):
        """
        Descript. :
        """
        if self.flux_hwobj is not None:
            flux = self.flux_hwobj.getValue()
        else:
            flux = 0.0
        return float("%.3e" % flux)

    def get_machine_current(self):
        """
        Descript. :
        """
        if self.machine_info_hwobj:
            return self.machine_info_hwobj.get_current()
        else:
            return 0

    def get_machine_message(self):
        """
        Descript. :
        """
        if self.machine_info_hwobj:
            return self.machine_info_hwobj.get_message()
        else:
            return ""

    def get_machine_fill_mode(self):
        """
        Descript. :
        """
        if self.machine_info_hwobj:
            return self.machine_info_hwobj.get_fill_mode()
        else:
            return ""

    def get_beam_configuration(self):
        pars_beam = self.mxlocal_object["SPEC_PARS"]["beam"]
        ax = pars_beam.getProperty("ax")
        ay = pars_beam.getProperty("ay")
        bx = pars_beam.getProperty("bx")
        by = pars_beam.getProperty("by")
        return [ax, ay, bx, by]

    def get_undulators(self):
        return [U20()]

    def get_flux(self):
        """
        Descript. :
        """
        return self.get_measured_intensity()

    ## OTHER HARDWARE OBJECTS (END) ##

    ## ADXV display images ##
    def adxv_connect(self):

        #  connect every time?? maybe we can do better
        try:
            res = socket.getaddrinfo(
                self.adxv_host, self.adxv_port, 0, socket.SOCK_STREAM
            )
            af, socktype, proto, canonname, sa = res[0]
            self.adxv_socket = socket.socket(af, socktype, proto)
            self.adxv_socket.connect((self.adxv_host, self.adxv_port))
            logging.getLogger().info("PX1Collect: ADXV Visualization connected.")
        except BaseException:
            self.adxv_socket = None
            logging.getLogger().info("PX1Collect: WARNING: Can't connect to ADXV.")

    def adxv_show_latest(self, fileinfo):

        now = time.time()
        elapsed = now - self.adxv_latest_refresh

        template = fileinfo["template"]
        basedir = fileinfo["directory"]

        if self.file_waiting_display is not None:
            if os.path.exists(self.file_waiting_display):
                self.adxv_sync_image(self.file_waiting_display)
                self.file_waiting_display = None
                self.is_firstimg = False

        # find next file to display
        if elapsed >= self.adxv_interval and self.file_waiting_display is None:
            _current_img_no = self.collect_device.currentImageSpi
            self.file_waiting_display = os.path.join(
                basedir, template % _current_img_no
            )
            self.adxv_last_refresh = time.time()

    def adxv_sync_image(self, filename):

        adxv_send_cmd = "\nload_image %s\n" + chr(32)

        try:
            if not self.adxv_socket:
                try:
                    self.adxv_connect()
                except Exception as err:
                    self.adxv_socket = None
                    logging.info(
                        "PX1Collect: ADXV: Warning: Can't connect to adxv socket to follow collect."
                    )
                    logging.error("PX1Collect: ADXV0: msg= %s" % err)
            else:
                logging.info(("PX1Collect: ADXV: " + adxv_send_cmd[1:-2]) % imgname)
                self.adxv_socket.send(adxv_send_cmd % imgname)
        except BaseException:
            try:
                del self.adxv_socket
                self.adxv_connect()
            except Exception as err:
                self.adxv_socket = None
                logging.error("PX1Collect: ADXV1: msg= %s" % err)
Ejemplo n.º 13
0
    def init(self):
        """
        Init method
        """

        self.collect_devname = self.getProperty("tangoname")
        self.collect_device = DeviceProxy(self.collect_devname)

        self.collect_state_chan = self.getChannelObject("state")

        self.px1env_hwobj = self.getObjectByRole("environment")

        self.fastshut_hwobj = self.getObjectByRole("fastshut")
        self.frontend_hwobj = self.getObjectByRole("frontend")
        self.safshut_hwobj = self.getObjectByRole("safshut")

        self.lightarm_hwobj = self.getObjectByRole("lightarm")

        self.diffractometer_hwobj = self.getObjectByRole("diffractometer")
        self.mxlocal_object = self.getObjectByRole("beamline_configuration")

        self.omega_hwobj = self.getObjectByRole("omega")
        self.kappa_hwobj = self.getObjectByRole("kappa")
        self.phi_hwobj = self.getObjectByRole("phi")

        self.lims_client_hwobj = self.getObjectByRole("lims_client")
        self.machine_info_hwobj = self.getObjectByRole("machine_info")
        self.energy_hwobj = self.getObjectByRole("energy")
        self.resolution_hwobj = self.getObjectByRole("resolution")
        self.transmission_hwobj = self.getObjectByRole("transmission")
        self.detector_hwobj = self.getObjectByRole("detector")
        self.beam_info_hwobj = self.getObjectByRole("beam_info")
        # self.autoprocessing_hwobj = self.getObjectByRole("auto_processing")
        self.graphics_manager_hwobj = self.getObjectByRole("graphics_manager")
        self.flux_hwobj = self.getObjectByRole("flux")

        self.img2jpeg = self.getProperty("imgtojpeg")
        undulators = self.get_undulators()

        self.exp_type_dict = {'Mesh': 'raster',
                              'Helical': 'Helical'}

        det_px, det_py = self.detector_hwobj.get_pixel_size()

        self.set_beamline_configuration(\
             synchrotron_name="SOLEIL",
             directory_prefix=self.getProperty("directory_prefix"),
             default_exposure_time=self.detector_hwobj.get_default_exposure_time(),
             minimum_exposure_time=self.detector_hwobj.get_minimum_exposure_time(),
             detector_fileext=self.detector_hwobj.get_file_suffix(),
             detector_type=self.detector_hwobj.get_detector_type(),
             detector_manufacturer=self.detector_hwobj.get_manufacturer(),
             detector_model=self.detector_hwobj.get_model(),
             detector_px=det_px,
             detector_py=det_py,
             undulators=undulators,
             focusing_optic=self.getProperty('focusing_optic'),
             monochromator_type=self.getProperty('monochromator'),
             beam_divergence_vertical=self.beam_info_hwobj.get_beam_divergence_hor(),
             beam_divergence_horizontal=self.beam_info_hwobj.get_beam_divergence_ver(),
             polarisation=self.getProperty('polarisation'),
             input_files_server=self.getProperty("input_files_server"))

        self.emit("collectConnected", (True,))
        self.emit("collectReady", (True, ))
Ejemplo n.º 14
0
class PX1Collect(AbstractCollect, HardwareObject):
    """Main data collection class. Inherited from AbstractMulticollect
       Collection is done by setting collection parameters and
       executing collect command
    """
    adxv_host = '127.0.0.1'
    adxv_port = 8100
    adxv_interval = 2.0 # minimum time (in seconds) between image refresh on adxv

    goimg_dir = "/nfs/ruche/share-temp/Proxima/.goimgpx1"
    goimg_filename = "goimg.db"

    characterization_nb_merged_images = 10

    def __init__(self, name):
        """

        :param name: name of the object
        :type name: string
        """

        AbstractCollect.__init__(self)
        HardwareObject.__init__(self, name)

        self._error_msg = ""
        self.owner = None
        self.osc_id = None
        self._collecting = None

        self.diffractometer_hwobj = None
        self.omega_hwobj = None
        self.kappa_hwobj = None
        self.phi_hwobj = None
        self.lims_client_hwobj = None
        self.machine_info_hwobj = None
        self.energy_hwobj = None
        self.resolution_hwobj = None
        self.transmission_hwobj = None
        self.detector_hwobj = None
        self.beam_info_hwobj = None
        self.autoprocessing_hwobj = None
        self.graphics_manager_hwobj = None
        self.mxlocal = None

        self.helical_positions = None

    def init(self):
        """
        Init method
        """

        self.collect_devname = self.getProperty("tangoname")
        self.collect_device = DeviceProxy(self.collect_devname)

        self.collect_state_chan = self.getChannelObject("state")

        self.px1env_hwobj = self.getObjectByRole("environment")

        self.fastshut_hwobj = self.getObjectByRole("fastshut")
        self.frontend_hwobj = self.getObjectByRole("frontend")
        self.safshut_hwobj = self.getObjectByRole("safshut")

        self.lightarm_hwobj = self.getObjectByRole("lightarm")

        self.diffractometer_hwobj = self.getObjectByRole("diffractometer")
        self.mxlocal_object = self.getObjectByRole("beamline_configuration")

        self.omega_hwobj = self.getObjectByRole("omega")
        self.kappa_hwobj = self.getObjectByRole("kappa")
        self.phi_hwobj = self.getObjectByRole("phi")

        self.lims_client_hwobj = self.getObjectByRole("lims_client")
        self.machine_info_hwobj = self.getObjectByRole("machine_info")
        self.energy_hwobj = self.getObjectByRole("energy")
        self.resolution_hwobj = self.getObjectByRole("resolution")
        self.transmission_hwobj = self.getObjectByRole("transmission")
        self.detector_hwobj = self.getObjectByRole("detector")
        self.beam_info_hwobj = self.getObjectByRole("beam_info")
        # self.autoprocessing_hwobj = self.getObjectByRole("auto_processing")
        self.graphics_manager_hwobj = self.getObjectByRole("graphics_manager")
        self.flux_hwobj = self.getObjectByRole("flux")

        self.img2jpeg = self.getProperty("imgtojpeg")
        undulators = self.get_undulators()

        self.exp_type_dict = {'Mesh': 'raster',
                              'Helical': 'Helical'}

        det_px, det_py = self.detector_hwobj.get_pixel_size()

        self.set_beamline_configuration(\
             synchrotron_name="SOLEIL",
             directory_prefix=self.getProperty("directory_prefix"),
             default_exposure_time=self.detector_hwobj.get_default_exposure_time(),
             minimum_exposure_time=self.detector_hwobj.get_minimum_exposure_time(),
             detector_fileext=self.detector_hwobj.get_file_suffix(),
             detector_type=self.detector_hwobj.get_detector_type(),
             detector_manufacturer=self.detector_hwobj.get_manufacturer(),
             detector_model=self.detector_hwobj.get_model(),
             detector_px=det_px,
             detector_py=det_py,
             undulators=undulators,
             focusing_optic=self.getProperty('focusing_optic'),
             monochromator_type=self.getProperty('monochromator'),
             beam_divergence_vertical=self.beam_info_hwobj.get_beam_divergence_hor(),
             beam_divergence_horizontal=self.beam_info_hwobj.get_beam_divergence_ver(),
             polarisation=self.getProperty('polarisation'),
             input_files_server=self.getProperty("input_files_server"))

        self.emit("collectConnected", (True,))
        self.emit("collectReady", (True, ))

    def data_collection_hook(self):
        """Main collection hook
        """

        collection_type = self.current_dc_parameters['experiment_type']

        logging.getLogger("HWR").info("PX1Collect: Running PX1 data collection hook. Type is %s" % collection_type )

        if self.aborted_by_user:
            self.emit_collection_failed("Aborted by user")
            self.aborted_by_user = False
            return

        ready = self.prepare_devices_for_collection()

        if not ready:
            self.collection_failed("Cannot prepare collection")
            self.stop_collect()
            return

        if collection_type != 'Characterization':  # standard
            prepare_ok = self.prepare_standard_collection()
        else:
            prepare_ok = self.prepare_characterization()

        self._collecting = True

        osc_seq = self.current_dc_parameters['oscillation_sequence'][0]
        # for progressBar brick
        self.emit("progressInit", "Collection", osc_seq['number_of_images'])

        #
        # Run
        #

        self.prepare_directories()

        if collection_type != 'Characterization':  # standard
            self.start_standard_collection()
            self.follow_collection_progress()
        else:
            self.start_characterization()

        # includes

        self.data_collection_end()
        self.collection_finished()

    def prepare_standard_collection(self):

        osc_seq = self.current_dc_parameters['oscillation_sequence'][0]
        fileinfo = self.current_dc_parameters['fileinfo']
        basedir = fileinfo['directory']

        logging.getLogger("HWR").info("PX1Collect: fileinfo is %s " % str(fileinfo))
        imgname = fileinfo['template'] % osc_seq['start_image_number']

        # move omega to start angle
        start_angle = osc_seq['start']

        nb_images = osc_seq['number_of_images']
        osc_range = osc_seq['range']
        exp_time = osc_seq['exposure_time'] 

        logging.getLogger("HWR").info("PX1Collect:  nb_images: %s / osc_range: %s / exp_time: %s" % \
                  (nb_images, osc_range, exp_time))

        self.collect_device.exposurePeriod = exp_time
        self.collect_device.numberOfImages = nb_images
        self.collect_device.imageWidth = osc_range

        # self.collect_device.collectAxis = "Omega"

        self.collect_device.startAngle = start_angle
        self.collect_device.triggerMode = 2
  
        self.collect_device.imagePath = basedir
        self.collect_device.imageName = imgname
        time.sleep(0.2)
        self.collect_device.PrepareCollect()
        ret = self.wait_collect_standby() 
        if ret is False:
              logging.getLogger("user_level_log").info("Collect server prepare error. Aborted") 
              return False

        self.prepare_headers()

        return True

    def start_standard_collection(self):
        self.emit("collectStarted", (self.owner, 1))
        self.detector_hwobj.start_collection()
        self.collect_device.Start()

    def follow_collection_progress(self):

        osc_seq = self.current_dc_parameters['oscillation_sequence'][0]
        fileinfo = self.current_dc_parameters['fileinfo']
        basedir = fileinfo['directory']
        archive_dir = fileinfo['archive_directory']
        template = fileinfo['template']

        jpeg_template = os.path.splitext(template)[0] + ".jpeg"
        thumb_template = os.path.splitext(template)[0] + ".thumb.jpeg"

        osc_range = osc_seq['range']
        osc_start = osc_seq['start']
        nb_images = osc_seq['number_of_images']

        first_imgno = osc_seq['start_image_number'] 
        first_image_fullpath = os.path.join(basedir,template % first_imgno)
        first_image_jpegpath = os.path.join(archive_dir, jpeg_template % first_imgno)
        first_image_thumbpath = os.path.join(archive_dir, thumb_template % first_imgno)

        last_imgno = first_imgno + nb_images -1
        last_image_fullpath = os.path.join(basedir,template % last_imgno)
        last_image_jpegpath = os.path.join(archive_dir, jpeg_template % last_imgno)
        last_image_thumbpath = os.path.join(archive_dir, thumb_template % last_imgno)

        # wait for first image
        self.adxv_latest_refresh = 0
        self.is_firstimg = True

        self.file_waiting_display = first_image_fullpath # for showing on adxv
        self.wait_image_on_disk(first_image_fullpath)
        thumbs_up = self.generate_thumbnails(first_image_fullpath, first_image_jpegpath, first_image_thumbpath)
        if thumbs_up:
            self.store_image_in_lims(first_imgno)

        # update display while collect is running
        while self.is_moving() or self.is_firstimg:
            self.adxv_show_latest(fileinfo)
            time.sleep(0.1)

        # wait for last image
        self.wait_image_on_disk(last_image_fullpath)
        thumbs_up = self.generate_thumbnails(last_image_fullpath, last_image_jpegpath, last_image_thumbpath)
        self.adxv_sync_image(first_image_fullpath)
        if thumbs_up:
            self.store_image_in_lims(last_imgno)

    def prepare_characterization(self):
        osc_seq = self.current_dc_parameters['oscillation_sequence'][0]
        fileinfo = self.current_dc_parameters['fileinfo']

        basedir = fileinfo['directory']

        merged_images = self.characterization_nb_merged_images 

        osc_range = float( osc_seq['range'] )/ merged_images
        exp_time = float( osc_seq['exposure_time'] )/ merged_images

        self.collect_device.numberOfImages = int(merged_images)
        self.collect_device.exposurePeriod = exp_time
        self.collect_device.imagePath = basedir
        self.collect_device.imageWidth = osc_range

        self.detector_hwobj.set_image_headers(["Angle_increment %.4f" % osc_range])

        return True

    def start_characterization(self):

        osc_seq = self.current_dc_parameters['oscillation_sequence'][0]
        fileinfo = self.current_dc_parameters['fileinfo']

        start_angle = osc_seq['start']
        nb_images = osc_seq['number_of_images']
        merged_images = self.characterization_nb_merged_images 
        wedge_range = osc_seq['range'] / merged_images

        image_template = fileinfo['template']

        oscil_image_template = image_template[:3] + '_wdg' + image_template[3:]

        start = start_angle

        self.emit("collectStarted", (self.owner, 1))

        for imgno in range(nb_images):
            image_filename = image_template % (imgno + 1)
            image_fullpath = os.path.join(fileinfo['directory'], image_filename)

            series_first_image = oscil_image_template % ((start-start_angle)/wedge_range + 1)
            series_last_image = oscil_image_template % ((start-start_angle)/wedge_range + merged_images)
            series_last_fullpath = os.path.join( fileinfo['directory'], series_last_image )

            logging.info("PX1Collect: start image series for angle %s - first image name is %s" % (start, series_first_image))

            self.collect_device.imageName = series_first_image
            self.collect_device.startAngle = start
            self.wait_collect_ready()
            self.collect_device.prepareCollect()
            self.wait_collect_ready()

            self.detector_hwobj.set_image_headers(["Start_angle %.4f" % start])
            self.collect_device.Start()

            # file names to wait for

            # wait for completion
            self.wait_collect_ready()
            logging.info("PX1Collect:   waiting to finish image series for angle %s - waiting for %s" % (start, series_last_fullpath))
            self.wait_image_on_disk(series_last_fullpath)
            self.adxv_sync_image(series_last_fullpath)

            # merge images into one image
            merge_images(series_first_image, image_filename, fileinfo['directory'],
                       start, osc_seq['range'], osc_seq['exposure_time'])

            logging.info("PX1Collect:   waiting for merged image to appear on disk %s - waiting for %s" % (start, image_fullpath))
            self.wait_image_on_disk(image_fullpath)
            self.adxv_sync_image(image_fullpath)

            start += 90.

    def data_collection_end(self):
        #
        # data collection end (or abort)
        #
        logging.getLogger("HWR").info("PX1Collect: finishing data collection ")
        self.omega_hwobj.stop()
        self.fastshut_hwobj.closeShutter()

        self.emit("progressStop")

    def data_collection_failed(self):
        logging.getLogger("HWR").info("PX1Collect: Data collection failed. recovering sequence should go here")

    def collect_finished(self, green):
        logging.info("PX1Collect: Data collection finished")

    def collect_failed(self, par):
        logging.exception("PX1Collect: Data collection failed")
        self.current_dc_parameters["status"] = 'failed'
        exc_type, exc_value, exc_tb = sys.exc_info()
        failed_msg = 'Data collection failed!\n%s' % exc_value
        self.emit("collectOscillationFailed", (self.owner, False, failed_msg,
           self.current_dc_parameters.get('collection_id'), 1))

        self.detector_hwobj.stop_collection()
        self.omega_hwobj.stop()
        self.data_collection_end()

    def set_helical_pos(self, arg):
        """
        Descript. : 8 floats describe
        p1AlignmY, p1AlignmZ, p1CentrX, p1CentrY
        p2AlignmY, p2AlignmZ, p2CentrX, p2CentrY
        """
        self.helical_positions = [arg["1"]["phiy"],  arg["1"]["phiz"],
                             arg["1"]["sampx"], arg["1"]["sampy"],
                             arg["2"]["phiy"],  arg["2"]["phiz"],
                             arg["2"]["sampx"], arg["2"]["sampy"]]

    def setMeshScanParameters(self, num_lines, num_images_per_line, mesh_range):
        """
        Descript. :
        """
        pass

    def trigger_auto_processing(self, *args):
        pass


    ## generate snapshots and data thumbnails ##
    @task
    def _take_crystal_snapshot(self, filename):
        """
        Descript. :
        """
        if not self.is_sampleview_phase():
            self.go_to_sampleview()
            time.sleep(2) # allow time to refresh display after

        self.lightarm_hwobj.adjustLightLevel() 
        time.sleep(0.3) # allow time to refresh display after

        self.graphics_manager_hwobj.save_scene_snapshot(filename)
        logging.getLogger("HWR").debug("PX1Collect:  - snapshot saved to %s" % filename)

    def generate_thumbnails(self, filename, jpeg_filename, thumbnail_filename):
        # 
        # write info on LIMS

        try:
            logging.info("PX1Collect: Generating thumbnails for %s" % filename)
            logging.info("PX1Collect:       jpeg file: %s" % jpeg_filename)
            logging.info("PX1Collect:  thumbnail file: %s" % thumbnail_filename)

            self.wait_image_on_disk(filename)
            if os.path.exists( filename ):
                subprocess.Popen([ self.img2jpeg, filename, jpeg_filename, '0.4' ])
                subprocess.Popen([ self.img2jpeg, filename, thumbnail_filename, '0.1' ])
                return True
            else:
                logging.info("PX1Collect: Oopps.  Trying to generate thumbs but  image is not on disk")
                return False
        except:
            import traceback
            logging.error("PX1Collect: Cannot generate thumbnails for %s" % filename)
            logging.error(traceback.format_exc())
            return False

    ## generate snapshots and data thumbnails (END) ##

    ## FILE SYSTEM ##
    def wait_image_on_disk(self, filename, timeout=20.0):
        start_wait = time.time()
        while not os.path.exists(filename):
            if time.time() - start_wait > timeout:
               logging.info("PX1Collect: Giving up waiting for image. Timeout")
               break
            time.sleep(0.1)
        logging.info("PX1Collect: Waiting for image %s ended in  %3.2f secs" % (filename, time.time()-start_wait))
        
    def check_directory(self, basedir):
        if not os.path.exists(basedir):
            try:
                os.makedirs(basedir)
            except OSError, e:
                if e.errno != errno.EEXIST:
                    raise
Ejemplo n.º 15
0
class PX1Energy(Device):

    energy_state = {
        "ALARM": "error",
        "FAULT": "error",
        "RUNNING": "moving",
        "MOVING": "moving",
        "STANDBY": "ready",
        "DISABLE": "error",
        "UNKNOWN": "unknown",
        "EXTRACT": "outlimits",
    }

    def init(self):

        self.moving = False

        self.doBacklashCompensation = False

        self.current_energy = None
        self.current_state = None

        try:
            self.monodevice = DeviceProxy(self.getProperty("mono_device"))
        except BaseException:
            self.errorDeviceInstance(self.getProperty("mono_device"))

        # Nom du device bivu (Energy to gap) : necessaire pour amelioration du
        # positionnement de l'onduleur (Backlash)
        self.und_device = DeviceProxy(self.getProperty("undulator_device"))
        self.doBacklashCompensation = self.getProperty("backlash")

        # parameters for polling
        self.isConnected()

        self.energy_chan = self.getChannelObject("energy")
        self.energy_chan.connectSignal("update", self.energyChanged)

        self.stop_cmd = self.getCommandObject("stop")

        self.state_chan = self.getChannelObject("state")
        self.state_chan.connectSignal("update", self.stateChanged)

    def connectNotify(self, signal):
        if signal == "energyChanged":
            logging.getLogger("HWR").debug(
                "PX1Energy. connectNotify. sending energy value %s" % self.get_energy()
            )
            self.energyChanged(self.get_energy())

        if signal == "stateChanged":
            logging.getLogger("HWR").debug(
                "PX1Energy. connectNotify. sending state value %s" % self.get_state()
            )
            self.stateChanged(self.get_state())

        self.setIsReady(True)

    def stateChanged(self, value):
        str_state = str(value)
        if str_state == "MOVING":
            self.moveEnergyCmdStarted()

        if self.current_state == "MOVING" or self.moving == True:
            if str_state != "MOVING":
                self.moveEnergyCmdFinished()

        self.current_state = str_state
        self.emit("stateChanged", self.energy_state[str_state])

    # function called during polling
    def energyChanged(self, value):

        if (
            self.current_energy is not None
            and abs(self.current_energy - value) < 0.0001
        ):
            return

        self.current_energy = value

        wav = self.getCurrentWavelength()
        if wav is not None:
            self.emit("energyChanged", (value, wav))

    def isSpecConnected(self):
        return True

    def isConnected(self):
        return True

    def sConnected(self):
        self.emit("connected", ())

    def sDisconnected(self):
        self.emit("disconnected", ())

    def isDisconnected(self):
        return True

    # Definit si la beamline est a energie fixe ou variable
    def can_move_energy(self):
        return True

    def getPosition(self):
        return self.getCurrentEnergy()

    def getCurrentEnergy(self):
        return self.get_energy()

    def get_energy(self):
        return self.energy_chan.getValue()

    def getState(self):
        return self.get_state()

    def get_state(self):
        return str(self.state_chan.getValue())

    def getEnergyComputedFromCurrentGap(self):
        return self.und_device.energy

    def getCurrentUndulatorGap(self):
        return self.und_device.gap

    def get_wavelength(self):
        return self.monodevice.read_attribute("lambda").value

    def getCurrentWavelength(self):
        return self.get_wavelength()

    def getLimits(self):
        return self.getEnergyLimits()

    def get_energy_limits(self):
        chan_info = self.energy_chan.getInfo()
        return (float(chan_info.min_value), float(chan_info.max_value))

    def get_wavelength_limits(self):
        energy_min, energy_max = self.getEnergyLimits()

        # max is min and min is max
        max_lambda = self.energy_to_lambda(energy_min)
        min_lambda = self.energy_to_lambda(energy_max)

        return (min_lambda, max_lambda)

    def energy_to_lambda(self, value):
        # conversion is done by mono device
        self.monodevice.simEnergy = value
        return self.monodevice.simLambda

    def lambda_to_energy(self, value):
        # conversion is done by mono device
        self.monodevice.simLambda = value
        return self.monodevice.simEnergy

    def move_energy(self, value, wait=False):
        value = float(value)

        backlash = 0.1  # en mm
        gaplimite = 5.5  # en mm

        if self.get_state() != "MOVING":
            if self.doBacklashCompensation:
                try:
                    # Recuperation de la valeur de gap correspondant a l'energie souhaitee
                    # self.und_device.autoApplyComputedParameters = False
                    self.und_device.energy = value
                    newgap = self.und_device.computedGap
                    actualgap = self.und_device.gap

                    #                    self.und_device.autoApplyComputedParameters = True

                    while str(self.und_device.State()) == "MOVING":
                        time.sleep(0.2)

                    # On applique le backlash que si on doit descendre en gap
                    if newgap < actualgap + backlash:
                        # Envoi a un gap juste en dessous (backlash)
                        if newgap - backlash > gaplimite:
                            self.und_device.gap = newgap - backlash
                            while str(self.und_device.State()) == "MOVING":
                                time.sleep(0.2)

                            self.energy_chan.setValue(value)
                        else:
                            self.und_device.gap = gaplimite
                            self.und_device.gap = newgap + backlash
                        time.sleep(1)
                except BaseException:
                    logging.getLogger("HWR").error(
                        "%s: Cannot move undulator U20 : State device = %s",
                        self.name(),
                        str(self.und_device.State()),
                    )

            try:
                self.energy_chan.setValue(value)
                return value
            except BaseException:
                logging.getLogger("HWR").error(
                    "%s: Cannot move Energy : State device = %s",
                    self.name(),
                    self.get_state(),
                )

        else:
            logging.getLogger("HWR").error(
                "%s: Cannot move Energy : State device = %s",
                self.name(),
                self.get_state(),
            )

    def move_wavelength(self, value, wait=False):
        egy_value = self.lambda_to_energy(float(value))
        logging.getLogger("HWR").debug(
            "%s: Moving wavelength to : %s (egy to %s" % (self.name(), value, egy_value)
        )
        self.move_energy(egy_value)
        return value

    def cancelMoveEnergy(self):
        self.stop_cmd()
        self.moving = False

    def energyLimitsChanged(self, limits):
        egy_min, egy_max = limits

        lambda_min = self.energy_to_lambda(egy_min)
        lambda_max = self.energy_to_lambda(egy_max)

        wav_limits = (lambda_min, lambda_max)

        self.emit("energyLimitsChanged", (limits,))

        if None not in wav_limits:
            self.emit("wavelengthLimitsChanged", (wav_limits,))
        else:
            self.emit("wavelengthLimitsChanged", (None,))

    def moveEnergyCmdReady(self):
        if not self.moving:
            self.emit("moveEnergyReady", (True,))

    def moveEnergyCmdNotReady(self):
        if not self.moving:
            self.emit("moveEnergyReady", (False,))

    def moveEnergyCmdStarted(self):
        self.moving = True
        self.emit("moveEnergyStarted", ())

    def moveEnergyCmdFailed(self):
        self.moving = False
        self.emit("moveEnergyFailed", ())

    def moveEnergyCmdAborted(self):
        self.moving = False

    def moveEnergyCmdFinished(self):
        self.moving = False
        self.emit("moveEnergyFinished", ())

    def getPreviousResolution(self):
        return (None, None)

    def restoreResolution(self):
        return (False, "Resolution motor not defined")

    getEnergyLimits = get_energy_limits
    getWavelengthLimits = get_wavelength_limits
    canMoveEnergy = can_move_energy
    startMoveEnergy = move_energy
    startMoveWavelength = move_wavelength
Ejemplo n.º 16
0
class PX1Collect(AbstractCollect, HardwareObject):
    """Main data collection class. Inherited from AbstractMulticollect
       Collection is done by setting collection parameters and
       executing collect command
    """

    adxv_host = "127.0.0.1"
    adxv_port = 8100
    adxv_interval = 2.0  # minimum time (in seconds) between image refresh on adxv

    goimg_dir = "/nfs/ruche/share-temp/Proxima/.goimgpx1"
    goimg_filename = "goimg.db"

    characterization_nb_merged_images = 10

    def __init__(self, name):
        """

        :param name: name of the object
        :type name: string
        """

        AbstractCollect.__init__(self)
        HardwareObject.__init__(self, name)

        self._error_msg = ""
        self.owner = None
        self.osc_id = None
        self._collecting = None

        self.mxlocal = None

        self.helical_positions = None

    def init(self):
        """
        Init method
        """

        self.collect_devname = self.getProperty("tangoname")
        self.collect_device = DeviceProxy(self.collect_devname)

        self.collect_state_chan = self.get_channel_object("state")

        self.px1env_hwobj = self.getObjectByRole("environment")

        self.frontend_hwobj = self.getObjectByRole("frontend")

        self.lightarm_hwobj = self.getObjectByRole("lightarm")

        self.mxlocal_object = self.getObjectByRole("beamline_configuration")

        self.img2jpeg = self.getProperty("imgtojpeg")
        undulators = self.get_undulators()

        self.exp_type_dict = {"Mesh": "raster", "Helical": "Helical"}

        det_px, det_py = HWR.beamline.detector.get_pixel_size()

        self.set_beamline_configuration(
            synchrotron_name="SOLEIL",
            directory_prefix=self.getProperty("directory_prefix"),
            default_exposure_time=HWR.beamline.detector.get_default_exposure_time(),
            minimum_exposure_time=HWR.beamline.detector.get_minimum_exposure_time(),
            detector_fileext=HWR.beamline.detector.get_file_suffix(),
            detector_type=HWR.beamline.detector.get_detector_type(),
            detector_manufacturer=HWR.beamline.detector.get_manufacturer(),
            detector_model=HWR.beamline.detector.get_model(),
            detector_px=det_px,
            detector_py=det_py,
            undulators=undulators,
            focusing_optic=self.getProperty("focusing_optic"),
            monochromator_type=self.getProperty("monochromator"),
            beam_divergence_vertical=HWR.beamline.beam.get_beam_divergence_hor(),
            beam_divergence_horizontal=HWR.beamline.beam.get_beam_divergence_ver(),
            polarisation=self.getProperty("polarisation"),
            input_files_server=self.getProperty("input_files_server"),
        )

        self.emit("collectConnected", (True,))
        self.emit("collectReady", (True,))

    def data_collection_hook(self):
        """Main collection hook
        """

        collection_type = self.current_dc_parameters["experiment_type"]

        logging.getLogger("HWR").info(
            "PX1Collect: Running PX1 data collection hook. Type is %s" % collection_type
        )

        if self.aborted_by_user:
            self.emit_collection_failed("Aborted by user")
            self.aborted_by_user = False
            return

        ready = self.prepare_devices_for_collection()

        if not ready:
            self.collection_failed("Cannot prepare collection")
            self.stop_collect()
            return

        if collection_type != "Characterization":  # standard
            prepare_ok = self.prepare_standard_collection()
        else:
            prepare_ok = self.prepare_characterization()

        self._collecting = True

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        # for progressBar brick
        self.emit("progressInit", "Collection", osc_seq["number_of_images"])

        #
        # Run
        #

        self.prepare_directories()

        if collection_type != "Characterization":  # standard
            self.start_standard_collection()
            self.follow_collection_progress()
        else:
            self.start_characterization()

        # includes

        self.data_collection_end()
        self.collection_finished()

    def prepare_standard_collection(self):

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]

        logging.getLogger("HWR").info("PX1Collect: fileinfo is %s " % str(fileinfo))
        imgname = fileinfo["template"] % osc_seq["start_image_number"]

        # move omega to start angle
        start_angle = osc_seq["start"]

        nb_images = osc_seq["number_of_images"]
        osc_range = osc_seq["range"]
        exp_time = osc_seq["exposure_time"]

        logging.getLogger("HWR").info(
            "PX1Collect:  nb_images: %s / osc_range: %s / exp_time: %s"
            % (nb_images, osc_range, exp_time)
        )

        self.collect_device.exposurePeriod = exp_time
        self.collect_device.numberOfImages = nb_images
        self.collect_device.imageWidth = osc_range

        # self.collect_device.collectAxis = "Omega"

        self.collect_device.startAngle = start_angle
        self.collect_device.triggerMode = 2

        self.collect_device.imagePath = basedir
        self.collect_device.imageName = imgname
        time.sleep(0.2)
        self.collect_device.PrepareCollect()
        ret = self.wait_collect_standby()
        if ret is False:
            logging.getLogger("user_level_log").info(
                "Collect server prepare error. Aborted"
            )
            return False

        self.prepare_headers()

        return True

    def start_standard_collection(self):
        self.emit("collectStarted", (self.owner, 1))
        HWR.beamline.detector.start_collection()
        self.collect_device.Start()

    def follow_collection_progress(self):

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]
        archive_dir = fileinfo["archive_directory"]
        template = fileinfo["template"]

        jpeg_template = os.path.splitext(template)[0] + ".jpeg"
        thumb_template = os.path.splitext(template)[0] + ".thumb.jpeg"

        osc_range = osc_seq["range"]
        osc_start = osc_seq["start"]
        nb_images = osc_seq["number_of_images"]

        first_imgno = osc_seq["start_image_number"]
        first_image_fullpath = os.path.join(basedir, template % first_imgno)
        first_image_jpegpath = os.path.join(archive_dir, jpeg_template % first_imgno)
        first_image_thumbpath = os.path.join(archive_dir, thumb_template % first_imgno)

        last_imgno = first_imgno + nb_images - 1
        last_image_fullpath = os.path.join(basedir, template % last_imgno)
        last_image_jpegpath = os.path.join(archive_dir, jpeg_template % last_imgno)
        last_image_thumbpath = os.path.join(archive_dir, thumb_template % last_imgno)

        # wait for first image
        self.adxv_latest_refresh = 0
        self.is_firstimg = True

        self.file_waiting_display = first_image_fullpath  # for showing on adxv
        self.wait_image_on_disk(first_image_fullpath)
        thumbs_up = self.generate_thumbnails(
            first_image_fullpath, first_image_jpegpath, first_image_thumbpath
        )
        if thumbs_up:
            self.store_image_in_lims(first_imgno)

        # update display while collect is running
        while self.is_moving() or self.is_firstimg:
            self.adxv_show_latest(fileinfo)
            time.sleep(0.1)

        # wait for last image
        self.wait_image_on_disk(last_image_fullpath)
        thumbs_up = self.generate_thumbnails(
            last_image_fullpath, last_image_jpegpath, last_image_thumbpath
        )
        self.adxv_sync_image(first_image_fullpath)
        if thumbs_up:
            self.store_image_in_lims(last_imgno)

    def prepare_characterization(self):
        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]

        basedir = fileinfo["directory"]

        merged_images = self.characterization_nb_merged_images

        osc_range = float(osc_seq["range"]) / merged_images
        exp_time = float(osc_seq["exposure_time"]) / merged_images

        self.collect_device.numberOfImages = int(merged_images)
        self.collect_device.exposurePeriod = exp_time
        self.collect_device.imagePath = basedir
        self.collect_device.imageWidth = osc_range

        HWR.beamline.detector.set_image_headers(["Angle_increment %.4f" % osc_range])

        return True

    def start_characterization(self):

        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]
        fileinfo = self.current_dc_parameters["fileinfo"]

        start_angle = osc_seq["start"]
        nb_images = osc_seq["number_of_images"]
        merged_images = self.characterization_nb_merged_images
        wedge_range = osc_seq["range"] / merged_images

        image_template = fileinfo["template"]

        oscil_image_template = image_template[:3] + "_wdg" + image_template[3:]

        start = start_angle

        self.emit("collectStarted", (self.owner, 1))

        for imgno in range(nb_images):
            image_filename = image_template % (imgno + 1)
            image_fullpath = os.path.join(fileinfo["directory"], image_filename)

            series_first_image = oscil_image_template % (
                (start - start_angle) / wedge_range + 1
            )
            series_last_image = oscil_image_template % (
                (start - start_angle) / wedge_range + merged_images
            )
            series_last_fullpath = os.path.join(
                fileinfo["directory"], series_last_image
            )

            logging.info(
                "PX1Collect: start image series for angle %s - first image name is %s"
                % (start, series_first_image)
            )

            self.collect_device.imageName = series_first_image
            self.collect_device.startAngle = start
            self.wait_collect_ready()
            self.collect_device.prepareCollect()
            self.wait_collect_ready()

            HWR.beamline.detector.set_image_headers(["Start_angle %.4f" % start])
            self.collect_device.Start()

            # file names to wait for

            # wait for completion
            self.wait_collect_ready()
            logging.info(
                "PX1Collect:   waiting to finish image series for angle %s - waiting for %s"
                % (start, series_last_fullpath)
            )
            self.wait_image_on_disk(series_last_fullpath)
            self.adxv_sync_image(series_last_fullpath)

            # merge images into one image
            merge_images(
                series_first_image,
                image_filename,
                fileinfo["directory"],
                start,
                osc_seq["range"],
                osc_seq["exposure_time"],
            )

            logging.info(
                "PX1Collect:   waiting for merged image to appear on disk %s - waiting for %s"
                % (start, image_fullpath)
            )
            self.wait_image_on_disk(image_fullpath)
            self.adxv_sync_image(image_fullpath)

            start += 90.0

    def data_collection_end(self):
        #
        # data collection end (or abort)
        #
        logging.getLogger("HWR").info("PX1Collect: finishing data collection ")
        HWR.beamline.diffractometer.omega.stop()
        HWR.beamline.fast_shutter.closeShutter()

        self.emit("progressStop")

    def data_collection_failed(self):
        logging.getLogger("HWR").info(
            "PX1Collect: Data collection failed. recovering sequence should go here"
        )

    def collect_finished(self, green):
        logging.info("PX1Collect: Data collection finished")

    def collect_failed(self, par):
        logging.exception("PX1Collect: Data collection failed")
        self.current_dc_parameters["status"] = "failed"
        exc_type, exc_value, exc_tb = sys.exc_info()
        failed_msg = "Data collection failed!\n%s" % exc_value
        self.emit(
            "collectOscillationFailed",
            (
                self.owner,
                False,
                failed_msg,
                self.current_dc_parameters.get("collection_id"),
                1,
            ),
        )

        HWR.beamline.detector.stop_collection()
        HWR.beamline.diffractometer.omega.stop()
        self.data_collection_end()

    def set_helical_pos(self, arg):
        """
        Descript. : 8 floats describe
        p1AlignmY, p1AlignmZ, p1CentrX, p1CentrY
        p2AlignmY, p2AlignmZ, p2CentrX, p2CentrY
        """
        self.helical_positions = [
            arg["1"]["phiy"],
            arg["1"]["phiz"],
            arg["1"]["sampx"],
            arg["1"]["sampy"],
            arg["2"]["phiy"],
            arg["2"]["phiz"],
            arg["2"]["sampx"],
            arg["2"]["sampy"],
        ]

    def setMeshScanParameters(self, num_lines, num_images_per_line, mesh_range):
        """
        Descript. :
        """
        pass

    def trigger_auto_processing(self, *args):
        pass

    ## generate snapshots and data thumbnails ##
    @task
    def _take_crystal_snapshot(self, filename):
        """
        Descript. :
        """
        if not self.is_sampleview_phase():
            self.go_to_sampleview()
            time.sleep(2)  # allow time to refresh display after

        self.lightarm_hwobj.adjustLightLevel()
        time.sleep(0.3)  # allow time to refresh display after

        HWR.beamline.sample_view.save_snapshot(filename)
        logging.getLogger("HWR").debug("PX1Collect:  - snapshot saved to %s" % filename)

    def generate_thumbnails(self, filename, jpeg_filename, thumbnail_filename):
        #
        # write info on LIMS

        try:
            logging.info("PX1Collect: Generating thumbnails for %s" % filename)
            logging.info("PX1Collect:       jpeg file: %s" % jpeg_filename)
            logging.info("PX1Collect:  thumbnail file: %s" % thumbnail_filename)

            self.wait_image_on_disk(filename)
            if os.path.exists(filename):
                subprocess.Popen([self.img2jpeg, filename, jpeg_filename, "0.4"])
                subprocess.Popen([self.img2jpeg, filename, thumbnail_filename, "0.1"])
                return True
            else:
                logging.info(
                    "PX1Collect: Oopps.  Trying to generate thumbs but  image is not on disk"
                )
                return False
        except BaseException:
            import traceback

            logging.error("PX1Collect: Cannot generate thumbnails for %s" % filename)
            logging.error(traceback.format_exc())
            return False

    ## generate snapshots and data thumbnails (END) ##

    ## FILE SYSTEM ##
    def wait_image_on_disk(self, filename, timeout=20.0):
        start_wait = time.time()
        while not os.path.exists(filename):
            if time.time() - start_wait > timeout:
                logging.info("PX1Collect: Giving up waiting for image. Timeout")
                break
            time.sleep(0.1)
        logging.info(
            "PX1Collect: Waiting for image %s ended in  %3.2f secs"
            % (filename, time.time() - start_wait)
        )

    def check_directory(self, basedir):
        if not os.path.exists(basedir):
            try:
                os.makedirs(basedir)
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise

    def prepare_directories(self):
        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]
        process_dir = basedir.replace("RAW_DATA", "PROCESSED_DATA")

        try:
            os.chmod(process_dir, 0o777)
        except BaseException:
            import traceback

            logging.getLogger("HWR").error(
                "PX1Collect: Error changing permissions for PROCESS directory"
            )
            logging.getLogger("HWR").error(traceback.format_exc())

        self.create_goimg_file(process_dir)

    def create_goimg_file(self, dirname):

        db_f = os.path.join(self.goimg_dir, self.goimg_filename)
        if os.path.exists(db_f):
            os.remove(db_f)

        with open(db_f, "w") as fd:
            fd.write(dirname)
        os.chmod(db_f, 0o777)

    def create_file_directories(self):
        """
        Method create directories for raw files and processing files.
        Directorie for xds.input and auto_processing are created
        """
        self.create_directories(
            self.current_dc_parameters["fileinfo"]["directory"],
            self.current_dc_parameters["fileinfo"]["process_directory"],
        )

        """create processing directories and img links"""
        xds_directory, auto_directory = self.prepare_input_files()
        try:
            # self.create_directories(xds_directory, auto_directory)
            # os.system("chmod -R 777 %s %s" % (xds_directory, auto_directory))
            """todo, create link of imgs for auto_processing
            try:
                os.symlink(files_directory, os.path.join(process_directory, "img"))
            except os.error, e:
                if e.errno != errno.EEXIST:
                    raise
            """
            pass
            # os.symlink(files_directory, os.path.join(process_directory, "img"))
        except BaseException:
            logging.exception("PX1Collect: Could not create processing file directory")
            return

        if xds_directory:
            self.current_dc_parameters["xds_dir"] = xds_directory

        if auto_directory:
            self.current_dc_parameters["auto_dir"] = auto_directory

    def prepare_input_files(self):
        """
        Descript. :
        """
        i = 1
        log = logging.getLogger("user_level_log")
        while True:
            xds_input_file_dirname = "xds_%s_%s_%d" % (
                self.current_dc_parameters["fileinfo"]["prefix"],
                self.current_dc_parameters["fileinfo"]["run_number"],
                i,
            )
            xds_directory = os.path.join(
                self.current_dc_parameters["fileinfo"]["process_directory"],
                xds_input_file_dirname,
            )
            if not os.path.exists(xds_directory):
                break
            i += 1
        self.current_dc_parameters["xds_dir"] = xds_directory

        mosflm_input_file_dirname = "mosflm_%s_run%s_%d" % (
            self.current_dc_parameters["fileinfo"]["prefix"],
            self.current_dc_parameters["fileinfo"]["run_number"],
            i,
        )
        mosflm_directory = os.path.join(
            self.current_dc_parameters["fileinfo"]["process_directory"],
            mosflm_input_file_dirname,
        )

        log.info("  - xds: %s / mosflm: %s" % (xds_directory, mosflm_directory))
        return xds_directory, mosflm_directory

    ## FILE SYSTEM (END) ##

    def prepare_devices_for_collection(self):

        fileinfo = self.current_dc_parameters["fileinfo"]
        basedir = fileinfo["directory"]

        self.check_directory(basedir)

        # check fast shutter closed. others opened
        shutok = self.check_shutters()
        shutok = True

        if not shutok:
            logging.getLogger("user_level_log").info(
                " Shutters not ready for collection. Aborted"
            )
            return False

        detok = HWR.beamline.detector.prepare_collection(self.current_dc_parameters)
        if not detok:
            logging.getLogger("user_level_log").info(
                "Cannot prepare detector for collection. Aborted"
            )
            return False

        adxv_ok = self.adxv_connect()

        diff_ok = self.diffractometer_prepare_collection()
        if not diff_ok:
            logging.getLogger("user_level_log").info(
                "Cannot prepare diffractometer for collection. Aborted"
            )
            return False

        return True

    def diffractometer_prepare_collection(self):
        HWR.beamline.diffractometer.wait_device_ready(timeout=10)

        # go to collect phase
        if not self.is_collect_phase():
            success = self.go_to_collect()
            if not success:
                logging.getLogger("HWR").info("PX1Collect: Cannot set COLLECT phase")
                return False
        return True

    def prepare_headers(self):
        osc_seq = self.current_dc_parameters["oscillation_sequence"][0]

        ax, ay, bx, by = self.get_beam_configuration()

        dist = HWR.beamline.detector.distance.get_value()
        wavlen = HWR.beamline.energy.get_wavelength()

        start_angle = osc_seq["start"]
        nb_images = osc_seq["number_of_images"]
        img_range = osc_seq["range"]
        exp_time = osc_seq["exposure_time"]

        kappa_angle = HWR.beamline.diffractometer.kappa.get_value()

        _settings = [
            ["Wavelength %.5f", wavlen],
            ["Detector_distance %.4f", dist / 1000.0],
            ["Beam_x %.2f", ax * dist + bx],
            ["Beam_y %.2f", ay * dist + by],
            ["Alpha %.2f", 49.64],
            ["Start_angle %.4f", start_angle],
            ["Angle_increment %.4f", img_range],
            ["Oscillation_axis %s", "Omega"],
            ["Detector_2theta %.4f", 0.0],
            ["Polarization %.3f", 0.990],
            ["Kappa %.4f", kappa_angle],
        ]

        # if self.oscaxis == "Phi":
        # _settings.append(["Chi %.4f", self.omega_hwo.get_value()])
        # _settings.append(["Phi %.4f", start])
        # elif self.oscaxis == "Omega":
        _settings.append(
            ["Phi %.4f", HWR.beamline.diffractometer.kappa_phi.get_value()]
        )
        _settings.append(["Chi %.4f", start_angle])
        HWR.beamline.detector.set_image_headers(_settings)

    def check_shutters(self):
        # Check safety shutter
        if self.check_shutter_opened(
            HWR.beamline.safety_shutter, "Safety shutter"
        ) and self.check_shutter_opened(self.frontend_hwobj, "Front end"):
            return True
        else:
            return False

    def check_shutter_opened(self, shut_hwo, shutter_name="shutter"):
        if shut_hwo.isShutterOpened():
            return True

        if shut_hwo.get_state() == "disabled":
            logging.getLogger("user_level_log").warning(
                "%s disabled. Collect cancelled" % shutter_name
            )
            return False
        elif shut_hwo.get_state() in ["fault", "alarm", "error"]:
            logging.getLogger("user_level_log").warning(
                "%s is in fault state. Collect cancelled" % shutter_name
            )
            return False
        elif shut_hwo.isShutterClosed():
            shut_hwo.openShutter()
            return shut_hwo.waitShutter("opened")
        else:
            logging.getLogger("user_level_log").warning(
                "%s is in an unhandled state. Collect cancelled" % shutter_name
            )
            return False

    def close_fast_shutter(self):
        HWR.beamline.fast_shutter.closeShutter()

    def close_safety_shutter(self):
        pass

    ## COLLECT SERVER STATE ##
    def wait_collect_standby(self, timeout=10):
        t0 = time.time()
        while not self.is_standby():
            elapsed = time.time() - t0
            if elapsed > timeout:
                break
            time.sleep(0.1)

    def wait_collect_moving(self, timeout=10):
        t0 = time.time()
        while not self.is_moving():
            elapsed = time.time() - t0
            if elapsed > timeout:
                break
            time.sleep(0.1)

    def wait_collect_ready(self, timeout=10):
        t0 = time.time()
        while self.is_moving():
            elapsed = time.time() - t0
            if elapsed > timeout:
                break
            time.sleep(0.1)

    def is_standby(self):
        return str(self.collect_state_chan.getValue()) == "STANDBY"

    def is_moving(self):
        return str(self.collect_state_chan.getValue()) in ["MOVING", "RUNNING"]

    ## COLLECT SERVER STATE (END) ##

    ## PX1 ENVIRONMENT PHASE HANDLING ##
    def is_collect_phase(self):
        return self.px1env_hwobj.isPhaseCollect()

    def go_to_collect(self, timeout=180):
        self.px1env_hwobj.gotoCollectPhase()
        gevent.sleep(0.5)

        t0 = time.time()
        while True:
            env_state = self.px1env_hwobj.get_state()
            if env_state != "RUNNING" and self.is_collect_phase():
                break
            if time.time() - t0 > timeout:
                logging.getLogger("HWR").debug(
                    "PX1Collect: timeout sending supervisor to collect phase"
                )
                break
            gevent.sleep(0.5)

        return self.px1env_hwobj.isPhaseCollect()

    def is_sampleview_phase(self):
        return self.px1env_hwobj.isPhaseVisuSample()

    def go_to_sampleview(self, timeout=180):
        self.px1env_hwobj.gotoSampleViewPhase()

        gevent.sleep(0.5)

        t0 = time.time()
        while True:
            env_state = self.px1env_hwobj.get_state()
            if env_state != "RUNNING" and self.is_sampleview_phase():
                break
            if time.time() - t0 > timeout:
                logging.getLogger("HWR").debug(
                    "PX1Collect: timeout sending supervisor to sample view phase"
                )
                break
            gevent.sleep(0.5)

        self.lightarm_hwobj.adjustLightLevel()
        return self.is_sampleview_phase()

    ## PX1 ENVIRONMENT PHASE HANDLING (END) ##


    @task
    def move_motors(self, motor_position_dict):
        """
        Descript. :
        """
        HWR.beamline.diffractometer.move_motors(motor_position_dict)

    def get_undulators_gaps(self):
        """
        Descript. : return gaps as dict. In our case we have one gap,
                    others are 0
        """
        if HWR.beamline.energy:
            try:
                u20_gap = HWR.beamline.energy.getCurrentUndulatorGap()
                return {"u20": u20_gap}
            except BaseException:
                return {}
        else:
            return {}

    def get_slit_gaps(self):
        """
        Descript. :
        """
        if HWR.beamline.beam is not None:
            return HWR.beamline.beam.get_slits_gap()
        return None, None

    def get_beam_shape(self):
        """
        Descript. :
        """
        if HWR.beamline.beam is not None:
            return HWR.beamline.beam.get_beam_shape()

    def get_machine_current(self):
        """
        Descript. :
        """
        if HWR.beamline.machine_info:
            return HWR.beamline.machine_info.get_current()
        else:
            return 0

    def get_machine_message(self):
        """
        Descript. :
        """
        if HWR.beamline.machine_info:
            return HWR.beamline.machine_info.get_message()
        else:
            return ""

    def get_machine_fill_mode(self):
        """
        Descript. :
        """
        if HWR.beamline.machine_info:
            return HWR.beamline.machine_info.get_fill_mode()
        else:
            return ""

    def get_beam_configuration(self):
        pars_beam = self.mxlocal_object["SPEC_PARS"]["beam"]
        ax = pars_beam.getProperty("ax")
        ay = pars_beam.getProperty("ay")
        bx = pars_beam.getProperty("bx")
        by = pars_beam.getProperty("by")
        return [ax, ay, bx, by]

    def get_undulators(self):
        return [U20()]

    ## OTHER HARDWARE OBJECTS (END) ##

    ## ADXV display images ##
    def adxv_connect(self):

        #  connect every time?? maybe we can do better
        try:
            res = socket.getaddrinfo(
                self.adxv_host, self.adxv_port, 0, socket.SOCK_STREAM
            )
            af, socktype, proto, canonname, sa = res[0]
            self.adxv_socket = socket.socket(af, socktype, proto)
            self.adxv_socket.connect((self.adxv_host, self.adxv_port))
            logging.getLogger().info("PX1Collect: ADXV Visualization connected.")
        except BaseException:
            self.adxv_socket = None
            logging.getLogger().info("PX1Collect: WARNING: Can't connect to ADXV.")

    def adxv_show_latest(self, fileinfo):

        now = time.time()
        elapsed = now - self.adxv_latest_refresh

        template = fileinfo["template"]
        basedir = fileinfo["directory"]

        if self.file_waiting_display is not None:
            if os.path.exists(self.file_waiting_display):
                self.adxv_sync_image(self.file_waiting_display)
                self.file_waiting_display = None
                self.is_firstimg = False

        # find next file to display
        if elapsed >= self.adxv_interval and self.file_waiting_display is None:
            _current_img_no = self.collect_device.currentImageSpi
            self.file_waiting_display = os.path.join(
                basedir, template % _current_img_no
            )
            self.adxv_last_refresh = time.time()

    def adxv_sync_image(self, filename):

        adxv_send_cmd = "\nload_image %s\n" + chr(32)

        try:
            if not self.adxv_socket:
                try:
                    self.adxv_connect()
                except Exception as err:
                    self.adxv_socket = None
                    logging.info(
                        "PX1Collect: ADXV: Warning: Can't connect to adxv socket to follow collect."
                    )
                    logging.error("PX1Collect: ADXV0: msg= %s" % err)
            else:
                logging.info(("PX1Collect: ADXV: " + adxv_send_cmd[1:-2]) % imgname)
                self.adxv_socket.send(adxv_send_cmd % imgname)
        except BaseException:
            try:
                del self.adxv_socket
                self.adxv_connect()
            except Exception as err:
                self.adxv_socket = None
                logging.error("PX1Collect: ADXV1: msg= %s" % err)