Skip to content

Monochromators

Classes

BLISS provides classes which represent a set of common functionalities for monochromator control.

We assume that a monochromator is composed of:

  • Rotation motor (bragg angle - real motor)
  • Energy motor (Calc Motor)
  • Crystal(s)
  • Energy tracking object (how motors should adjust for a given energy)

This is represented by 6 classes Monochromator, MonochromatorFixExit, XtalManager, EnergyCalcMotor EnergyTrackerCalcMotor and EnergyTrackingObject. On can find a simulation class to test a monochromator with additional motors to change from one crystal to an other one: SimulMonoWithChangeXtalMotors.

Monochromator

This is the base class for monochromators.

Simple monochromator

```yml
- plugin: generic
  module: monochromator
  class: Monochromator
  name: simul_mono
  xtals: $simul_mono_xtals
  motors:
      - energy: $ene
      - energy_tracker: $enetrack      
  tracker: $tracker
  ```

Fix exit monochromator

  • For DCM monochromator, a fix exit offset can be given and passed to the XtalManager object (see XTalManager section)

    • YAML file

      - plugin: generic
        module: monochromator
        class: MonochromatorFixExit
        name: simul_mono_fix_exit
        xtals: $simul_mono_xtals
        motors:
            - energy: $ene
        fix_exit_offset: 10   <---
      
  • If the monochromator holds a set of crystals, a method to move from one crystal to the other(s) is foreseen. In this case, a new class should be written which inherits from Monochromator or MonochromatorFixExit Class.

    • 3 methods should be rewritten:
      • _load_config(self): allow to get the extra parameters in the mono yaml file
      • _xtal_change(self, xtal): move “xtal” in the beam
      • _xtal_is_in(self, xtal): return True if “xtal” is in the beam, False otherwise
    • Additional parameters should also be added in the XtalManager YAML file to get the position of the crystals in the beam, for example

    • Mono YAML file example

       - plugin: generic
         package: id09.controllers.monochromators
         class: ID09Mono
         name: ml_mono
         xtals: $ml_xtals     # the crystals manager
         ver_motor: $mlz
         hor_motor: $mly
         iotz_motor: $iotz
         ver_tolerance: 0.1
         hor_tolerance: 0.1
         motors:
             - energy: $mle
      

XtalManager

XtalManager describes the crystal(s) mounted on the monochromator.

  • At least one crystal need to be defined …

    • YAML file:

      - plugin: generic
        module: monochromator
        class: XtalManager
        name: mono_xtals
        xtals:
            - xtal: Si220
      
    • Available method:

      • bragg2energy
      • energy2bragg
    • … but more may be used:
    • YAML file:

      xtals:
          - xtal: Si111
          - xtal: Si311  <--
          - xtal: Ge511  <--
      
  • More methods are available for DCM monochromator, if the “fix_exit_offset” attribute is set: + bragg2dxtal + energy2dxtal + dxtal2bragg

    • YAML file:

      plugin: generic
      package: bm23.MONO.BM23monochromator
      class: XtalManager
      name: bm23_mono_xtals
      fix_exit_offset: -10    <--
      xtals:
          - xtal: Si111
          - xtal: Si311
          - xtal: Ge511
      
  • If you want to use crystal harmonics, add a crystal with its corresponding HKL values. You will be able to use it by changing the selected crystal with the Monochromator object (mono.xtal.change(new_xtal)).

    • YAML file:

      xtals:
          - xtal: Si111
          - xtal: Si333  -> Use third harmonic of Si111
          - xtal: Si311
          - xtal: Ge511  
      
  • Calculations are using the module bliss.physics.diffraction based on the public module mendeleev which define a number of crystals parameters. You may specify your own dspacing (in Angstrom) in the yml file. In this case, this value MUST be specified for each crystal

    • YAML file:

      xtals:
          - xtal: Si111
              dspacing: 3.1356  --> new dspacing for Si111
          - xtal: Si333
              dspacing: 3.1356  --> need to be set to be coherent
          - xtal: Ge511         --> using default constants
      
  • Multilayers:

    • Principle

      • the Bragg to Energy calculation for a multilayer is given by: n*lambda = 2*d-spacing*sqrt(1-2*delta_bar/pow(sin(theta),2))*sin(theta)
      • n = order of reflexion
      • d-spacing of such a multilayer is the sum of the thickness of each material (in Angstrom in the calculation)
      • delta_bar: . Parameter which is energy dependant. . Given by the Optic Group as a file Energy/Delta_bar . this formula is not bijective. In consequence a lookup table is built at the creation of the object to get energy from angle or angle from energy.
    • Configuration

      • to define a multilayer, use the tag “multilayer” instead of “xtal”
      • dpspacing: . Use tag “thickness1” and “thickness2” if the materials and their thicknesses are known. Only 2 materials are taken into account. Thickness must be given in nm . Use tag “dspacing” if the materials are unknown but you know an approximate dspacing. dspacing must be given in nm
      • delta_bar: . Use tag “delta_bar” to specify the file given by the optic group . if delta_bar is not specified, delta_bar=0
      • ml_lab_file: . if none of the parameters are known you can directly specify a lookup table energy(eV) vs bragg angle (radian) . Use the tag “lookup_table” to specify the file containing the lut
    • YAML File:

      xtals:
      - xtal: Si111       <-- Normal crystal definition
      
      - multilayer: ML_1  <-- Multilayer: All parameters are known
        dspacing1: 10        
        dspacing1: 11    
        delta_bar: /users/blissadm/local/beamline_configuration/mono/multilayer/OpticalConstantsW_B4C.txt
      
      - multilayer: ML_2  <-- Multilayer: Only an approximate dspacing is known
        dspacing: 21                      delta_bar = 0
      
      - multilayer: W  <-- Multilayer: Only a Energy<-> Bragg lookup table is given
        ml_lab_file: /users/blissadm/local/beamline_configuration/mono_config/ID09_110314_WB4C_E_th.txt
      

Calculation Motors and Tracking object

The monochromator controller required at least a energy axis controlled by a EnergyCalcMotor and in addition it can have an energy tracking axis controlled by a EnergyTrackerCalcMotor and a bragg tracking axis controlled by BraggTrackerCalcMotor.

EnergyCalcMotor

EnergyCalcMotor and EnergyTrackingCalcMotor need to know the Monochromator it is refering to. At Initialization of the mono, the method EnergyCalcMotor.set_mono(self) is called. The Value of the EnergyCalcMotor is Nan before this call or if no crystal is selected in the XtalManager object. The Monochromator object is in charge to do this selection.

# Energy Calc Motor config is like:
- plugin: emotion
  module: monochromator
  class: EnergyCalcMotor
  axes:
    - name: $sim_mono
      tags: real bragg
    - name: ene
      tags: energy
      unit: keV

EnergyTrackingCalcMotor

# EnergyTracker CalcMotor config is like:

- plugin: emotion
  module: monochromator
  class: EnergyTrackingCalcMotor
  approximation: 0.0005
  axes:
    - name: $ene
      tags: real energy
    - name: $sim_c1
      tags: real sim_c1
    - name: $sim_c2
      tags: real sim_c2
    - name: $sim_acc
      tags: real sim_acc
    - name: enetrack
      tags: energy_track
      unit: keV

EnergyTrackingObject

The monochromator can have one EnergyTrackingObject. It contains the list of axes that require to adjust its position when the bragg angle (and the energy) changes.

Each motor can have one or several parameter identifier (id) defined, for instance some harmonic ids in the case of an undulator monochromator.

Each id can have one or several tracking modes defined, by table, polynom or therory. See details below.

Configuration

This is a whole yml configuration with a tracker object and a energy tracker axis and the use of a simulated EnergyTrackingObject (available in the monochromator bliss module), which just implements a theory mode with the methods _ene2gap() and _gap2ene().

# Monochromator
- plugin: generic
  module: monochromator
  class: Monochromator
  name: simul_mono
  xtals: $simul_mono_xtals        # the crystals manager
  motors: 
    - energy: $ene                # the energy axis
    - energy_tracker: $enetrack   # a energy tracker axis
  tracker: $tracker


# Xtals Manager
- plugin: generic
  module: monochromator
  class: XtalManager
  name: mono_xtals
  xtals:
    - xtal: Si220
      dspacing: 1.920171445282458
    - xtal: Si311
      dspacing: 3.141592653589793

# Energy -> bragg Calc motor
- plugin: generic
  module: monochromator
  class: EnergyCalcMotor
  axes:
    - name: $sim_mono
      tags: real bragg
    - name: ene
      tags: energy
      unit: keV

# Energy -> bragg +tracker calc motor
- plugin: generic
  module: monochromator
  class: EnergyTrackerCalcMotor
  approximation: 0.003
  master_tag: energy
  axes:
    - name: $ene
      tags: real energy
    - name: $sim_c1
      tags: real tracker1
    - name: $sim_c2
      tags: real tracker2
    - name: $sim_acc
      tags: real tracker3
    - name: enetrack
      tags: energy_tracker
      unit: keV

# Tracking objects
- plugin: generic
  module: monochromator
  class: SimulEnergyTrackingObject
  name: tracker
  trackers:
    - motor: $sim_c1
      parameters:
        - id: harmonic_1
          table: "monochromator/focus_C1.dat"
        - id: harmonic_2
          table: "monochromator/focus_C1.dat"
          polynom:
            E6: -2.305918e-07
            E5: 1.772031e-05
            E4: -0.0005460834
            E3: 0.008611169
            E2: -0.07324875
            E1: 0.3891596
            E0: -0.4258383
          theory:
            - energy2tracker: _ene2gap
            - tracker2energy: _gap2ene
            - harmonic: 1
            - Uperiod: 27.19

    - motor: $sim_c2
      parameters:
        - id: harmonic_1
          table: "monochromator/focus_C2.dat"
          polynom:
            E6: -2.305918e-07
            E5: 1.772031e-05
            E4: -0.0005460834
            E3: 0.008611169
            E2: -0.07324875
            E1: 0.3891596
            E0: -0.4258383

Usage

Monochromator information

MONO_SESSION [15]: mono
         Out [15]: Monochromator: mono
           Monochromator: simul_mono

           Crystal: Si220 (Si220 Si311)

                              ene    sim_mono
           Calculated  18.592 keV  10.000 deg
              Current     nan keV  10.000 deg

                         enetrack         ene    sim_c1    sim_c2    sim_acc
           Calculated  18.592 keV  18.592 keV  1.425 mm  1.423 mm  -0.096 mm
              Current  18.592 keV     nan keV  0.000 mm  1.000 mm   0.000 mm
             Tracking                                ON       OFF        OFF

Display information about:

  • selected crystal
  • bragg angle and corresponding energy
  • status of tracked motors
  • current position
  • calculated trajectory position given tracking parameters and current energy
  • tracking status (ON or OFF)

Motor tracking information

Current tracking info is given by tracking property of monochromator object or tracking object.

BLISS [5]: simul_mono.tracking
  Out [5]:                      sim_c1      sim_c2    sim_acc
           Calculated Pos.    1.425 mm    1.423 mm  -0.096 mm
              Current Pos.    0.000 mm    1.000 mm   0.000 mm
            Tracking State          ON         OFF        OFF
                      Mode       table     polynom      table
              Parameter id  harmonic_1  harmonic_1    default

For each tracker object and motor, display information about:

  • weither motor is on trajectory with calculated and current position
  • tracking status (ON or OFF)
  • tracking mode (table / polynom / theory)
  • selected trajectory (or harmonic for undulators)

Toggle tracking state

Use tracking.all_on / tracking.all_off methods to enable or disable tracking on tracking objects, or on / off methods on motors directly.

# Enable tracking for monochromator (all trackers and motors)
MONO_SESSION [1]: mono.tracking.all_on()

# Disable tracking for a motor only
MONO_SESSION [2]: sim_c1.tracking.off()

# Get axis current tracking state
MONO_SESSION [3]: sim_c1.tracking.state
         Out [3]: False

# Enable tracking on axis object
MONO_SESSION [4]: sim_c1.tracking.on()

Tracking mode

Energy can be tracked using several modes table, polynom or theory.

  • table uses a calibration file (see track tables below)
  • polynom uses the polynom defined by its coefficients from E0 to E6
  • theory uses a formula for undulators (gap) defined by TG0, TL0, TGAM, TB0.

Configuration can specify one or several modes for each parameters. The default mode is given by the mode specified in yaml file.

The current mode can be set with mode property either from the .tracking or the .tracking object.

# Set tracking mode on axis object via monochromator object
MONO_SESSION [1]: mono.tracking.sim_c1.mode
         Out [1]: Selected Mode: table (polynom/theory/table)

# Set tracking mode on axis object via monochromator object
MONO_SESSION [2]: mono.tracking.sim_c1.mode.table()

# Get current tracking mode of an axis object
MONO_SESSION [3]: sim_c1.tracking.mode
         Out [3]: Selected Mode: polynom (polynom/theory/table)

# Set current tracking mode of an axis object
MONO_SESSION [4]: sim_c1.tracking.mode.polynom

Switch trajectories or harmonics

Tracking parameters for each motor can specify different settings for different trajectories.

Each parameter ID must have parameters defined for at least one mode (table, polynom or theory).

Undulator harmonics

In case of undulator monochromator, the parameter ids represent the different harmonics.

# Get current parameter ID name
BLISS [20]: sim_c1.tracking.param_id
  Out [20]: Selected Param Id: harmonic_1 (harmonic_1/harmonic_2)

# Switch to 2nd harmonic
BLISS [21]: sim_c1.tracking.param_id.harmonic_2()
BLISS [22]: sim_c1.tracking.param_id
  Out [22]: Selected Param Id: harmonic_2 (harmonic_1/harmonic_2)

Track tables

Tracking tables allow a motor position to be calibrated to a given energy point. The table define a trajectory that the motor will track when the energy changes.

It relies on XCalibu project (for tables only).

File format is a 2 columns text file with energy and motor position for each point.

# Energy motor_position
10.0000  1.1514
11.0000  1.3532
...      ...

Between two energy points, the position of the motor is interpolated using linear regression.

Usage

track_tables property of monochromator object allow to interact with tracking tables.

It allows to print, plot and modify tables with methods setpoint, delpoint, save, plot.

# Display current tables for all currently tracked motors
MONO_SESSION [1]: mono.track_tables
         Out [1]: 
                    Energy    sim_c1    sim_c2    sim_acc
                  --------  --------  --------  ---------
                    4.9399  0.470157  0.411799  -0.146702
                    5       0.475166  0.416808  -0.145901
                    5.5     0.51492   0.449367  -0.141491
                    5.7503  0.533636  0.466079  -0.138115
                    5.9996  0.552033  0.482473  -0.136984
                    6.5     0.588508  0.516125  -0.133978
                    6.9999  0.621568  0.552008  -0.13299
                    7.5004  0.657133  0.585569  -0.130494
                    7.9998  0.692698  0.621134  -0.128493
                    8.5001  0.725257  0.659704  -0.126993
                    8.9996  0.761323  0.692263  -0.124993
                    9.4979  0.794383  0.726826  -0.123493
                    ...

# Add current point (energy, motor position) in tables for all tracked motors
MONO_SESSION [2]: mono.track_tables.setpoint()

# Delete energy point from tables for all currently tracked motors
MONO_SESSION [3]: mono.track_tables.delpoint()     # current energy point
MONO_SESSION [4]: mono.track_tables.delpoint(6.5)  # delete 6.5 kev point

# Save modified table files to disk (in beamline configuration)
MONO_SESSION [5]: mono.track_tables.save()

# Display trajectory in a plot (for given axis)
MONO_SESSION [6]: mono.track_tables.plot("axis")

track_table property of axis or tracking object allow do the same on a per axis basis.

# Display current table for a tracked motor
MONO_SESSION [1]: sim_c1.track_table
         Out [1]: 
                    Energy    sim_c1
                  --------  --------
                    4.9399  0.470157
                    5       0.475166
                    5.5     0.51492
                    5.7503  0.533636
                    5.9996  0.552033
                    6.5     0.588508
                    6.9999  0.621568
                    7.5004  0.657133
                    7.9998  0.692698
                    8.5001  0.725257
                    8.9996  0.761323
                    9.4979  0.794383
                    ...

# Add current point (energy, motor position) in table
MONO_SESSION [2]: sim_c1.track_table.setpoint()

# Delete energy point from table
MONO_SESSION [3]: sim_c1.track_table.delpoint()     # current energy point
MONO_SESSION [4]: sim_c1.track_table.delpoint(6.5)  # delete 6.5 kev point

# Save modified table files to disk (in beamline configuration)
MONO_SESSION [5]: sim_c1.track_tables.save()

# Display trajectory in a plot
MONO_SESSION [6]: sim_c1.track_tables.plot()

Note: a tolerance of 10 eV (by default) is applied when replacing/deleting an enegy point in the table. It’s configurable with sim_c1.track_tables._kev_tolerance.

Access to underlying XCalibu object is given by sim_c1.track_table.calib object for lower level operations.

Backup when saving tables

When saving changes with track_table.save() the old table file is backed up with the date in the filename extension, (up to one backup per day).