def photon_counter_channels(): ''' `p7888_start_trigger` tells the photon counting card to start listening for photon counts. I believe listens for data for less than 1 ms. `p7888_flushing_trigger` feeds into one of the listening ports on the photon counting card. It's so we can send fake photons and fill up the memory of the card so it updates on the PC. `photon_counter_shutter` controls the shutter before the photon_counter photodiode. It's to for prevent damage to the photodiode. ''' DigitalOut( name = 'p7888_start_trigger', parent_device = ni_pci_6284_dev6, connection = 'port0/line11' ) DigitalOut( name = 'p7888_flushing_trigger', parent_device = ni_pci_6284_dev6, connection = 'port0/line15' ) DigitalOut( name = 'photon_counter_shutter', parent_device = ni_pci_6284_dev6, connection = 'port0/line13', inverted = True )
def __init__(self, name, parent_device, connection, BIAS_port, serial_number, SDK, effective_pixel_size, exposuretime=None, orientation='side'): DigitalOut.__init__(self,name,parent_device,connection) self.exposuretime = exposuretime self.orientation = orientation self.exposures = [] self.BLACS_connection = BIAS_port if isinstance(serial_number,str): serial_number = int(serial_number,16) self.sn = np.uint64(serial_number) self.sdk = str(SDK) self.effective_pixel_size = effective_pixel_size
def __init__(self,name,parent_device,com_port='COM1',FMSignal=None,RFOnOff=None,freq_limits = None,freq_conv_class = None,freq_conv_params = {},amp_limits=None,amp_conv_class = None,amp_conv_params = {},phase_limits=None,phase_conv_class = None,phase_conv_params = {}): #self.clock_type = parent_device.clock_type # Don't see that this is needed anymore IntermediateDevice.__init__(self,name,parent_device) self.BLACS_connection = com_port self.sweep_dt = 2e-6 self.RFSettings = { 'freq': 0, 'amp': 0, 'phase': 0, 'freq_dev':0 ##EE } self.sweep_params = { # 'type': None, 'low': 0, 'high': 1, 'duration': 0, # 'falltime': 0, 'sample_rate': self.sweep_dt } self.sweep = False self.ext_in = False self.frequency = StaticAnalogQuantity(self.name+'_freq',self,'freq',freq_limits,freq_conv_class,freq_conv_params) self.amplitude = StaticAnalogQuantity(self.name+'_amp',self,'amp',amp_limits,amp_conv_class,amp_conv_params) self.phase = StaticAnalogQuantity(self.name+'_phase',self,'phase',phase_limits,phase_conv_class,phase_conv_params) self.FMSignal = {} self.RFOnOff = {} if FMSignal: if 'device' in FMSignal and 'connection' in FMSignal: self.FMSignal = AnalogOut(self.name+'_FMSignal', FMSignal['device'], FMSignal['connection']) else: raise LabscriptError('You must specify the "device" and "connection" for the analog output FMSignal of '+self.name) else: raise LabscriptError('Expected analog output for "FMSignal" control') if RFOnOff: if 'device' in RFOnOff and 'connection' in RFOnOff: self.RFOnOff = DigitalOut(self.name+'_RFOnOff', RFOnOff['device'], RFOnOff['connection']) else: raise LabscriptError('You must specify the "device" and "connection" for the digital output RFOnOff of '+self.name) else: raise LabscriptError('Expected digital output for "RFOnOff" control')
def red_laser_channels(): ''' ## Intensity Controls `red_cavity_power` Controls the trap light power going into the cavity axis via error offset into a (PI) power lockbox. This RF signal is switched via `red_cavity_power_switch`. `red_cavity_power_switch` has some crosstalk with Channel 8 on Dev 6. `red_transverse_power` Controls the light power for the transverse trapping beam, which is oriented along the y-axis (lab frame). ''' AnalogOut( name = 'red_cavity_power', parent_device = ni_pci_6723_dev3, connection = 'ao0', limits = None ) AnalogOut( name = 'red_transverse_power', parent_device = ni_pci_6723_dev3, connection = 'ao5' ) DigitalOut( name = 'red_cavity_power_switch', parent_device = ni_pci_6284_dev6, connection = 'port0/line9' )
def blue_laser_channels(): ''' ###`blue_mot_power` This controls the power to our 399nm laser. It currently needs no distinction, as we only have one blue laser beam path: the MOT beampath. ###`blue_mot_shutter` This controls the shutter for the MOT beampath. ###`imaging_power_switch` Controls the RF switch for the 399nm Imaging Light beampath. ###`imaging_power_shutter` Controls the shutter for the 399nm Imaging Light beampath. ''' AnalogOut( name = 'blue_mot_power', parent_device = ni_pci_6713_dev4, connection = 'ao0', limits = None ) DigitalOut( name = 'blue_mot_shutter', parent_device = ni_pci_6284_dev6, connection = 'port0/line1' ) DigitalOut( name = 'imaging_power_switch', parent_device = ni_pci_6284_dev6, connection = 'port0/line6' ) DigitalOut( name = 'imaging_power_shutter', parent_device = ni_pci_6284_dev6, connection = 'port0/line7' )
def green_laser_channels(): ''' Control the power and shutters of the various green beams as well as the frequency. ##Beampaths Polarizations are defined with respect to the magnetic field bias. This is currently pointing up. ### Probe Beampath This is beampath for the light going into the cavity **for measurement**. It's \\(\\sigma+\\) polarized. #### Probe Sideband The Probe carrier frequency is actually a little far off from the atom+cavity resonance. The Probe Sideband is what actually interacts with the atoms+cavity. One can say the 'Probe Sideband' is the actual probing beam. Unfortunately, 'Probe' is more of a name for the ultimate use of the beam path rather than it's initial spectral content. This makes things confusing. We can try and help by saying that the naming convention in the lab is labeled by its final state. This makes it difficult to understand its evolution through the system but that's the way things are. #### Two Color Probe Sidebands (of the Probe Sideband) We have a **phase** measurement technique where we center the probe sideband frequency at the center of the atom + cavity resonances, then we apply modulation \\(f_m\\) to split this sideband in two. This allows us to drive two colors of light into the two modes of the atom + cavity system. Since these two beams share the same spatial mode, they interfere at the photodetector giving us a signal that, at least somewhat, looks like \\(\\cos(f_m t + \\phi) \\) where \\(\\phi\\) is the phase shift imparted by one of the atom + cavity transmission peaks. ### Pump Beampath This goes into the cavity axis. It's used polarizing the atoms in the up state. It's \\(\\sigma+\\) polarized. ### Cooling Beampath This is greenlight coming perpendicular to the cavity axis. It's \\(\\pi\\) polarized. ### Green MOT Beampath It has a complicated beam path. Green comes in from all directions. .. figure:: ./imgs/mot_path.png ##Analog Intensity Controls ###`probe_sideband_power` This controls the **sideband light** power via Mixer + Amplifier into an **EOM**. ###`two_color_probe_sideband_power` The probe sideband is split in two via EOM modulation. See the above section. **We think** that this controls the modulation strength and thus the ratio of the probe sideband and these two color sidebands, but are not sure. ###`probe_power_lock_error_offset` This controls an error offset to the `probe_sideband_power` lock. Typically, this constant across a whole experimental run. ###`pump_power` This controls the power via Mixer + Amplifier into an **AOM**. ###`cooling_pi_power` Currently not connected. ###`cooling_sigma_plus_power` Controls the power of the \\(\\sigma +\\) light feeding into the cavity axis for cooling purposes via **EOM**. ###`green_mot_power` Controls the power of the Green MOT via **AOM**. ##Digital Intensity Controls All the channels in this section turn off all the RF power to the AOM/EOM via an RF switch. ###`green_mot_power_switch` Controlled via MOT AOM. ###`probe_power_switch` Controlled via AOM. ###`probe_sideband_power_switch` Controlled via EOM. ###`pump_power_switch` Controlled via AOM. ###`cooling_pi_power_switch` Controlled via AOM. ###`probe_sideband_cooling_rf_switch` Is the TTL for an RF switch for changing the frequency fed into the eom for the probe/cooling path. ##Shutter Controls Aren't these just intensity controls? Yes, but they block the light better than turning off the EOM/AOM can. So a shutter helps ensure the light is really off. Ofcourse, they are slower so they are used in conjunction with an AOM/EOM RF control. ###`green_mot_shutter` ###`cooling_pi_shutter` ###`probe_shutter` Located almost just before entering the cavity mirror. It's beneath the optics table. ###`probe_sideband_cooling_shutters` This output actually controls two shutters. For `go_high`, the cooling path is open. For `go_low`, the probe sideband path is open. ## Frequency Control ###`probe_sideband_frequency` Controls the frequency of the EOM modulation, thus letting us control the detuning from the atom + cavity system. ###`two_color_chirp` Triggers the SRS to begin the frequency sweep for the phase measurement. ###`cooling_sideband_frequency` (SRS FM input) An analog input feeding into an SRS to control the Frequency Modulation. Thus, it's effectively a VCO. This VCO is driving the same EOM as the `probe_sideband_frequency` channel controls. We need a TTL to switch between the probe and cooling settings. One for the shutter, and one for the RF switch. ## FPGA Trigger There is an FPGA (Opal Kelly) that controls the frequencies of a Double Pass AOM early in the beampath. So it controls all the frequencies of all the beampaths. This FPGA controls the PTS synthesizer on top of the canopy of the lab. The frequencies are defined in an external program "FrontPanel.exe". There's a short cut to it on the desktop. ''' # # Intensity Controls # AnalogOut( name = 'probe_sideband_power', parent_device = ni_pci_6713_dev5, connection = 'ao0' ) AnalogOut( name = 'probe_power_lock_error_offset', parent_device = ni_pci_6713_dev5, connection = 'ao5' ) DigitalOut( name = 'probe_sideband_power_switch', parent_device = ni_pci_6284_dev6, connection = 'port0/line23' ) DigitalOut( name = 'probe_power_switch', parent_device = ni_pci_6284_dev6, connection = 'port0/line10', inverted = True ) AnalogOut( name = 'two_color_probe_sideband_power', parent_device = ni_pci_6713_dev5, connection = 'ao1' ) DigitalOut( name = 'probe_shutter', parent_device = ni_pci_6284_dev6, connection = 'port0/line12' ) AnalogOut( name = 'pump_power', parent_device = ni_pci_6713_dev5, connection = 'ao7', ) DigitalOut( name = 'pump_power_switch', parent_device = ni_pci_6284_dev6, connection = 'port0/line8' ) AnalogOut( name = 'cooling_pi_power', parent_device = ni_pci_6713_dev5, connection = 'ao6', ) DigitalOut( name = 'cooling_pi_power_switch', parent_device = ni_pci_6284_dev6, connection = 'port0/line24' ) AnalogOut( name = 'cooling_sigma_plus_power', parent_device = ni_pci_6723_dev3, connection = 'ao4' ) AnalogOut( name = 'green_mot_power', parent_device = ni_pci_6713_dev4, connection = 'ao4', limits = None ) DigitalOut( name = 'green_mot_power_switch', parent_device = ni_pci_6284_dev6, connection = 'port0/line2' ) DigitalOut( name = 'probe_sideband_cooling_rf_switch', #Old name: ProbeEOMPowerSelect (0=VCO 1=SRS) parent_device = ni_pci_6284_dev6, connection = 'port0/line29' ) # # Shutters # DigitalOut( name = 'cooling_pi_shutter', parent_device = ni_pci_6284_dev6, connection = 'port0/line25' ) DigitalOut( name = 'green_mot_shutter', parent_device = ni_pci_6284_dev6, connection = 'port0/line4' ) DigitalOut( name = 'green_frequency_fpga_trigger', parent_device = ni_pci_6284_dev6, connection = 'port0/line3' ) DigitalOut( name = 'probe_sideband_cooling_shutters', parent_device = ni_pci_6284_dev6, connection = 'port0/line16' ) # # Frequency Controls # AnalogOut( name = 'probe_sideband_frequency', parent_device = ni_pci_6713_dev4, connection = 'ao6', unit_conversion_class = GreenFrequencyVCOCalibration, unit_conversion_parameters = { 'raw_voltage' : vco_raw_voltage_data, 'raw_frequency' : vco_raw_frequency_data } ) AnalogOut( name = 'cooling_sideband_frequency', parent_device = ni_pci_6723_dev3, connection = 'ao2' ) DigitalOut( name = 'two_color_chirp', parent_device = ni_pci_6284_dev6, connection = 'port0/line5' )
def __init__(self, name, parent_device, connection, com_port): DigitalOut.__init__(self, name, parent_device, connection) self.BLACS_connection = com_port self.duration = None
) # same as above, but we are changing some parameters used in the conversion and # specifying a prefix to be used with units. You can now program in mA, uA, mGauss, # uGauss AnalogOut( name="analog1", parent_device=ni_card_1, connection="ao1", unit_conversion_class=example1, unit_conversion_parameters={"a": 5, "b": 1, "magnitudes": ["m", "u"]}, ) AnalogOut(name="analog2", parent_device=ni_card_0, connection="ao2") AnalogOut(name="analog3", parent_device=ni_card_0, connection="ao3") AnalogIn(name="input1", parent_device=ni_card_0, connection="ai0") DigitalOut(name="do0", parent_device=ni_card_0, connection="port0/line2") Shutter( name="shutter1", parent_device=ni_card_0, connection="port0/line1", delay=(0, 0) ) Shutter( name="shutter2", parent_device=pulseblaster_0.direct_outputs, connection="flag 2", delay=(0, 0), ) DigitalOut( name="switch", parent_device=pulseblaster_0.direct_outputs, connection="flag 4" ) DDS(name="dds1", parent_device=novatechdds9m_0, connection="channel 0") DDS(name="dds2", parent_device=novatechdds9m_0, connection="channel 1")
def do_checks(self, *args): if not self.t0 in self.instructions: self.go_low(self.t0) DigitalOut.do_checks(self, *args)
# Use a virtual, or 'dummy', device for the psuedoclock DummyPseudoclock(name='pseudoclock') # An output of this DummyPseudoclock is its 'clockline' attribute, which we use # to trigger children devices DummyIntermediateDevice(name='intermediate_device', parent_device=pseudoclock.clockline) # Create an AnalogOut child of the DummyIntermediateDevice AnalogOut(name='analog_out', parent_device=intermediate_device, connection='ao0') # Create a DigitalOut child of the DummyIntermediateDevice DigitalOut(name='digital_out', parent_device=intermediate_device, connection='port0/line0') # Begin issuing labscript primitives # A timing variable t is used for convenience # start() elicits the commencement of the shot t = 0 add_time_marker(t, "Start", verbose=True) start() # Wait for 1 second with all devices in their default state t += 1 # Change the state of digital_out, and denote this using a time marker add_time_marker(t, "Toggle digital_out (high)", verbose=True) digital_out.go_high(t)
class AgilentE4422B(IntermediateDevice): description = 'Agilent RF Signal Generator' allowed_children = [StaticAnalogQuantity] generation = 2 @set_passed_properties(property_names = { "connection_table_properties": ["com_port"]} ) def __init__(self,name,parent_device,com_port='COM1',FMSignal=None,RFOnOff=None,freq_limits = None,freq_conv_class = None,freq_conv_params = {},amp_limits=None,amp_conv_class = None,amp_conv_params = {},phase_limits=None,phase_conv_class = None,phase_conv_params = {}): #self.clock_type = parent_device.clock_type # Don't see that this is needed anymore IntermediateDevice.__init__(self,name,parent_device) self.BLACS_connection = com_port self.sweep_dt = 2e-6 self.RFSettings = { 'freq': 0, 'amp': 0, 'phase': 0, 'freq_dev':0 ##EE } self.sweep_params = { # 'type': None, 'low': 0, 'high': 1, 'duration': 0, # 'falltime': 0, 'sample_rate': self.sweep_dt } self.sweep = False self.ext_in = False self.frequency = StaticAnalogQuantity(self.name+'_freq',self,'freq',freq_limits,freq_conv_class,freq_conv_params) self.amplitude = StaticAnalogQuantity(self.name+'_amp',self,'amp',amp_limits,amp_conv_class,amp_conv_params) self.phase = StaticAnalogQuantity(self.name+'_phase',self,'phase',phase_limits,phase_conv_class,phase_conv_params) self.FMSignal = {} self.RFOnOff = {} if FMSignal: if 'device' in FMSignal and 'connection' in FMSignal: self.FMSignal = AnalogOut(self.name+'_FMSignal', FMSignal['device'], FMSignal['connection']) else: raise LabscriptError('You must specify the "device" and "connection" for the analog output FMSignal of '+self.name) else: raise LabscriptError('Expected analog output for "FMSignal" control') if RFOnOff: if 'device' in RFOnOff and 'connection' in RFOnOff: self.RFOnOff = DigitalOut(self.name+'_RFOnOff', RFOnOff['device'], RFOnOff['connection']) else: raise LabscriptError('You must specify the "device" and "connection" for the digital output RFOnOff of '+self.name) else: raise LabscriptError('Expected digital output for "RFOnOff" control') def reset(self, t): self.FMSignal.constant(t,-1) return t def synthesizeRF(self, t, freq, amp, ph, freqUnits=None, ampUnits=None, phaseUnits=None): self.RFSettings['freq'] = freq self.RFSettings['amp'] = amp self.RFSettings['phase'] = ph self.sweep = False self.ext_in = False self.FMSignal.constant(t,0) self.RFOnOff.go_high(t) return t def synthesizeRF_ext(self, t, freq, amp, ph, freq_dev, freqUnits=None, ampUnits=None, phaseUnits=None): self.RFSettings['freq'] = freq self.RFSettings['amp'] = amp self.RFSettings['phase'] = ph self.RFSettings['freq_dev'] = freq_dev ##EE self.sweep = False self.ext_in = True self.FMSignal.constant(t,0) #when plugged into the feedforward, needs to be set to 0.017 to account for some offset self.RFOnOff.go_high(t) return t def sweepRF(self, t, duration, low_freq, high_freq, sample_rate, amp): center_freq = np.mean([low_freq,high_freq]) for dev_freq_range in max_deviations: if center_freq > dev_freq_range['low'] and center_freq <= dev_freq_range['high']: deviation = high_freq - center_freq if deviation > dev_freq_range['dev']: raise LabscriptError('Frequency deviation is too high. For a center frequency of '+str(center_freq)+' MHz, the maximum deviation is '+str(dev_freq_range['dev'])+' MHz ('+str(deviation)+' MHz requested)') self.sweep_params['duration'] = duration self.sweep_params['low'] = low_freq self.sweep_params['high'] = high_freq self.sweep_params['sample_rate'] = sample_rate self.RFSettings['freq'] = center_freq self.RFSettings['amp'] = amp self.RFSettings['phase'] = 0 self.sweep = True self.RFOnOff.go_high(t) self.FMSignal.ramp(t,duration=duration,initial=-1.03,final=1.08,samplerate=sample_rate) #To account for the gain of the feedforward box: initial=-0.085 and +final=+1 self.RFOnOff.go_low(t+duration) return t+duration def generate_code(self, hdf5_file): IntermediateDevice.generate_code(self, hdf5_file) if len(self.child_devices) != 3: raise LabscriptError("Wrong number of child_devices. This device expects exactly 3 children") grp = hdf5_file.create_group('/devices/'+self.name) profile_dtypes = [('freq',np.float), ('phase',np.float), ('amp',np.float), ('ext_in',bool), #EE ('freq_dev',np.float)] #EE profile_table = np.zeros(1, dtype=profile_dtypes) profile_table['freq'] = self.RFSettings['freq'] profile_table['amp'] = self.RFSettings['amp'] profile_table['phase'] = self.RFSettings['phase'] profile_table['ext_in'] = 0 ##EE profile_table['freq_dev'] = 0 #EE ## Emily edit if self.ext_in: profile_table['ext_in'] = 1 profile_table['freq_dev'] = self.RFSettings['freq_dev'] grp.create_dataset('RF_DATA',compression=config.compression,data=profile_table) if self.sweep: sweep_dtypes = [('sweep_low',np.float), ('sweep_high',np.float), ('sweep_duration',np.float), ('sweep_samplerate',np.float)] sweep_table = np.empty(1, dtype=sweep_dtypes) # sweep_table['sweep_type'] = sweep_types[output.sweep_params['type']] sweep_table['sweep_low'] = self.sweep_params['low'] sweep_table['sweep_high'] = self.sweep_params['high'] sweep_table['sweep_duration'] = self.sweep_params['duration'] # sweep_table['sweep_falltime'] = output.sweep_params['falltime'] sweep_table['sweep_samplerate'] = self.sweep_params['sample_rate'] grp.create_dataset('SWEEP_DATA',compression=config.compression,data=sweep_table)