Microwave Sources - ACBJayichLab/NV_ABJ GitHub Wiki
A microwave source in this case is most closely linked to anything that we use to supply RF to the nitrogen vacancy. This may mean that other microwave sources don't fall into this abstract class it may also mean that more than one item makes the microwave source. For example, we consider the microwave source in most experiments to be the SG384 but in this use case we really should consider the microwave source to be the SG384 and the microwave switch. This is because the microwave switch adds the functionality of duration control which is essential for driving the nitrogen vacancy correctly. The microwave switch is also not necessary for experiments using triggered arbitrary wave generators but these devices fulfill the same roll so the class needs to specify the necessary components for the devices in use.
Required Abstract Functionality
For a class to be a microwave source you have to use the abstract MicrowaveSource class as a sub class for the module. By importing this abstract class as a subclass you will not be able to create a microwave source without the required functions defined. This doesn't assure the correctness of the code but it does encourage compatibility.
from NV_ABJ import MicrowaveSource
class SG380(MicrowaveSource):
frequency_range_hz
This is meant to return the frequency range of the device as a tuple in Hz. It may be something that is defined by the code and not interfaced from the device or it could be something that is pulled from the device when a new class is instantiated. It is a property function because this is not something that necessarily needs regular updating or computation it should be static through the duration of the class. (minimum frequency, maximum frequency)
@property
def frequency_range_hz(self)->tuple[float,float]:
power_range_dbm
This returns in the power range of the device that you are interfacing with as a tuple in dBm (minimum power, maximum power)
@property
def power_range_dbm(self)->tuple[float,float]:
get_frequency_hz
This should return the frequency in Hz that the microwave source is set to currently it is okay to have this as a pythonic based function for items like the AWG where the frequency is more set on creation and it might not be running the whole time.
def get_frequency_hz(self)->int:
get_power_dbm
Returns the power in dBm that the microwave source should be at. For items like the SRS SG384 it is appropriate to have this as a get function from the SRS.
def get_power_dbm(self)->float:
generate_sine_wave_hz_dbm
Generates a microwave source that is set to a specific frequency and amplitude this a general
def generate_sine_wave_hz_dbm(self,frequency:int,amplitude:float,*args,**kwargs):
set_power_dbm
Sets the power the microwave source should be at in dBm
def set_power_dbm(self,power:float):
set_frequency_hz
Sets the frequency in Hz for the microwave source
def set_frequency_hz(self,frequency_hz:int):
turn_on_signal
Turns on the RF signal by default we should not turn on the RF when using a context manger like the with keyword. This is because we want to send lists of data or change powers when the microwave source is not outputting to the sample
def turn_on_signal(self):
turn_off_signal
Turns off the microwave sources this should be expected to be called when exiting a context manager like the with keyword so that we can expect microwave sources stay off when not being interfaced with
def turn_off_signal(self):
load_frequency_list_hz
This is meant to be a command to load a frequency list to a device if the device can't do this it can be implemented using the set frequency and saving the list as a property to the class triggering you can just iterate through the list
def load_frequency_list_hz(self,frequency_list:list):
get_frequency_list_hz
returns the frequency list currently loaded
def get_frequency_list_hz(self)->list:
iterate
This will iterate through the loaded frequency list essentially setting the current frequency to the triggered values
def iterate(self):
all = ["MicrowaveSource","MicrowaveSourceConfiguration"]
from abc import ABCMeta, abstractmethod from NV_ABJ.abstract_interfaces.connected_device import ConnectedDevice import numpy.typing as npt import numpy as np from dataclasses import dataclass
@dataclass class MicrowaveSourceConfiguration: frequency_range_hz:tuple[float,float] amplitude_range_dbm:tuple[float,float]
class MicrowaveSource(ConnectedDevice,metaclass=ABCMeta): """This is a class for a signal generator not limited to but used for control of the RF supplied to the NV and allows for a general implementation for the singal frequency generators """
@property
@abstractmethod
def frequency_range_hz(self)->tuple[float,float]:
"""This is the frequency range that the prime sinusoidal rf is able to generate in
Returns:
tuple[float,float]: (minimum frequency, maximum frequency)
"""
@property
@abstractmethod
def amplitude_range_dbm(self)->tuple[float,float]:
"""This is the amplitude range that the prime sinusoidal rf is able to generate in
Returns:
tuple[float,float]: (minimum amplitude, maximum amplitude)
"""
@abstractmethod
def prime_sinusoidal_rf(self,frequency_list_hz:npt.NDArray[np.float64],
rf_amplitude_dbm:npt.NDArray[np.float64],
duration_s:npt.NDArray[np.float64],
*args,**kwargs):
"""This is a generalized function that is meant to allow for an experimental signal generation this
is meant to be implemented so the experimental logic for a cwesr, pulsed esr, or tau sweep will work properly.
Not all actions need to be completed by the device but these are the expected inputs to constrain an arbitrary
waveform to the correct sinusoidal signal. This priming is not meant to start the signal but it is meant to queue
up the frequency list for operation
A primed signal means that when a external trigger is applied to the device or device pair it will play the requested frequency
- For the SRS SG384 this means the signal is turned on and a microwave switch is expected to be present
- For a Keysight AWG the duration is added and we expect the sequence generator to trigger it on for a preset duration
Args:
frequency_list_hz (npt.NDArray[np.float64]): A floating point numpy array that consists of the frequency in Hz
rf_amplitude_dbm (npt.NDArray[np.float64]): A floating point numpy array of the amplitude of the un-modulated sine wave dBm
duration_s (npt.NDArray[np.float64]): A floating point numpy array of the duration in seconds for sine wave
"""
pass
@abstractmethod
def turn_on_signal(self)->None:
"""This turns on the signal source as a continuous operation
"""
pass
@abstractmethod
def turn_off_signal(self)->None:
"""This turns off the signal source and will not turn off the device
"""
pass
@abstractmethod
def iterate_next_waveform(self)->None:
"""This will iterate through the loaded frequency list essentially setting the current frequency to the triggered values
"""
pass