Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLT Calibration Standards Creation #905

Closed
AceYoung938 opened this issue Apr 29, 2023 · 2 comments
Closed

SOLT Calibration Standards Creation #905

AceYoung938 opened this issue Apr 29, 2023 · 2 comments
Labels
Calibration Is it a bug? To be confirmed if it is a bug or not

Comments

@AceYoung938
Copy link

AceYoung938 commented Apr 29, 2023

class Standards_Creation:
    def __init__(self,open1,short1,load1,open2,short2,load2,thru):
        ##测量标准件s1p->s2p
        self.short_calkit_meas = rf.two_port_reflect(short1, short2)
        self.open_calkit_meas = rf.two_port_reflect(open1, open2)
        self.load_calkit_meas = rf.two_port_reflect(load1, load2)
        self.thru_calkit_meas = thru

    # 传输线创建
    # freq:频率点,offset_delay:时延,offset_loss:损耗,offset_z0:偏移阻抗,port_z0:端口阻抗
    def calkit_offset_line(self,freq, offset_delay, offset_loss, offset_z0, port_z0):
        if offset_delay or offset_loss:
            alpha_l = (offset_loss * offset_delay) / (2 * offset_z0)
            alpha_l *= np.sqrt(freq.f / 1e9)
            beta_l = 2 * np.pi * freq.f * offset_delay + alpha_l # alpha_l和beta_l为偏移因子
            zc = offset_z0 + (1 - 1j) * (offset_loss / (4 * np.pi * freq.f)) * np.sqrt(freq.f / 1e9) # 传输部分的阻抗
            gamma_l = alpha_l + beta_l * 1j #由偏移因子组成的传播常数

            medium = DefinedGammaZ0(frequency=freq, z0=port_z0, Z0=zc, gamma=gamma_l) # 传输媒介创建
            offset_line = medium.line(d=1, unit='m', z0=medium.Z0, embed=True) #创建偏移传输线
            return medium, offset_line
        else:
            medium = DefinedGammaZ0(frequency=freq, Z0=offset_z0)
            line = medium.line(d=0)
            return medium, line

    #
    def calkit_open(self,freq, offset_delay, offset_loss, c0, c1, c2, c3, offset_z0=50, port_z0=50):
        medium, line = self.calkit_offset_line(freq, offset_delay, offset_loss, offset_z0, port_z0)
        if c0 or c1 or c2 or c3:
            poly = np.poly1d([c3, c2, c1, c0])
            capacitance = medium.shunt_capacitor(poly(freq.f)) ** medium.open()
        else:
            capacitance = medium.open() # 理想的标准
        return line ** capacitance


    def calkit_short(self,freq, offset_delay, offset_loss, l0, l1, l2, l3, offset_z0=50, port_z0=50):
        medium, line = self.calkit_offset_line(freq, offset_delay, offset_loss, offset_z0, port_z0)
        if l0 or l1 or l2 or l3:
            poly = np.poly1d([l3, l2, l1, l0])
            inductance = medium.inductor(poly(freq.f)) ** medium.short()
        else:
            inductance = medium.short()
        return line ** inductance


    def calkit_load(self,freq, offset_delay=0, offset_loss=0, offset_z0=50, port_z0=50):
        medium, line = self.calkit_offset_line(freq, offset_delay, offset_loss, offset_z0, port_z0)
        load = medium.match()
        return line ** load


    def keysight_calkit_thru(self,freq, offset_delay=0, offset_loss=3.554e9, offset_z0=50, port_z0=50):
        medium, line = self.calkit_offset_line(freq, offset_delay, offset_loss, offset_z0, port_z0)
        thru = medium.thru()
        return line ** thru

    def Standards_create(self,startFreq,stopFreq,pointNum,unit='hz'):
        freq = rf.Frequency(startFreq, stopFreq, pointNum,unit)
        open_std = self.calkit_open(
            freq,
            offset_delay=20.837e-12, offset_loss=3.230e9,
            c0=29.72e-15, c1=165.780e-27, c2=-3.539e-36, c3=0.071e-45
        )
        short_std = self.calkit_short(
            freq,
            offset_delay=22.548e-12, offset_loss=3.554e9,
            l0=2.164e-12, l1=-146.350e-24, l2=4.044e-33, l3=-0.036e-42
        )
        load_std = self.calkit_load(freq)
        thru_std = self.keysight_calkit_thru(freq)
        ##标准校准件s1p->s2p
        short_s2p = rf.two_port_reflect(short_std, short_std)
        open_s2p = rf.two_port_reflect(open_std, open_std)
        load_s2p = rf.two_port_reflect(load_std, load_std)


        my_ideals = [
            short_s2p,
            open_s2p,
            load_s2p,
            thru_std,
        ]
        my_measured = [
            self.short_calkit_meas,
            self.open_calkit_meas,
            self.load_calkit_meas,
            self.thru_calkit_meas,
        ]
        # 计算误差项并导出

        # create a SOLT instance9
        cal = SOLT(
            ideals=my_ideals,
            measured = my_measured,
        )
       cal.run()
        try:
            rf.write('cal.coef', cal.coefs)
        except:
            pass
        return cal,1  # 1为校准完成标志`

(main_fuction)
      `self.caled_ntwk = self.cal.apply_cal(dut_ntwk)

I imitated the example in the document to create the model of the calibration part. My calibration part is Agilent's 85056D, but the final calibration result is not ideal. The 'DUT_no_image' picture is the uncalibrated amplitude map of the tested part, and the 'VNA_image' is used The amplitude graph obtained by the calibration of the vector network analyzer in the laboratory, 'MY_image' is the amplitude graph obtained after I calibrated the calibration model with code.

DUT_NO.txt is the uncalibrated S parameter, VNA_measure.txt is the calibrated S parameter of the vector network analyzer in the laboratory, and 4_26myMeasure.txt is the result of my code calibration.

4_26myMeasure.txt
DUT_NO.txt
VNA_measure.txt

DUT_no_image
MY_image
VNA_image

@AceYoung938
Copy link
Author

I solved this problem. My code is correct. The vector network analyzer in the laboratory is broken, which leads to incorrect results

@jhillairet
Copy link
Member

can you close the issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Calibration Is it a bug? To be confirmed if it is a bug or not
Projects
None yet
Development

No branches or pull requests

2 participants