atomiq.components.laser ======================= .. py:module:: atomiq.components.laser Classes ------- .. autoapisummary:: atomiq.components.laser.LaserSource atomiq.components.laser.LockedLaserSource atomiq.components.laser.Laser atomiq.components.laser.SwitchableLaser atomiq.components.laser.ModulatedLaser atomiq.components.laser.StabilizedModulatedLaser atomiq.components.laser.AutoCalibratedModulatedLaser atomiq.components.laser.OptimizerStabilizedModulatedLaser atomiq.components.laser.ContinuouslyStabilizedModulatedLaser Module Contents --------------- .. py:class:: LaserSource(frequency, power = 0.001, *args, **kwargs) Bases: :py:obj:`atomiq.components.primitives.Component` Free-running laser source This class represents a generic (free-running) laser source that emits light of a specified frequency :param frequency: Frequency of the emitted light in Hz :param power: Emitted light power in W .. py:attribute:: _frequency .. py:attribute:: _power :value: 0.001 .. py:method:: get_frequency() .. py:method:: set_frequency(frequency) .. py:method:: get_power() .. py:method:: set_power(power) .. py:class:: LockedLaserSource(lock, *args, **kwargs) Bases: :py:obj:`LaserSource` Locked laser source This class represents a generic locked laser source that emits light of a specified frequency :param lock: lock component that locks the laser source .. py:attribute:: kernel_invariants .. py:attribute:: lock .. py:method:: get_frequency() .. py:method:: set_frequency(frequency) .. py:class:: Laser(laser_source, zero_freq = None, *args, **kwargs) Bases: :py:obj:`LaserSource` Laser light that can be modulated Since we inherit from LaserSource here, a Laser object can itself again be a LaserSource for another Laser object. This way one can describe consecutive manipulations from a LaserSource to the final Laser object. :param laser_source: The laser source that this laser is taken from :param zero_freq: absolute frequency in Hz that should be considered zero. This allows to reference the laser frequency relative to e.g. an atomic transition. If not set, the detuning will be relative to the lock point of the laser source .. py:attribute:: kernel_invariants .. py:attribute:: laser_source .. py:attribute:: zero_freq .. py:method:: get_frequency() .. py:method:: set_frequency(frequency) Set the absolute frequency of the light after modulation :param frequency: Absolute frequency of the light after modulation in Hz .. py:method:: _set_frequency_dummy(frequency) .. py:method:: set_detuning(detuning) Set the detuning of the light from the frequency defined by `zero_freq` .. note:: If you are using a modulator (e.g. AOM) the center frequency is not taken into account. If you want to set the detuning from the center frequency of the modulator use `self.modulator.set_detuning` :param detuning: Detuning in Hz .. py:method:: detune(frequency) Alias for :meth:`set_detuning` .. py:class:: SwitchableLaser(switch, *args, **kwargs) Bases: :py:obj:`Laser`, :py:obj:`atomiq.components.primitives.Switchable` A laser that can be switched on and off This class represents a laser that can be switched on and off, e.g. by a mechanical shutter. However, every `Switchable` can be used to switch the laser. :param laser_source: The laser source that this laser is taken from :param switch: The component that switches the laser light .. py:attribute:: kernel_invariants .. py:attribute:: laser_source .. py:attribute:: switch .. py:method:: on() .. py:method:: off() .. py:class:: ModulatedLaser(modulator, switch = None, fm_device = 'mod', am_device = 'mod', src_transmission = 1.0, *args, **kwargs) Bases: :py:obj:`SwitchableLaser`, :py:obj:`atomiq.components.primitives.Parametrizable` A laser that can be changed in frequency and amplitude This class represents a laser that is altered by an acusto-optic modular (AOM). The AOM can be used the modulate the amplitude and the frequency of the light. :param laser_source: The laser source that this laser is taken from :param switch: The component that switches the laser light. If none is given, the AOM is used to switch the light. :param modulator: component that does the amplitude/frequency/phase modulation of the laser. E.g. an AOM, EOM, etc. :param zero_freq: absolute frequency in Hz that should be considered zero. This allows to reference the laser frequency relative to e.g. an atomic transition. If not set, the detuning will be relative to the lock point of the laser source :param fm_device: Choose whether the frequency should be set via the modulator (mod) or the laser source (src). (default: mod) :param am_device: Choose whether the power should be set via the modulator (mod) or the laser source (src). (default: mod) :param src_transmission: Transmission of the light from the laser source to behind the modulator [0..1] (default 1) .. py:attribute:: kernel_invariants .. py:attribute:: modulator .. py:attribute:: laser_source .. py:attribute:: fm_device :value: 'mod' .. py:attribute:: am_device :value: 'mod' .. py:attribute:: src_transmission :value: 1.0 .. py:method:: get_amplitude() .. py:method:: set_amplitude(amplitude) .. py:method:: get_frequency() .. py:method:: set_frequency(frequency) Set the absolute frequency of the light after modulation :param frequency: Absolute frequency of the light after modulation in Hz .. py:method:: _set_frequency_through_modulator(frequency) .. py:method:: _set_frequency_through_source(frequency) .. py:method:: ramp(duration, frequency_start = float('nan'), frequency_end = float('nan'), detuning_start = float('nan'), detuning_end = float('nan'), amplitude_start = float('nan'), amplitude_end = float('nan'), power_start = float('nan'), power_end = float('nan'), ramp_timestep = float('nan'), ramp_steps = -1) Ramp frequency and/or power/amplitude over a given duration. Parameters default to ``-1`` or ``nan`` to indicate no change. If no starting value is given, the ramp starts from the last frequency/amplitude which was set. Either power or amplitude can be given to ramp the intensity of the laser. If power is given, it overwrites the value for the amplitude This method advances the timeline by ´duration´ :param duration: ramp duration [s] :param frequency_start: initial frequency [Hz] :param frequency_end: end frequency [Hz] :param detuning_start: initial detuning [Hz] :param detuning_start: final detuning [Hz] :param amplitude_start: initial amplitude :param amplitude_end: end amplitude :param power_start: initial power [W] :param power_end: final power [W] .. py:method:: arb(duration, samples_amp = [], samples_power = [], samples_freq = [], samples_det = [], samples_phase = [], repetitions = 1, prepare_only = False, run_prepared = False, transform_amp=identity_float, transform_freq=identity_float, transform_phase=identity_float) Play Arbitrary Samples from a List This method allows to set the output amplitude, frequency an phase according to the values specified in respective lists. The whole sequence is played in the specified duration. The pattern store in the sample list can also be repeated. We supports a scheme to prepare the arb function before it is actually used. If that is needed, run this function with `prepare_only = True` when the arb should be prepared and with `run_only = True` when the prepared arb should be played. In both calls the other parameters have to be passed. :param samples_amp: List of amplitude samples. If this list is empty (default), the amplitude is not modified. :param samples_power: List of power samples. If this list is empty (default), the amplitude is not modified. This overwrites `samples_amp`. :param samples_freq: List of frequency samples. If this list is empty (default), the frequency is not modified. :param samples_det: List of frequency samples relative to the zero frequency. If this list is empty (default), the frequency is not modified. This overwrites `samples_frequency` :param samples_phase: List of phase samples. If this list is empty (default), the phase is not modified. :param duration: The time in which the whole sequence of samples should be played back [s]. :param repetitions: Number of times the sequence of all samples should be played. (default 1) .. py:method:: get_power() .. py:method:: _amplitude_from_power(power) .. py:method:: set_power(power) Set the absolute power of the light after modulation :param power: Absolute power of the light after modulation in W .. py:class:: StabilizedModulatedLaser(photodiode, *args, **kwargs) Bases: :py:obj:`ModulatedLaser`, :py:obj:`atomiq.components.primitives.Measurable` A power-stabilized modulated laser With some means of measuring the laser power after the amplitude modulator and a feedback, the laser power can be stabilized. This is an abstract class to represent this kind of setups. To monitor the power of the laser after the modulator, a photodiode is required. :param photodiode: The photodiode that monitors the laser power .. py:attribute:: kernel_invariants .. py:attribute:: photodiode .. py:method:: get_power() .. py:method:: stabilize(enable) .. py:method:: _stabilize(enable) :abstractmethod: .. py:class:: AutoCalibratedModulatedLaser(points = 6, *args, amp_min = 0.0, amp_max = 1.0, timestep = 325 * us, **kwargs) Bases: :py:obj:`StabilizedModulatedLaser` A laser that uses a Measurable to auto-calibrate its power With some means of measuring the laser power after the amplitude modulator and a feedback, the amplitude for the modulator to achieve a certain power in the beam can be auto-calibrated. To achieve this, this laser measures a configurable number of points and makes a linear interpolation between them if a power in between is requested. :param points: number of points to measure for the auto-calibration. (default 6) :param amp_min: minimum amplitude to test in the auto-calibration :param amp_max: maximum amplitude to test in the auto-calibration .. py:attribute:: kernel_invariants .. py:attribute:: points :value: 6 .. py:attribute:: amp_min :value: 0.0 .. py:attribute:: amp_max :value: 1.0 .. py:attribute:: timestep .. py:attribute:: cache .. py:attribute:: cache_filled :value: False .. py:method:: clear_cache() .. py:method:: _cache_closest_idx(power) .. py:method:: amplitude_from_power(power) .. py:method:: autocalibrate() .. py:method:: set_power(power) Set the output power of the laser If no autocalibration has been done before in this kernel, this will immediately perform the calibration and set the modulator according to the result. If a calibration is present in the cache, the cache values are used to calculate an interpolation. :param power: the power the laser should be stabilized to. If the photodiode is calibrated the power should be :param given in the calibrated units: :type given in the calibrated units: e.g. mW .. py:class:: OptimizerStabilizedModulatedLaser(optimizer, cache_size = 8, *args, **kwargs) Bases: :py:obj:`StabilizedModulatedLaser` A modulated laser power-stabilized through an optimizer This class integrates an optimizer to find the best setting of the amplitude modulator to achieve the desired power on the monitoring photodiode. This can be used to create "poor man's PID". Upon calling :func:set_power() it is checked whether an optimization result for the requested power already exists. If not the optimizer is called to find the best setting. This result is applied to the modulator and stored in the cache. To find the best setting, the optimizer will (multiple times) switch on the laser, change its power and measure the photodiode. When switching on the light interferes with the experimental sequence, make sure to call :func:set_power() for your desired power for the first time before the experiment starts. Then the optimization will be done when it does not interfere with your experiment and at a later time the optimization result can be read from the cache, i.e. not further optimization is possible. Of course this assumes that the laser source power is reasonably stable during the time between the optimization the the time the value is recalled from the cache. :param optimizer: Optimizer to use for finding the proper setting of the modulator. Make sure that the `actor_component` of the optimizer is identical to the the lasers `modulator` and the optimizer's `monitor_component` is identical to the lasers `photodiode`. :param cache_size: number of optimization results that can be stored. (default 8) .. py:attribute:: kernel_invariants .. py:attribute:: cache .. py:attribute:: cache_size :value: 8 .. py:attribute:: optimizer .. py:method:: _cache_idx(power) .. py:method:: clear_cache() .. py:method:: set_power(power) Set the output power of the laser If the requested power is not already in the cache, this will immediately perform the optimization and set the result on the modulator. If the requested power is present in the cache, the cache value is used. :param power: the power the laser should be stabilized to. If the photodiode is calibrated the power should be :param given in the calibrated units: :type given in the calibrated units: e.g. mW .. py:class:: ContinuouslyStabilizedModulatedLaser(start_stabilized = True, *args, **kwargs) Bases: :py:obj:`StabilizedModulatedLaser` A modulated laser power-stabilized through a continuous servo loop If a laser is power-stabilized by an external (hardware) servo loop, it is represented by this abstract class. :param start_stabilized: Should the servo loop be activated on startup? (default True) .. py:attribute:: stabilized :value: True .. py:method:: _prerun() Specify here what should be done for this component before the run starts. In contrast to the _build() method, the _prerun() routine is executed on the core device before the actual experiment starts.