Skip to content

Lens

lens

Basic Lens object handling

Attributes

LENS_MOTOR_PVS module-attribute

LENS_MOTOR_PVS = {2: {'x': 'MFX:TFS:MMS:03', 'y': 'MFX:TFS:MMS:04'}, 3: {'x': 'MFX:TFS:MMS:05', 'y': 'MFX:TFS:MMS:06'}, 4: {'x': 'MFX:TFS:MMS:07', 'y': 'MFX:TFS:MMS:08'}, 5: {'x': 'MFX:TFS:MMS:09', 'y': 'MFX:TFS:MMS:10'}, 6: {'x': 'MFX:TFS:MMS:11', 'y': 'MFX:TFS:MMS:12'}, 7: {'x': 'MFX:TFS:MMS:13', 'y': 'MFX:TFS:MMS:14'}, 8: {'x': 'MFX:TFS:MMS:15', 'y': 'MFX:TFS:MMS:16'}, 9: {'x': 'MFX:TFS:MMS:17', 'y': 'MFX:TFS:MMS:18'}, 10: {'x': 'MFX:TFS:MMS:19', 'y': 'MFX:TFS:MMS:20'}}

logger module-attribute

logger = getLogger(__name__)

Classes

LensCalcMixin

LensCalcMixin(*args, **kwargs)

Mixin class to abstract focal length calculation from a variety of lens devices.

Relies on the following methods / attributes from the child class: - self.radius - self.z

Source code in tfs/lens.py
def __init__(self, *args, **kwargs):
    """
    Mixin class to abstract focal length calculation from a variety of 
    lens devices.

    Relies on the following methods / attributes from the child class:
    - self.radius
    - self.z
    """
    return
Functions
focus
focus(energy)
Source code in tfs/lens.py
def focus(self, energy):
    return ut.focal_length(self.radius, energy)
image_from_obj
image_from_obj(z_obj, energy)

Method calculates the image distance in meters along the beam pipeline from a point of origin given the focal length of the lens, location of lens, and location of object.

Parameters:

Name Type Description Default
z_obj

Location of object along the beamline in meters (m)

required

Returns:

Type Description
image

Returns the distance z_im of the image along the beam pipeline from a point of origin in meters (m)

Note

If the location of the object (z_obj) is equal to the focal length of the lens, this function will return infinity.

Source code in tfs/lens.py
def image_from_obj(self, z_obj, energy):
    """
    Method calculates the image distance in meters along the beam pipeline
    from a point of origin given the focal length of the lens, location of
    lens, and location of object.

    Parameters
    ----------
    z_obj
        Location of object along the beamline in meters (m)

    Returns
    -------
    image
        Returns the distance z_im of the image along the beam pipeline from
        a point of origin in meters (m)
    Note
    ----
    If the location of the object (z_obj) is equal to the focal length of
    the lens, this function will return infinity.
    """
    # Find the object location for the lens
    obj = self.z - z_obj
    # Check if the lens object is at the focal length
    # If this happens, then the image location will be infinity.
    # Note, this should not effect the recursive calculations that occur
    # later in the code
    if obj == self.focus(energy):
        return np.inf
    # Calculate the location of the focal plane
    plane = 1/(1/self.focus(energy) - 1/obj)
    # Find the position in accelerator coordinates
    return plane + self.z

LensConnect

LensConnect(*args)

Data structure for a basic system of lenses

Parameters:

Name Type Description Default
args Lens

Lens objects

()

Parameters:

Name Type Description Default
args

Variable length argument list of the lenses in the system, their radii, z position, and focal length.

()
Source code in tfs/lens.py
def __init__(self, *args):
    """
    Parameters
    ----------
    args
        Variable length argument list of the lenses in the system, their
        radii, z position, and focal length.
    """
    self.lenses = sorted(args, key=lambda lens: lens.z)
Attributes
effective_radius property
effective_radius

Method calculates the effective radius of the lens array including prefocusing lens

Returns:

Type Description
float

returns the effective radius of the lens array.

lenses instance-attribute
lenses = sorted(args, key=lambda lens: z)
nlens property
nlens

Method calculates the total number of lenses in the Lens array.

Returns:

Type Description
int

Returns the total number of lenses in the array.

tfs_radius property
tfs_radius

Method calculates the effective radius of the lens array excluding prefocusing lens

Returns:

Type Description
float

returns the effective radius of the lens array.

Functions
connect classmethod
connect(array1, array2)

Create a new LensConnect from the combination of multiple

Source code in tfs/lens.py
@classmethod
def connect(cls, array1, array2):
    """
    Create a new LensConnect from the combination of multiple
    """
    return cls(*array1.lenses, *array2.lenses)
image
image(z_obj, energy)

Method recursively calculates the z location of the image of a system of lenses and returns it in meters (m)

Parameters:

Name Type Description Default
z_obj

Location of the object along the beam pipline from a designated point of origin in meters (m)

required

Returns:

Type Description
float

returns the location z of a system of lenses in meters (m).

Source code in tfs/lens.py
def image(self, z_obj, energy):
    """
    Method recursively calculates the z location of the image of a system
    of lenses and returns it in meters (m)

    Parameters
    ----------
    z_obj
        Location of the object along the beam pipline from a designated
        point of origin in meters (m)

    Returns
    -------
    float
        returns the location z of a system of lenses in meters (m).
    """
    # Set the initial image as the z object
    image = z_obj
    # Determine the final output by looping through lenses
    for lens in self.lenses:
        image = lens.image_from_obj(image, energy)
    return image
show_info
show_info()

Show a table of information on the lens

Source code in tfs/lens.py
def show_info(self):
    """
    Show a table of information on the lens
    """
    print(self._info())

LensTripLimits

Bases: Device

Trip limits for a given pre-focus lens (or lack thereof).

Attributes
high class-attribute instance-attribute
high = Component(EpicsSignalRO, ':HIGH', doc='Trip region high [um]', auto_monitor=False)
low class-attribute instance-attribute
low = Component(EpicsSignalRO, ':LOW', doc='Trip region low [um]', auto_monitor=False)

MFXLens

MFXLens(prefix, **kwargs)

Bases: InOutPVStatePositioner, LensCalcMixin

Data structure for basic Lens object

Parameters:

Name Type Description Default
prefix str

Name of the state record that controls the PV

required
prefix_lens str

Prefix for the PVs that contain focusing information

required
Source code in tfs/lens.py
def __init__(self, prefix, **kwargs):
    # Only assign X/Y motor PVs for true TFS lenses of the form ":TFS:##"
    # Prefocus lenses (":DIA:##") should not use the TFS X/Y motor map.
    m = re.search(r":(TFS|DIA):(\d+)$", prefix)
    if m and m.group(1) == 'TFS':
        lens_num = int(m.group(2))
        try:
            mapping = LENS_MOTOR_PVS[lens_num]
        except KeyError:
            raise ValueError(f"Unknown TFS lens number {lens_num} parsed from prefix {prefix}")
        self.x_pv = mapping['x']
        self.y_pv = mapping['y']
    else:
        # For DIA or any non-matching suffix, do not configure X/Y PVs
        self.x_pv = None
        self.y_pv = None
    super().__init__(prefix, **kwargs)
Attributes
radius property
radius

Method converts the EPICS lens radius signal into a float that can be used for calculations.

Returns:

Type Description
float

Returns the radius of the lens

sig_focus property
sig_focus

Method converts the EPICS focal length signal of the lens into a float

Returns:

Type Description
float

Returns the focal length of the lens in meters

x class-attribute instance-attribute
x = FormattedComponent(OnePVMotorRetry, '{x_pv}', kind='normal')
x_pv instance-attribute
x_pv = mapping['x']
y class-attribute instance-attribute
y = FormattedComponent(OnePVMotorRetry, '{y_pv}', kind='normal')
y_pv instance-attribute
y_pv = mapping['y']
z property
z

Method converts the z position EPICS signal into a float.

Returns:

Type Description
float

Returns the z position of the lens in meters along the beamline

Functions

OnePVMotorRetry

Bases: OnePVMotor

OnePVMotor with a simple retry-to-tolerance move helper.

Usage: motor.mv_retry(target, retries=3, tolerance=1e-3)

Functions
mv_retry
mv_retry(position, *, retries=3, tolerance=0.01, settle_time=0.2, timeout=None)

Move to position with verify-and-retry until within tolerance.

Parameters:

Name Type Description Default
position float

Desired setpoint in engineering units.

required
retries int

Number of additional attempts after the first move, by default 3.

3
tolerance float

Allowed absolute error |RBV - SP|, by default 1e-2.

0.01
settle_time float

Seconds to wait after move completion before checking RBV, by default 0.2.

0.2
timeout float | None

Move timeout passed through to the underlying move call.

None
Source code in tfs/lens.py
def mv_retry(self, position, *, retries=3, tolerance=1e-2, settle_time=0.2, timeout=None):
    """Move to position with verify-and-retry until within tolerance.

    Parameters
    ----------
    position : float
        Desired setpoint in engineering units.
    retries : int, optional
        Number of additional attempts after the first move, by default 3.
    tolerance : float, optional
        Allowed absolute error |RBV - SP|, by default 1e-2.
    settle_time : float, optional
        Seconds to wait after move completion before checking RBV, by default 0.2.
    timeout : float | None, optional
        Move timeout passed through to the underlying move call.
    """
    attempts = retries + 1
    last_readback = None
    for attempt_index in range(attempts):
        status = self.move(position, wait=True, timeout=timeout)
        if settle_time and settle_time > 0:
            time.sleep(settle_time)
        try:
            last_readback = self.position
        except Exception:
            last_readback = None
        if last_readback is not None and abs(last_readback - position) <= tolerance:
            return status
        logger.warning(
            "Motor %s missed target (attempt %d/%d): target=%s readback=%s tol=%s",
            getattr(self, 'name', repr(self)),
            attempt_index + 1,
            attempts,
            position,
            last_readback,
            tolerance,
        )