예제 #1
0
    class Count(object):
        """X-ray detector tigger input high?"""
        # Was unable to use XPP:R31:EVR:21:EVENT1CNT.
        # Count was not counting up. F. Schotte, 26 Nov 2013
        # Silke recommeded to use XPP:IPM:EVR:EVENT1CNT instead.
        count_PV = PV("XPP:IPM:EVR:EVENT1CNT")
        event_code_PV = PV("XPP:IPM:EVR:EVENT1CTRL.ENM")
        enabled_PV = PV("XPP:IPM:EVR:EVENT1CTRL.VME")
        name_PV = PV("XPP:IPM:EVR:EVENT1NAME")
        offset = 0

        def setup(self):
            self.event_code_PV.value = 92
            self.enabled_PV.value = 1
            self.name_PV.value = "Sample Translation"

        def get_value(self):
            return int(self.count_PV.value) + self.offset

        def set_value(self, value):
            # "caput" does not change the count value.
            # Using a user-defined offset instead.
            self.offset = value - self.value
            ##self.count_PV.value = value

        value = property(get_value, set_value)
예제 #2
0
class Pulses(object):
    """Number of pulses per acquisition"""
    mode_PV = PV("ECS:SYS0:3:PLYMOD")  # 0=Once,1=N times,2=Forever
    target_count_PV = PV("ECS:SYS0:3:REPCNT")
    run_PV = PV("ECS:SYS0:3:PLYCTL")
    count_PV = PV("ECS:SYS0:3:PLYCNT")  # counting up to target count

    doc = "When read return the number of pulses remaining until the burst"\
        "ends. When set trigger a burst with the given number of pulses."

    def get_value(self):
        """Number of pulses remaining until the burst ends"""
        # PV is counting up from zero to count_PV
        count = toint(self.target_count_PV.value) - toint(self.count_PV.value)
        return count

    def set_value(self, count):
        if count > 0:
            if self.mode_PV.value != 1:
                self.mode_PV.value = 1  # Repeat N Times
            if self.target_count_PV.value != count:
                self.target_count_PV.value = count
            self.run_PV.value = 1
        if count == 0:
            self.run_PV.value = 0

    value = property(get_value, set_value, doc=doc)
예제 #3
0
    class Count(object):
        """X-ray detector tigger input high?"""
        # Was unable to use XPP:R31:EVR:21:EVENT3CNT.
        # Count was not counting up. F. Schotte, 1 Dec 2013
        # Using XPP:IPM:EVR:EVENT2CNT instead.
        count_PV = PV("XPP:IPM:EVR:EVENT2CNT")
        event_code_PV = PV("XPP:IPM:EVR:EVENT2CTRL.ENM")
        enabled_PV = PV("XPP:IPM:EVR:EVENT2CTRL.VME")
        name_PV = PV("XPP:IPM:EVR:EVENT2NAME")
        offset = 0

        def setup(self):
            self.event_code_PV.value = 94
            self.enabled_PV.value = 1
            self.name_PV.value = "X-ray area detector"

        def get_value(self):
            return toint(self.count_PV.value) + self.offset

        def set_value(self, value):
            # "caput" does not change the count value.
            # Using a user-defined offset instead.
            self.offset = value - self.value
            ##self.count_PV.value = value

        value = property(get_value, set_value)
예제 #4
0
class TriggerActive(object):
    status_PV = PV("ECS:SYS0:3:PLSTAT")  # 0: Stopped, 1:Playing
    control_PV = PV("ECS:SYS0:3:PLYCTL")  # 0: Stop, 1:Start

    def get_value(self):
        return self.status_PV.value != 0

    def set_value(self, value):
        self.control_PV.value = 1 if value else 0

    value = property(get_value, set_value)
예제 #5
0
    class TriggerLevel(object):
        """X-ray detector tigger input high?"""
        polarity_PV = PV("XPP:R31:EVR:21:CTRL.DG1P")

        def get_value(self):
            return self.polarity_PV.value == 1

        def set_value(self, value):
            self.polarity_PV.value = 1 if value else 0

        value = property(get_value, set_value)
예제 #6
0
class XRayShutterEnabled(object):
    """X-ray shutter trigger enabled?"""
    enabled_PV = PV("XPP:R32:EVR:32:EVENT1CTRL.ENAB")

    def get_value(self):
        return self.enabled_PV.value

    def set_value(self, value):
        self.enabled_PV.value = 1 if value else 0

    value = property(get_value, set_value)
예제 #7
0
class ContinuousTrigger(object):
    """Is continuous triggering enabled?"""
    mode_PV = PV("ECS:SYS0:3:PLYMOD")
    run_PV = PV("ECS:SYS0:3:PLYCTL")

    def get_value(self):
        """Is continuous triggering enabled?"""
        return self.mode_PV.value == 2 and self.run_PV.value == 1

    def set_value(self, value):
        if bool(value) == True:
            if self.mode_PV.value != 2:
                self.mode_PV.value = 2  # Repeat Forever
            self.run_PV.value = 1
        else:
            self.run_PV.value = 0

    value = property(get_value, set_value)

    def __repr__(self):
        return self.PV.name
예제 #8
0
class XRayAttenuatorInserted(object):
    """X-ray shutter trigger enabled?"""
    polarity_PV = PV("XPP:R32:EVR:32:CTRL.DG2P")

    def get_value(self):
        level_OK = self.polarity_PV.value == 1
        active = xray_attenuator_enabled.value and trigger_active.value
        return level_OK and not active

    def set_value(self, value):
        self.polarity_PV.value = 1 if value else 0

    value = property(get_value, set_value)
예제 #9
0
class Laue_Crystallography(object):
    """Serial Laue crystallography"""
    from persistent_property import persistent_property
    from action_property import action_property
    # instumentation
    from image_scan import image_scan
    from cavro_centris_syringe_pump_IOC import volume, port  # volume[0],...,volume[3]
    mother_liquor = volume[0]
    mother_liquor_dV = persistent_property("mother_liquor_dV", 10)
    crystal_liquor = volume[2]
    crystal_liquor_dV = persistent_property("crystal_liquor_dV", 10)
    from cavro_centris_syringe_pump import PumpController
    pump = p = PumpController()
    from cavro_centris_syringe_pump import S_flow, S_load, S_flowIM
    from CA import PV
    upstream_pressure = PV("NIH:DI245.56671FE403.CH1.pressure")
    downstream_pressure = PV("NIH:DI245.56671FE403.CH3.pressure")
    from instrumentation import microscope_camera as camera

    from instrumentation import DetZ
    det_inserted_pos = 185.8
    det_retracted_pos = 485.8

    def get_det_inserted(self):
        from numpy import isnan, nan
        value = abs(self.DetZ.value-self.det_inserted_pos) < 0.001\
            if not isnan(self.DetZ.value) else nan
        return value

    def set_det_inserted(self, value):
        if value: self.DetZ.command_value = self.det_inserted_pos
        else: self.DetZ.moving = False

    det_inserted = property(get_det_inserted, set_det_inserted)

    def get_det_retracted(self):
        from numpy import isnan, nan
        value = abs(self.DetZ.value-self.det_retracted_pos) < 0.001\
            if not isnan(self.DetZ.value) else nan
        return value

    def set_det_retracted(self, value):
        if value: self.DetZ.command_value = self.det_retracted_pos
        else: self.DetZ.moving = False

    det_retracted = property(get_det_retracted, set_det_retracted)

    def get_stage_enabled(self):
        from instrumentation import SampleX, SampleY, SampleZ
        return SampleX.enabled * SampleY.enabled * SampleZ.enabled

    def set_stage_enabled(self, value):
        from instrumentation import SampleX, SampleY, SampleZ
        SampleX.enabled, SampleY.enabled, SampleZ.enabled = True, True, True

    stage_enabled = property(get_stage_enabled, get_stage_enabled)

    @property
    def stage_online(self):
        from instrumentation import ensemble
        return ensemble.connected

    def get_centered(self):
        return self.image_scan.position == self.image_scan.center

    def set_centered(self, value):
        if value: self.image_scan.position = self.image_scan.center

    centered = property(get_centered, set_centered)

    def define_center(self):
        self.image_scan.center = self.image_scan.position

    inserted = centered

    @property
    def retracted_position(self):
        x, y, z = self.image_scan.center
        return x, y + 11, z

    def get_retracted(self):
        return self.image_scan.position == self.retracted_position

    def set_retracted(self, value):
        if value: self.image_scan.position = self.retracted_position

    retracted = property(get_retracted, set_retracted)

    scanning = action_property("self.image_scan.acquire()",
                               stop="self.image_scan.cancelled = True")

    @property
    def crystal_coordinates(self):
        """X,Y,Z in mm as formatted text"""
        XYZ = self.image_scan.crystal_XYZ
        lines = "\n".join(["%+.3f,%+.3f,%+.3f" % tuple(xyz) for xyz in XYZ.T])
        return lines

    @property
    def pump_online(self):
        from numpy import isnan
        return not isnan(self.volume[0].value)

    def init(self):
        """Home all motors"""
        self.p.init()

    def get_flowing(self):
        return self.mother_liquor.moving and \
            self.mother_liquor.speed == self.S_flow

    def set_flowing(self, value):
        if value: self.p.flow()
        else: self.p.abort()

    flowing = property(get_flowing, set_flowing)

    def inject(self):
        """Load crystals"""
        self.inject_count += 1
        self.p.inject()

    inject_count = persistent_property("inject_count", 0)

    def get_injecting(self):
        return self.mother_liquor.moving \
            and self.mother_liquor.speed == self.S_flowIM

    def set_injecting(self, value):
        if value:
            self.inject_count += 1
            self.p.inject()
        else:
            self.p.abort()

    injecting = property(get_injecting, set_injecting)

    def get_mother_liquor_refilling(self):
        return self.mother_liquor.moving \
            and self.mother_liquor.speed == self.S_load

    def set_mother_liquor_refilling(self, value):
        if value: self.p.refill_1()
        else: self.p.abort()

    mother_liquor_refilling = property(get_mother_liquor_refilling,
                                       set_mother_liquor_refilling)

    def get_crystal_liquor_refilling(self):
        return self.crystal_liquor.moving \
            and self.crystal_liquor.speed == self.S_load

    def set_crystal_liquor_refilling(self, value):
        if value:
            self.inject_count = 0
            self.p.refill_3()
        else:
            self.p.abort()

    crystal_liquor_refilling = property(get_crystal_liquor_refilling,
                                        set_crystal_liquor_refilling)

    image_rootname = persistent_property("image_rootname", "")

    def save_image(self):
        """Record photo"""
        from os.path import dirname
        directory = dirname(self.image_scan.directory)
        filename = "%s/%s.jpg" % (directory, self.image_rootname)
        self.camera.save_image(filename)
예제 #10
0
"""This tells the number of seconds to the next top-up.
This is needed to decide whether it is necessary to postpone the next image
until after the next top-up, to avoid collecting data during a top-up. """
__version__ = "1.0"
from CA import PV

time_to_next_refill = PV("Mt:TopUpTime2Inject")
"""
This is to log the tempeature of the
ILX Lightwave LDT-5948 Precision Temperature Controller
Friedrich Schotte, APS, 4 Dec 2009
"""

from temperature_controller import temperature_controller
from CA import PV
from scan import timescan

temperature = temperature_controller.temperature
power = temperature_controller.power
chillerT = PV("14Keithley1:DMM1Ch3_raw.VAL")

logfile = "//id14bxf/data/anfinrud_1004/Scans/2010.04.14-01 Temperature.log"
##logfile = None
timescan([temperature,power,chillerT],waiting_time=1,logfile=logfile)
class XrayAttenuator(object):
    motors = [motor("XPP:SB2:MMS:%d" % i) for i in range(26, 16, -1)]
    for motor in motors:
        motor.readback_slop = 0.075
    thicknesses = [0.020 * 2**i for i in range(0, len(motors))]
    outpos = [0] * len(motors)
    inpos = [20] * len(motors)
    inpos[3] = 19  # Filter #4 is damaged at position 20 mm.

    photon_energy_PV = PV("SIOC:SYS0:ML00:AO627")  # in eV
    """Variable Si X-ray attenuator of XPP hutch"""
    def get_transmission(self):
        from numpy import exp
        x = self.pathlength
        E = self.photon_energy
        return exp(-float(Si_mu(E)) * x)

    def set_transmission(self, T):
        from numpy import log
        E = self.photon_energy
        x = -log(T) / float(Si_mu(E))
        self.pathlength = x

    transmission = property(get_transmission, set_transmission)
    value = transmission

    def get_photon_energy(self):
        "Photon energy in eV"
        return self.photon_energy_PV.value

    photon_energy = property(get_photon_energy)

    def get_pathlength(self):
        "Thickness of silicon the X-ray beam passes through"
        pathlength = 0
        inserted = self.inserted
        for i in range(0, len(self.motors)):
            if inserted[i]: pathlength += self.thicknesses[i]
        return pathlength

    def set_pathlength(self, pathlength):
        from numpy import rint
        pathlength = min(pathlength, sum(self.thicknesses))
        steps = int(rint(pathlength / min(self.thicknesses)))
        insert = [(steps & 2**i != 0) for i in range(0, len(self.motors))]
        self.inserted = insert

    pathlength = property(get_pathlength, set_pathlength)

    def get_inserted(self):
        "True of False for each abosrber, list of 10"
        positions = self.positions
        return [
            abs(positions[i] - self.inpos[i]) <
            abs(positions[i] - self.outpos[i])
            for i in range(0, len(self.motors))
        ]

    def set_inserted(self, insert):
        "Inserted: list of booleans, one for each absorber"
        positions = [
            self.inpos[i] if insert[i] else self.outpos[i]
            for i in range(0, len(self.motors))
        ]
        self.positions = positions

    inserted = property(get_inserted, set_inserted)

    def get_positions(self):
        "Position for each absorber, list of 10"
        return [self.motors[i].value for i in range(0, len(self.motors))]

    def set_positions(self, positions):
        "Inserted: list of positions, one for each absorber"
        for i in range(0, len(self.motors)):
            self.motors[i].value = positions[i]

    positions = property(get_positions, set_positions)

    def get_moving(self):
        """Is any of the absorbers moving?"""
        return any(motor.moving for motor in self.motors)

    def set_moving(self, moving):
        """If moving = False, stop all motors."""
        for motor in self.motors:
            motor.moving = moving

    moving = property(get_moving, set_moving)

    def stop(self):
        """Stop all motors."""
        for motor in self.motors:
            motor.stop()
예제 #13
0
class EventSequencer(object):
    """Trigger generator"""
    stop_at_step = PV("ECS:SYS0:3:LEN")
    event_code = PV("ECS:SYS0:3:SEQ.A")
    delta_beam = PV("ECS:SYS0:3:SEQ.B")
    fiducial_delays = PV("ECS:SYS0:3:SEQ.C")
    burst_count = PV("ECS:SYS0:3:SEQ.D")
    process = PV("ECS:SYS0:3:SEQ.PROC")
    base_rate = PV("EVNT:SYS0:1:LCLSBEAMRATE")

    events = []

    def clear(self):
        self.events = []

    def add_event(self, time_mark, event_code):
        for i in range(len(self.events), time_mark + 1):
            self.events += [[]]
        if not event_code in self.events[time_mark]:
            self.events[time_mark] += [event_code]

    def add_burst(self, start_time_mark, end_time_mark, event_code):
        """start_time_mark: first
        end_time_mark: not included"""
        for i in range(start_time_mark, end_time_mark):
            self.add_event(i, event_code)

    def update(self):
        event_code = []
        delta_beam = []
        last_time_mark = 0
        for i in range(0, len(self.events)):
            event_group = self.events[i]
            if len(event_group) == 0: continue
            event_code += event_group
            delta_beam += [i - last_time_mark]
            delta_beam += [0] * (len(event_group) - 1)
            last_time_mark = i
        assert len(event_code) == len(delta_beam)
        n = len(event_code)
        self.stop_at_step.value = n
        self.event_code.value = event_code + [0] * (2048 - n)
        self.delta_beam.value = delta_beam + [0] * (2048 - n)
        self.fiducial_delays.value = [0] * 2048
        self.burst_count.value = [0] * 2048
        # Add labels to MEDM screen
        event_code += [0] * (20 - len(event_code))
        for i in range(0, 20):
            caput("XPP:ECS:IOC:01:EC_3:%02d.DESC" % i,
                  event_code_name(event_code[i]))
        sleep(0.1)  # needed
        self.process.value = 1
        sleep(0.2)  # needed
        self.process.value = 1  # needed

    @property
    def sequence_length(self):
        """interger value in multiples of 120-Hz cycles"""
        n = self.stop_at_step.value
        delta_beam = self.delta_beam.value
        sequence_length = sum(delta_beam[0:n])
        return sequence_length

    @property
    def period(self):
        """Repetion time in seconds"""
        rate = tofloat(self.base_rate.value)
        if rate == 0: return nan
        period = self.sequence_length / rate
        return period

    def single_shot_setup(self):
        self.clear()
        self.add_burst(0, 1, 90)  # X-ray shutter
        self.add_burst(2, 3, 92)  # Sample translation
        self.add_burst(2, 3, 94)  # X-ray detector
        self.add_burst(1, 2, 95)  # Data Acquisition
        self.add_event(0, 96)  # Timing tool reference
        self.add_event(13, 0)  # add delay and the end for the rep rate
        self.update()
        event_receiver_setup()

    def collection_setup(self):
        self.clear()
        self.add_burst(1, 11, 90)  # X-ray shutter
        self.add_burst(14, 15, 90)  # X-ray shutter
        self.add_burst(1, 11, 91)  # X-ray attenuator
        self.add_burst(2, 3, 92)  # Sample translation
        self.add_burst(15, 16, 92)  # Sample translation
        self.add_burst(14, 15, 93)  # Laser shutter
        self.add_burst(12, 13, 94)  # X-ray detector
        self.add_burst(25, 26, 94)  # X-ray detector
        self.add_burst(1, 13, 95)  # Data Acquisition (X-ray shutter+1)
        self.add_burst(25, 26, 95)  # Data Acquisition (X-ray shutter+1)
        self.add_event(26, 0)  # add delay and the end for the rep rate
        self.update()
        event_receiver_setup()

    def alignment_setup(self):
        self.clear()
        self.add_burst(2, 12, 90)  # X-ray shutter
        self.add_burst(2, 12, 91)  # X-ray attenuator
        self.add_burst(13, 14, 92)  # Sample translation
        self.add_burst(13, 14, 94)  # X-ray detector
        self.add_burst(3, 13, 95)  # Data Acquisition (X-ray shutter+1)
        self.add_burst(0, 1, 95)  # Data Acquisition (X-ray shutter+1)
        self.add_event(12, 0)  # add delay and the end for the rep rate
        ##self.add_event(120,0)   # for debugging, slow down to 1 Hz
        self.update()
        event_receiver_setup()

    def test_setup(self):
        self.clear()
        self.add_event(0, 90)
        self.add_event(0, 91)
        self.add_event(0, 92)
        self.add_event(0, 93)
        self.add_event(0, 94)
        self.add_event(24, 0)
        self.update()
예제 #14
0
 def PV_object(self):
     from CA import PV
     return PV(self.prefix + name)
예제 #15
0
class XraySafetyShuttersEnabled(object):
    def __init__(self,PV_name):
        self.PV_name = PV_name

    def get_value(self):
        from CA import caget
        value = caget(self.PV_name)
        from numpy import nan
        if value is None: value = nan
        return value
    value = property(get_value)

xray_safety_shutters_enabled = XraySafetyShuttersEnabled("ACIS:ShutterPermit.VAL")

ID14A_shutter_auto_open = PV("14IDA:shutter_auto_enable1.VAL")
ID14C_shutter_auto_open = PV("14IDA:shutter_auto_enable2.VAL")

class XraySafetyShuttersAutoOpen(object):
    def get_value(self):
        return ID14A_shutter_auto_open.value and ID14C_shutter_auto_open.value
    def set_value(self,value):
        if value:
            ID14A_shutter_auto_open.value = True
            ID14C_shutter_auto_open.value = True
        else:
            ID14A_shutter_auto_open.value = False
            ID14C_shutter_auto_open.value = False
    value = property(get_value,set_value)

xray_safety_shutters_auto_open = XraySafetyShuttersAutoOpen()