qkitgroup / qkit

Qkit framework
GNU General Public License v2.0
43 stars 46 forks source link

Negative Qi (intrinsic quality factor) #88

Closed DaBiebs closed 2 years ago

DaBiebs commented 2 years ago
# open h5 data and fit
res = Resonator(h5_name)
res.fit_circle(notch=True, f_min=min(frq), f_max=max(frq))

# extract fit parameters
c = res._circle_port
fr = c.fr;
ql = c.fitresults['Ql'];
qc = c.fitresults['Qc']
qi = c.fitresults['Qi']

This is loosely my implementation using the Resonator class that wraps circuit.py. My Ql comes out to ~ 60,000, which is reasonable. However, Qc and Qi don't make sense, and appear to be derived from Ql. Below are lines 209-212 in circuit.py, which show the other 2 Q's being derived.

self.absQc = self.Ql / (self.n_ports*self.r0)
# For Qc, take real part of 1/(complex Qc) (diameter correction method)
self.Qc = self.absQc / np.cos(self.phi)
self.Qi = 1. / (1./self.Ql - 1./self.Qc)

Both of these derivations appear correct, but Qc comes out LESS than Ql. This means that in the next step, Qi comes out negative. Based on this paper that we have been following, this shouldn't be possible. Any ideas/suggestions?

sebastianprobst commented 2 years ago

Hi, without seeing your data and fit, I can only speculate... Here are some thoughts:

If you are struggeling with a "wiggly" baseline, I have added some methods in the resonator-tools package that may help you to fit the baseline and normalize it. Furthermore, there is a rudementary GUI available that may help you to interactively fit your data and find potential problems, see examples in the my github repository.

DaBiebs commented 2 years ago

image

@sebastianprobst Thanks for the response! Above is a fit with some dummy data i generated as shown below. The dummy data is definitely oversimplified, but this creates the case i'm seeing with my real data. With the dummy data below and the fit shown above, Qi = -907828; Qc = 33881; Ql = 35194.

I'm unsure why this is happening or if i'm somehow violating a constraint that should be a given... Thoughts?

# resonator parameters
frq_low = 4.999e9
frq_high = 5.001e9
frq_steps = 1e3
amp = 50
fr = 5e9
fwhm = 100e3
phase_offset = 0
mag_offset = amp
ql = 80e3
pwr = 5         # we don't care about this

# generate frequency and magnitude response
frq = np.arange(frq_low, frq_high, frq_steps)
l = mods.Lorentz1D(amp, fr, fwhm)
mag = -l(frq) + mag_offset

# generate phase response
tan = 2 *ql * (1 - frq/fr)
theta = phase_offset + 2 * np.arctan(tan)

# create hdf5 file
h5_name = dummy_dir + 'dummy' + '.hdf5'
u.arr_to_h5(h5_name, pwr, frq, mag, theta)

# open h5 data and fit
res = Resonator(h5_name)
res.fit_circle(notch=True, f_min=frq_low, f_max=frq_high)
c = res._circle_port
c.plotall()
sebastianprobst commented 2 years ago

Thank you for providing the plots. Your raw data is not circular but rather "heart-shaped". Something is definitely wrong with your data or there are additional effects. What happens is that the algorithm tries to fit a circle anyway which makes the fitted circle cross the origin. This makes the diameter of the circle larger than the dip in the amplitude, here approximately 50, which is unphysical. This then automatically leads to negative Qi. The diameter of the circle can only be smaller or equal than the amplitude value off-resonance, i.e. the "baseline" of the amplitude plot.

Schneider1 commented 2 years ago

I close this issue as it seems that the problem is rather related to the data than the code. Please feel free to re-open it, if you see any changes in the code to be made or if you need more assistance.