-
Notifications
You must be signed in to change notification settings - Fork 2
Instructions
1. Setting up your general_config file
4. How to equalize power for same bifurcation levels of KIDs
Step 0.
-
Start up the TUI with python kidPy.py (sudo may be required). You will be greeted with the following prompt. For the most part, you just follow through the prompted options of kidPy in order.
-

Step 1.
- Upload firmware to the Roach by typing 1 and pressing enter.
Step 2.
- Initialize system and UDP connection by typing 2 and pressing enter.
Step 3.
- Write a test comb by typing 3 and pressing enter. Type "y" and enter when prompted for full comb. At this point, the roach should start streaming packets to the computer. You can check that this is happening using option 9 or with a program like wireshark.
Step 4.
- Take a VNA sweep. type 10 to and enter to take a VNA sweep. This will use the test comb to do a quick VNA sweep that can be used to locate resonators.
Step 5.
- Find resonators using the VNA sweep. type 11 and press enter. You will be greeted with several plots the final of which will show you where the automatic resonance finding program has identified resonators for you. You can use python's interactive plots to go through and check the VNA sweep. Resonators can be deleted by holding control and left clicking near found resonances and resonators can be added by holding shift and right clicking anywhere on the plot. When finished simply close all of the plots.
Step 6.
- Write the tones to the Roach board for your recently found resonances. Type 12 and press enter. This will write one tone per found resonance.
Step 7.
- Target sweep. Now type 13 to do a target sweep and plot the results. The plot will display a sweep around each targeted resonance frequency in both magnitude space and iq space. You can toggle through which resonator is plotted using the left and right arrows on your keyboard.
The folder scripts in kidPy contain some additional scripts that you can use by choosing option 16 Execute a script from the TUI. A description of these scripts is below.
-
fine_gain.py This script takes two target sweeps one with a small span that samples the resonator loop well and the other is a larger gain scan that samples gain variation and the effects of cable delay.
- You can change the spans and step size as necessary by directly editing the script.
- If you select fit_scans = True in the script, after finishing taking the data it will run a fitter over the iq sweeps outputting plots both of the fits and a summary plot fit_results.pdf that will display frequencies, Qs, and the non-linearity parameter a for all the resonators. In addition, it will output .csv and .npy files containing all of the fitted parameters. These files can be found in the fine scan's output directory.
-
tune_min.py and tune_max_didq.py These scripts look at the last target sweep and change the frequencies in the comb to be the minimum of each resonator from the last target sweep or for tune_max_didq.py to the frequency that has the maximum separation in IQ space from adjacent frequency points. By default, it will bring up an interactive plot where you can scroll through the resonators by pressing the left and right arrows on your keyboard and you can change the number of points around the old center frequency to look for the new optimized value by pressing the up and down arrows on your keyboard. In addition, you can hold shift and right click on the magnitude plot to override the automatically picked frequency for any of the points shown on the plot.
- By default, it tries to apply the last transfer function.
-

-
some additional scripts are discussed in section 4 for normalizing bifurcation powers.
TUI option 5 Apply inverse transfer function allows you to apply a transfer function to normalize the tone powers so that they are all at the same level. However, for taking noise data in the lab or for observing at the telescope you often want to drive all of the resonators at maximum power. Often this is just a little below bifurcation of the resonator. This maximizes the clearance of your detector noise compared to the noise of your amplifier. For various reasons you may find that all of your resonators do not bifurcate at the exact same drive power. In this case, you would like to normalize the tone powers so that they all bifurcate at the same power for a given digital attenuator setting.
kidPy contains extra scripts to allow you to do just that.
Warning the analysis code has dependencies on a different github repository located here submm_python_routines you will need to clone it and put it in your python path
Step 0.
- Before starting, make sure you are at the temperature you want to operate at and have all of your coax lines, attenuators, filters, and amplifiers, configured as you want them to stay. Changing these may change the transfer function of your system invalidating the inverse transfer function you calculate.
Step 1. Take a power sweep. -You want to take a power sweep. This is an iq sweep both a fine sweep and a gain (coarse) sweep at a range of power levels going from reasonably below bifurcation for every resonator to above bifurcation for every resonator.
-
This is accomplished with the script power_sweep.py
-
Activate it by choosing option 16 Execute a script from the TUI and typing power_sweep.py when prompted
-
Before running power_sweep.py open the script and configure the gain and fine sweep parameters and the power levels that you want to sweep over within the script
-
Currently power_sweep.py is only set up for labbrick attenuators. When I get my hands on a Rudat I will try to make it compatible with either.
-
Step 2. Fit the nonlinearity parameter and choose power levels.
-
Now you want to fit the nonlinearity parameter as a function of power.
-
This is accomplished with the script analyze_power_sweep_interactive.py
- Call this function with python outside of the TUI in a directory where you would like it to store plots and output transfer functions.
-
This script will output fits for all of the resonators of the non-linearity parameter a versus digital attenuator power.
-
Fitting is done both in magnitude space and IQ space. Fitting in magnitude space tends to be more reliable so the program uses the magnitude fits to produce an inverse transfer function that normalizes all of the tone powers so that all of the resonators will all bifurcate at the same power as set by your digital attenuator.
-
Since the fitting never works perfectly, after the data have been analyzed an interactive plot will pop up. You can scroll through the resonators by pushing the left and right arrows on the keyboard and you can change the plotted power level by pushing the up and down arrows on the keyboard. If you see that the program has chosen the wrong power you can override that choice by either holding shift and right clicking on the bottom plot where you would like the chosen power to be or you can hold shift and press enter to choose the currently displayed power level as the chosen power level. A screenshot of this interface is shown below.
-

Step 3. Take output trans_func and apply it to the frequency comb
-
Now you want to apply the transfer function you derived to the systems frequency comb.
-
This is accomplished with the script apply_custom_transfunc.py
- Edit transfunc_filename in the top of the script to the name of the transfunc analyze_power_sweep produced.
- Select option 16 Execute a script from the TUI and type apply_custom_transfunc.py when prompted
-
Your transfer function should be applied.
- One way to confirm that it is being applied is to watch the output of the Downsampled Channel Magnitudes (option 3 of kidPy.py plot)
-
Test your transfer function by doing a second power_sweep or a fine_gain.py with analyze = True looking at the output fit_results.pdf to see if all resonators have the same non-linearity parameter (plot on page 3)
-
PYTHONPATH issues with sudo
- sudo doesn't preserve your pythonpath. I fixed this with the line below in my .bashrc
- alias sudo='sudo PYTHONPATH=$PYTHONPATH'
-
Non Roach Packet received
- This happens to me every time I restart the computer because it resets my mtu on my ethernet for receiving UDP packets
- sudo ifconfig eth1 -mtu 9000
- change permanently by adding mtu 9000 below iface eth1 inet static in etc/network/interfaces
- Also check that your mac address and ip address that receives the UDP packets are correct in your general_config.
- Wireshark is also helpful to see if packets are being transmitted or not.
-
Dropping Packets
- If you see missing data in your time series you are probably dropping packets. The best way to check this is to look at the output of the streaming data time and packet_count files. If you use read_multitone.read_stream() from https://github.com/GlennGroupUCB/submm_python_routines it should auto warn you that you are dropping packets. Otherwise read in the time and packet_count files and plot the delta between points.
plt.plot((time-np.roll(time,1))[1:])
plt.plot((packet_count-np.roll(packet_count,1))[1:])-
If the second plot shows any variation from 1 packet you have dropped packets. Next, you want to examine the first plot of the delta time. An example is below
-

* Here there are several instances where the delta t between grabbing packets jumps to ~0.4 seconds. This can happen for a variety of reason but probably the kernel has decided to task this processor with some other task and the grabbing of the packets gets delayed. In this case, our max and default buffer sizes, which you can find with the following command were both 212992 bytes
* `sysctl net.core.rmem_max`
* `sysctl net.core.rmem_default`
* The packet size is 8324 bytes so we had room for 212992/8324 = 25 packets in our buffer. However, we have several delays that are 0.4 seconds long meaning if we are sampling at 488 Hz 0.4*488 = 195 packets accumulated during that time. Since our buffer was only set to 25 packets 170 packets get dropped. In order to fix this, you need to increase your systems buffer size to be greater than the spikes (in packet units) in your delta t plot. In this case, I just increased the buffer size to 25 Mb or 3149 packets with the following commands
* `sudo sysctl -w net.core.rmem_max=26214400`
* `sudo sysctl -w net.core.rmem_default=26214400`
* kidPy will detect this change and change the buffer size accordingly. Note that the buffer will fill up with old packets thus before you take any data you need to clean out the buffer. The kidPy software does this for you, but the larger you make the buffer the more time it will take to clean it out. For this case and the computer at Caltech, it took 20ms to clear out the 25 Mb buffer.
Additionally, to make this change persistent, add these lines to the end of /etc/sysctl.conf(as root)
net.core.rmem_max = 26214400
net.core.rmem_default = 26214400