T_make_sys_ADY

test.ASC_SOLVER.T_make_sys_ADY

This File has the sole purpose of creating the ASC DHARD Y Model that is then exported to the buzz repository.

pytest-html report

Functions

FBNSSS_DARM([return_name, return_scale, ...])

FBNSSS_Fit([gain, return_name, return_scale])

FBNSSS_Hand([return_name, return_scale, as_zpk])

FBNSsimpSS([return_name, lo_ord, ...])

This is a pytest needing documentation

FFlatSS([gain, return_name])

This is a pytest needing documentation

addSS([namespace, dt, sub, outSufx])

Create a state space model for an adder.

delayDrive([namespace, Sp, delay, order, ...])

This is a pytest needing documentation

delaySS([namespace, delay, order, numins, dt])

Create a state space model for the delay block.

nullSS([namespace, gain])

Create a state space model for the null block.

test_Make_ADY(folder)

This is the main function that is called to create the model for the ASC DHARD Y.

Details

FBNSSS_DARM(return_name=False, return_scale=False, as_zpk=False, normalize=True)[source]
code
docstring
"""
"""
 1def FBNSSS_DARM(
 2    return_name=False,
 3    return_scale=False,
 4    as_zpk=False,
 5    normalize=True,
 6):
 7
 8    if return_name:
 9        name = "FOM BNS (Hand Fit)"
10        return name
11
12    #BNS_zpk = file_io.load(fjoin('ExampleModels_DARMFOM/BNS_FOM_from_DARM.yml'))
13    BNS_zpk = file_io.load(fjoin('ExampleModels_DARMFOM/BNS_FOM_IR.yml'))
14    F_z = np.array(BNS_zpk["z"], dtype=np.complex128)
15    F_p = np.array(BNS_zpk["p"], dtype=np.complex128)
16    F_k = BNS_zpk["k"]
17
18    F_zpk = SISO.zpk(F_z, F_p, F_k)
19    F = F_zpk.asSS.mimo("FBNS.out", "FBNS.in")
20    if not normalize:
21        return F
22    F, scale = ssutil.normalize_gain(F, norm=1, return_scale=True)
23    if as_zpk:
24        return F_zpk * scale
25    if return_scale:
26        return scale
27    else:
28        return F
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.FBNSSS_DARM

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

FBNSSS_Fit(gain=1, return_name=False, return_scale=False)[source]
code
docstring
"""

"""
 1def FBNSSS_Fit(gain=1, return_name=False, return_scale = False):
 2
 3    if return_name:
 4        name = "FOM BNS"
 5        return name
 6
 7    if gain != 1:
 8        NotImplementedError("This function does not support gain scaling")
 9
10    BNS_zpk = file_io.load(fjoin('ExampleModels_newFOM/BNS_FOM.yml'))
11    print(BNS_zpk['z'])
12    F_z = np.array(BNS_zpk["z"], dtype=np.complex128)
13    #BNS_zpk["p"].append(BNS_zpk["p"][-1])
14    F_p = np.array(BNS_zpk["p"], dtype=np.complex128)
15    F_k = BNS_zpk["k"]
16
17    #print(len(F_z))
18    #print(len(F_p))
19    F_mod = SISO.zpk(F_z, F_p, F_k).asSS
20    F_iod = {"FBNS.in": 0, "FBNS.out": 0}
21    F = ssutil.wieldSS(F_mod.A, F_mod.B, F_mod.C, F_mod.D, iod=F_iod)
22    F, scale = ssutil.normalize_gain(F, norm=1, return_scale=True)
23    if return_scale:
24        return scale
25    else:
26        return F
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.FBNSSS_Fit

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

FBNSSS_Hand(return_name=False, return_scale=False, as_zpk=False)[source]
code
docstring
"""

"""
 1def FBNSSS_Hand(return_name=False, return_scale = False, as_zpk=False):
 2
 3    if return_name:
 4        name = "FOM BNS (Hand Fit)"
 5        return name
 6
 7    BNS_zpk = file_io.load(fjoin('ExampleModels_newFOM/BNS_FOM_handfit.yml'))
 8    F_z = np.array(BNS_zpk["z"], dtype=np.complex128)
 9    F_p = np.array(BNS_zpk["p"], dtype=np.complex128)
10    F_k = BNS_zpk["k"]
11
12    F_zpk = SISO.zpk(F_z, F_p, F_k)
13    F = F_zpk.asSS.mimo("FBNS.out", "FBNS.in")
14    F, scale = ssutil.normalize_gain(F, norm=1, return_scale=True)
15    if as_zpk:
16        return F_zpk * scale
17    if return_scale:
18        return scale
19    else:
20        return F
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.FBNSSS_Hand

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

FBNSsimpSS(return_name=False, lo_ord=4, return_scale=False, as_zpk=False)[source]

This is a pytest needing documentation

code
 1def FBNSsimpSS(return_name=False, lo_ord=4, return_scale=False, as_zpk = False):
 2    if return_name:
 3        name = "FOM BNS Simple"
 4        return name
 5
 6    BNS_zpk = file_io.load(fjoin('FOMs/FBNSsimp_FOM.yml'))
 7    print(BNS_zpk['z'])
 8    F_z = np.array(BNS_zpk["z"], dtype=np.complex128)
 9    F_p = np.array(BNS_zpk["p"], dtype=np.complex128)
10    F_k = BNS_zpk["k"]
11
12    F_zpk = SISO.zpk(F_z, F_p, F_k)
13    F = F_zpk.asSS.mimo("FBNS.out", "FBNS.in")
14    F, scale = ssutil.normalize_gain(F, norm=1, return_scale=True)
15    if as_zpk:
16        return F_zpk * scale
17    if return_scale:
18        return scale
19    else:
20        return F
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.FBNSsimpSS

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

FFlatSS(gain=1, return_name=False)[source]

This is a pytest needing documentation

code
1def FFlatSS(gain=1, return_name=False):
2    if return_name:
3        name = "FOM Flat"
4        return name
5
6    return SISO.zpk([], [], gain).asSS.mimo("F2.out", "F2.in")
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.FFlatSS

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

addSS(namespace='T', dt=0.0001, sub=False, outSufx=None)[source]

Create a state space model for an adder. It has two inputs and one output.

Parameters:
  • namespace (string) – The namespace to use for the model i.e. the letter that comes at the beginning of the input and output names. Defaults to ‘T’.

  • dt (float, optional) – The time step. Defaults to 1e-4.

  • sub (bool, optional) – If true, the model will be a subtractor. Defaults to False.

Returns:

Returns the local name space for the function including the state space model as mod, input output dictionary as iod, and namespace.

Return type:

wield.bunch

code
docstring
"""Create a state space model for an adder. It has two inputs and one output.

Args:
    namespace (string): The namespace to use for the model i.e. the letter that comes at the beginning of the input and output names. Defaults to 'T'.
    dt (float, optional): The time step. Defaults to 1e-4.
    sub (bool, optional): If true, the model will be a subtractor. Defaults to False.

Returns:
    wield.bunch: Returns the local name space for the function including the state space model as `mod`, input output dictionary as `iod`, and namespace.
"""
 1def addSS(namespace='T', dt=1e-4, sub=False, outSufx = None):
 2
 3    A = np.zeros([0,0]) # Construct the A state matrix
 4    B = np.zeros([2,0]) # Construct the B state matrix
 5    C = np.zeros([0,1]) # Construct the C state matrix
 6    if sub:
 7        D = np.array([[1, -1]]) # Construct the D state matrix for a subtractor
 8    else:
 9        D = np.array([[1, 1]]) # Construct the D state matrix
10    if outSufx == None:
11        iod = {namespace+'.in.1': 0, namespace+'.in.2': 1, namespace+'.out': 0} # Input output dictionary
12    else:
13        iod = {namespace+'.in.1': 0, namespace+'.in.2': 1, namespace+'.out.'+outSufx: 0} # Input output dictionary
14    return ssutil.wieldSS(A, B, C, D, iod=iod)
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.addSS

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

delayDrive(namespace='D', Sp=None, delay=0.001, order=1, numins=1, dt=0.0001)[source]

This is a pytest needing documentation

code
 1def delayDrive(namespace='D', Sp=None, delay=1e-3, order=1, numins=1, dt=1e-4):
 2    D = delaySS(namespace=namespace, delay=delay, order=order, numins=numins, dt=dt)
 3
 4    if Sp is None or Sp == 1:
 5        #assert(False)
 6        return D
 7
 8    #rename the input for pending merge
 9    D.iod[namespace + '.in.2'] = D.iod[namespace + '.in']
10    del D.iod[namespace + '.in']
11
12    #check that it only has 1 input and one output (THIS IS A HACKY WAY TO TEST)
13    assert(len(Sp.iod) == 2)
14
15    print(Sp.iod)
16    Sp.iod.clear()
17    Sp.iod[namespace + '.in'] = 0
18    Sp.iod[namespace + '.out.1'] = 0
19    print(Sp.iod)
20
21    Dx = ssutil.multiconnect([Sp, D], [[namespace+'.in.2', namespace+'.out.1']])
22    print(Dx.iod)
23    return Dx
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.delayDrive

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

delaySS(namespace='D', delay=0.001, order=1, numins=1, dt=0.0001)[source]

Create a state space model for the delay block. It has one input and one output.

Parameters:
  • namespace (str, optional) – The namespace for the delay block. Defaults to ‘D’.

  • delay (_type_, optional) – The delay in seconds. Defaults to 1e-3.

  • order (int, optional) – Order of the filter. Defaults to 1.

  • numins (int, optional) – Number of inputs. Defaults to 1.

  • dt (_type_, optional) – The discretization time step. Defaults to 1e-4.

Returns:

Returns the local name space for the function including the state space model as mod, input output dictionary as iod, and namespace.

Return type:

wield.bunch

code
docstring
"""Create a state space model for the delay block. It has one input and one output.

Args:
    namespace (str, optional): The namespace for the delay block. Defaults to 'D'.
    delay (_type_, optional): The delay in seconds. Defaults to 1e-3.
    order (int, optional): Order of the filter. Defaults to 1.
    numins (int, optional): Number of inputs. Defaults to 1.
    dt (_type_, optional): The discretization time step. Defaults to 1e-4.

Returns:
    wield.bunch: Returns the local name space for the function including the state space model as `mod`, input output dictionary as `iod`, and namespace.
"""
 1def delaySS(namespace='D', delay=1e-3, order=1, numins=1, dt=1e-4):
 2
 3    if delay==0:
 4        print('Delay is zero, using nullSS')
 5        D_mod = nullSS().mod
 6    else:
 7        # take the poles of this normalized bessel filter (delay=1s)
 8        z, p, k = scipy.signal.besselap(order, norm="delay")
 9
10        # now rescale for desired delay
11        roots = p / delay * 2
12        if order % 2 == 0:
13            k = 1
14        else:
15            k = -1
16
17
18        D_mod = SISO.zpk(-roots.conjugate(), roots, k).ss
19        # D_res = control.zpk(-roots.conjugate(), roots, k)
20        # D_mod = control.tf2ss(D_res)
21
22    B_blocked = D_mod.B
23    D_blocked = D_mod.D
24    for ii in range(numins-1):
25        B_blocked = np.block([[B_blocked, D_mod.B]])
26        D_blocked = np.block([[D_blocked, D_mod.D]])
27
28    mod = control.ss(D_mod.A, B_blocked, D_mod.C, D_blocked) # Create the system
29    mod_dis = control.c2d(mod, dt) # Discretize the system
30    iod = dict({namespace+'.in': 0, namespace+'.out': 0}) # Input output dictionary
31    for ii in range(numins-1):
32        iod[namespace+'.in.'+str(ii+1)] = ii+1
33
34    return Bunch(locals())
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.delaySS

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

nullSS(namespace='N', gain=1)[source]

Create a state space model for the null block. It has one input and one output.

Parameters:
  • namespace (str, optional) – The namespace to use for the model i.e. the letter that comes at the beginning of the input and output names. Defaults to ‘N’.

  • gain (float, optional) – The gain of the null block. Defaults to 1.

Returns:

Returns Wield MIMO statespace

Return type:

MIMO Statespace

code
docstring
"""Create a state space model for the null block. It has one input and one output.

Args:
    namespace (str, optional): The namespace to use for the model i.e. the letter that comes at the beginning of the input and output names. Defaults to 'N'.
    gain (float, optional): The gain of the null block. Defaults to 1.

Returns:
    MIMO Statespace: Returns Wield MIMO statespace
"""
1def nullSS(namespace='N', gain=1):
2
3
4    A = np.zeros([0,0]) # Construct the A state matrix
5    B = np.zeros([1,0]) # Construct the B state matrix
6    C = np.zeros([0,1]) # Construct the C state matrix
7    D = np.array([[gain]]) # Construct the D state matrix 
8    iod = dict({namespace+'.in': 0, namespace+'.out': 0}) # Input output dictionary
9    return ssutil.wieldSS(A, B, C, D, iod=iod)
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.nullSS

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

test_Make_ADY(folder)[source]

This is the main function that is called to create the model for the ASC DHARD Y.

code
docstring
"""
This is the main function that is called to create the model for the ASC DHARD Y.
"""
  1@pytest.mark.parametrize(
  2    'folder', [
  3        'ExampleModels_working',
  4        'ExampleModels_working_F3',
  5        'ExampleModels_newFOM',
  6        'ExampleModels_newFOM_F3',
  7        'ExampleModels_DARMFOM',
  8        'ExampleModels_DARMFOM_F3',
  9    ]
 10)
 11@pytest.mark.gitlabCI
 12@pytest.mark.ADY
 13def test_Make_ADY(folder):
 14
 15    use_old_balancing = False
 16    # not helpful it seems
 17    use_alt_balancing = False
 18
 19    if use_old_balancing:
 20        from wield.control.utilities import algorithm_choice
 21        # This fix is needed since updating several wield.controls algorithms
 22        algorithm_choice.algorithm_adjust_default('zpk2ss', 'zpk2ss_chain_poly_nobal', 200)
 23
 24    S = ssutil.loadSys(fjoin(folder, 'ADY_E_from_fit.mat'))
 25    S = S.balance(which='ABC')
 26    if use_old_balancing:
 27        S = ssutil.balance_sys_gain(S, verbose=True)
 28    if use_alt_balancing:
 29        S = ssutil.balance_sys_gain(S, method='bfsqrt', verbose=True)
 30        S = S.schur_form()
 31
 32    O = ssutil.loadSys(fjoin(folder, 'ADY_M_from_fit.mat'))
 33    # O = nullSS(namespace='O', gain=5e-5)
 34    print('O.A: ', O.A)
 35    O = O.balance(which='ABC')
 36    if use_old_balancing:
 37        O = ssutil.balance_sys_gain(O, verbose=True)
 38    if use_alt_balancing:
 39        O = ssutil.balance_sys_gain(O, method='bfsqrt', verbose=True)
 40        O = O.schur_form()
 41
 42    # TODO - make solver handle unobserved modes
 43    # can be tested by adding one here
 44    # the plant of the working folder has a nontrivial statespace for some reason even though
 45    # it has a flat response with no poles or zeros
 46    # this ensures an un-observable mode that the solver DOES NOT LIKE
 47    O = O.siso('O.out', 'O.in').asZPK.asSS.mimo('O.out', 'O.in')
 48
 49    P_fname = 'ADY_plant_from_fit.mat'
 50    P = ssutil.loadSys(fjoin(folder, P_fname))
 51    P = P.balance(which='ABC')
 52    #if use_old_balancing:
 53    #    P = ssutil.balance_sys_gain(P, verbose=True)
 54    if use_alt_balancing:
 55        P = ssutil.balance_sys_gain(P, method='bfsqrt', verbose=True)
 56        P = P.schur_form()
 57
 58    # print("plant shape:")
 59    # P.print_nonzero()
 60
 61    # this rescale is still helping the solver (it shouldn't!)
 62    w2_rescale = 1e6
 63    if use_old_balancing:
 64        w2_rescale = 1e6
 65
 66    S = (w2_rescale * S.siso('S.out', 'S.in')).mimo('S.out', 'S.in')
 67    O = (w2_rescale * O.siso('O.out', 'O.in')).mimo('O.out', 'O.in')
 68
 69    if '_newFOM' in folder or '_newFOM_F3' in folder:
 70        FBNS_func = FBNSSS_Hand
 71        FBNS = FBNS_func()
 72        FBNS_zpk = FBNS_func(as_zpk=True)
 73        FBNS_scale = FBNS_func(return_scale=True)
 74
 75    elif 'DARMFOM' in folder:
 76       FBNS_func = FBNSSS_DARM
 77       FBNS = FBNS_func()
 78       FBNS_zpk = FBNS_func(as_zpk=True)
 79       FBNS_scale = FBNS_func(return_scale=True)
 80
 81    else:
 82        FBNS_func = FBNSsimpSS
 83        FBNS = FBNS_func()
 84        FBNS_zpk = FBNS_func(as_zpk=True)
 85        FBNS_scale = FBNS_func(return_scale=True)
 86
 87        omega_limits = [1e-2, 1e4]
 88        axB = ssutil.bode(FBNS.siso('FBNS.out', 'FBNS.in'), omega_limits=omega_limits, label='Simple FBNS')
 89        axB = ssutil.bode(FBNSSS_Hand().siso('FBNS.out', 'FBNS.in'), omega_limits=omega_limits, axB=axB, label='Hand Fit FBNS')
 90        axB = ssutil.bode(FBNSSS_Fit().siso('FBNS.out', 'FBNS.in'), omega_limits=omega_limits, axB=axB, label='FBNS From Data')
 91        axB.save(tjoin('BNS_FOMS_Comp.pdf'))
 92        axB.save(tjoin('BNS_FOMS_Comp.png'))
 93
 94    print("OBS STATESPACE-----------------------------------------------------------")
 95    print(O.print_nonzero())
 96    print("ZP: ", O.siso('O.out', 'O.in').asZPK.zeros, O.siso('O.out', 'O.in').asZPK.poles)
 97    print("/OBS STATESPACE-----------------------------------------------------------")
 98
 99    print("SEI STATESPACE-----------------------------------------------------------")
100    print(S.print_nonzero())
101    print("/SEI STATESPACE-----------------------------------------------------------")
102
103    print("FOM STATESPACE-----------------------------------------------------------")
104    if use_old_balancing:
105        FBNS = ssutil.balance_sys_gain(FBNS, verbose=True)
106    print(FBNS.print_nonzero())
107    print("/FOM STATESPACE-----------------------------------------------------------")
108
109    FFlat = FFlatSS()
110    if use_old_balancing:
111        FFlat = ssutil.balance_sys_gain(FFlat, verbose=True)
112
113    # Inject the coupling into the BNS FOM, normalize it to Hinf=1 and then collect its scale
114    Coup = ssutil.loadSys(fjoin(folder, 'A2L_coupling_with_cal.mat')) # This is the Angle to length coupling it would be multiplied by the BNS FOM
115    if use_old_balancing:
116        Coup = ssutil.balance_sys_gain(Coup, verbose=True)
117    if use_alt_balancing:
118        Coup = ssutil.balance_sys_gain(Coup, method='bfsqrt', verbose=True)
119        Coup = Coup.schur_form()
120    # Coup = SISO.zpk([], [], 1e-14).asSS.mimo('COUP.out', 'COUP.in')
121
122    FBNS_orig = FBNS
123    FBNS = ssutil.multiconnect([Coup, FBNS], [['FBNS.in', 'COUP.out']])
124    #FBNS = ssutil.truncate_io(FBNS, ['COUP.in'], ['FBNS.out', 'COUP.out']) #commented out to display DARM Spectrum
125    FBNS = ssutil.rename_io(FBNS, 'COUP.out', 'FBNS.DARM.out') # to see DARM Spectrum
126    FBNS = ssutil.rename_io(FBNS, 'FBNS.in', 'FBNS.noC.in') # add a bypass coup for the FBNS
127    FBNS = ssutil.rename_io(FBNS, 'COUP.in', 'FBNS.in')
128
129    FBNS_Trash, Coup_scale = ssutil.normalize_gain(ssutil.truncate_io(FBNS, ['FBNS.in'], ['FBNS.out']), norm=1, return_scale=True, method='fq_resp')
130    del FBNS_Trash
131    FBNS = ssutil.scale_io(FBNS, 'FBNS.out', Coup_scale)  # using this to scale preserves the DARM.out output
132    # TODO, comment this for breakage test and  uncomment for typical operation
133    #FBNS = ssutil.scale_io(FBNS, 'FBNS.noC.in', 1/Coup_scale)  # using this to scale preserves the DARM.out output
134    FBNS = ssutil.scale_io(FBNS, 'FBNS.noC.in', 1/Coup_scale * 1/FBNS_scale)  # using this to scale preserves the DARM.out output
135
136    omega_limits_noise = [1e-1, 1e3]
137    axN = ssutil.bode(ssutil.asSISO(ssutil.truncate_io(FBNS, ['FBNS.noC.in'], ['FBNS.out'])), omega_limits=omega_limits_noise, label='FBNS Scaled')
138    axN = ssutil.bode(ssutil.asSISO(FBNS_func(normalize=False)), axB=axN, omega_limits=omega_limits_noise, linestyle='--',label='Unscaled BNS')
139    axN.save(tjoin('FBNS_bode_after_scl.png'))
140    axN.save(tjoin('FBNS_bode_after_scl.pdf'))
141
142    # FBNS_alt = Coup.siso('COUP.out', 'COUP.in') * FBNS.siso('FBNS.out', 'FBNS.in')
143
144    print("FOM STATESPACE-with Coupling---------------------------------------------")
145    print(FBNS.inputs)
146    print(FBNS.print_nonzero())
147    print("/FOM STATESPACE-with coupling---------------------------------------------")
148
149    FBNS_scale = FBNS_scale * Coup_scale
150    np.savetxt(fjoin(folder, 'FBNS_scale.txt'), [FBNS_scale])
151    print('FBNS scale', FBNS_scale)
152
153    current_range = np.loadtxt(fjoin(folder, 'FBNS_Current_range.txt'))  # Saved by the normalization in the make function
154    io_scales = Bunch(
155        FBNS = FBNS_scale,  # will need to apply this to the BNS FOM
156        w2_rescale = w2_rescale,  # will need to divide by this on both FOMs
157        # will need to be applied only to the Flat fom since the A2L_coupling_with_cal includes it as a factor
158        ct2rad = 5.2e-11,  # Calibration from https://alog.ligo-wa.caltech.edu/aLOG/index.php?callRep=69551
159        strain2m = 1/3995,  # Representing the 4km arm length. Strain is h = dL/L where L = 3995 m. The coupling is "I" is
160        # in rad to displacement so we need to convert it to strain for the BNS FOM which is in strain
161        current_range = current_range,
162        coup_scale = Coup_scale,
163    )
164    io_scales.RMS_cal_F1 = 1/io_scales.FBNS * io_scales.strain2m / io_scales.w2_rescale
165    io_scales.RMS_cal_F2 = io_scales.ct2rad / io_scales.w2_rescale
166    file_io.save(fjoin(folder, 'io_scales.yml'), dict(io_scales))
167
168    omega_limits = [1e-2, 1e4]
169
170    omega_limits_noise = [1e-1, 1e3]
171    axN = ssutil.bode(ssutil.asSISO(S), omega_limits=omega_limits_noise, label='Seismic')
172    axN = ssutil.bode(ssutil.asSISO(O), axB=axN, omega_limits=omega_limits_noise, label='Meas. Noise')
173    axN = ssutil.bode(ssutil.asSISO(P), axB=axN, omega_limits=omega_limits_noise, label='Plant')
174    axN = ssutil.bode(ssutil.asSISO(S.siso('S.out', 'S.in') * P.siso('P.out', 'P.in')), axB=axN, omega_limits=omega_limits_noise, label='S*P')
175    axN.save(tjoin('Noise_bode.png'))
176    axN.save(tjoin('Noise_bode.pdf'))
177
178
179    # control.bode(S.mod, dB=False, Hz=True, omega_limits=omega_limits, label='Seismic')
180    # control.bode(O.mod, dB=False, Hz=True, omega_limits=omega_limits, label='Meas. Noise')
181    # control.bode(P.mod, dB=False, Hz=True, omega_limits=omega_limits, label='Plant')
182    # control.bode((S.siso('S.out', 'S.in') * P.siso('P.out', 'P.in')).mimo('out', 'in').mod, dB=False, Hz=True, omega_limits=omega_limits, label='S*P')
183    # plt.legend()
184    # plt.savefig(tjoin('Noise_bode.pdf'), bbox_inches='tight')
185    # plt.savefig(tjoin('Noise_bode.png'), bbox_inches='tight', dpi=300)
186    # plt.close()
187
188    omega_limits_fom = np.array([1e-1, 1e5])*2*np.pi
189    axFOM = ssutil.bode(FBNS.siso('FBNS.out', 'FBNS.in'), omega_limits=omega_limits_fom, label='FBNS')
190    axFOM = ssutil.bode(FFlat.siso(iodutil.listoutputs(FFlat)[0], iodutil.listinputs(FFlat)[0]), axB=axFOM, omega_limits=omega_limits_fom, label='FFlat')
191    axFOM.save(tjoin('FOM_bode.pdf'))
192    axFOM.save(tjoin('FOM_bode.png'))
193    # control.bode(FBNS.mod, dB=True, Hz=True, omega_limits=omega_limits, label='FBNS')
194    # control.bode(FFlat.mod, dB=True, Hz=True, omega_limits=omega_limits, label='FFlat')
195    # plt.legend()
196    # plt.savefig(tjoin('FOM_bode.pdf'))
197    # plt.savefig(tjoin('FOM_bode.png'))
198    # plt.close()
199
200    #make the SO
201    #conlist =[['T_SO.in.1', 'O.out'], ['T_SO.in.2','S.out']]
202    #T_SO = addSS(namespace='T_SO', sub=True)
203    #SO = ssutil.multiconnect([S, O, T_SO], conlist)
204    #SO = ssutil.truncate_io(SO, ['O.in', 'S.in'], ['T_SO.out', 'S.out'])
205    #SO = ssutil.rename_io(SO, 'T_SO.out', 'O.out')
206
207    #control.bode(SO.mod[SO.iod['S.out'], SO.iod['S.in']], dB=True, Hz=True, omega_limits=omega_limits, label='S to S')
208    #control.bode(SO.mod[SO.iod['O.out'], SO.iod['O.in']], dB=True, Hz=True, omega_limits=omega_limits, label='O to O')
209    #control.bode(SO.mod[SO.iod['O.out'], SO.iod['S.in']], dB=True, Hz=True, omega_limits=omega_limits, label='S to O', linestyle='--', linewidth=5)
210    #control.bode(S.mod, dB=True, Hz=True, omega_limits=[1e-2, 1e3], label='Orig. S', linestyle='dotted', linewidth=4)
211    #control.bode(O.mod, dB=True, Hz=True, omega_limits=[1e-2, 1e3], label='Orig. O', linestyle='dotted', linewidth=4)
212    #plt.legend(fontsize=8)
213    #plt.savefig(tjoin('SO_bode.pdf'))
214    #plt.close()
215    SPOFF_kw = {}
216    if '_F3' in folder:
217        extras = 'F3_withP'
218        SPOFF_kw['include_F1'] = False
219        FBNS_eff_in = 'F3.in'
220        FBNS_eff_out = 'F3.out'
221    else:
222        extras = None
223        FBNS_eff_in = 'FBNS.in'
224        FBNS_eff_out = 'FBNS.out'
225
226    # TODO, this will break the solve to use noC.in. but debugging breakage
227    SPOFF = ssutil.makeSPOFF(
228        S, P, O,
229        FBNS,
230        FFlat,
231        diagnostic=True,
232        extras=extras,
233        balance=use_old_balancing,
234        # F1in='FBNS.noC.in',
235        F1in='FBNS.in',
236        F1out='FBNS.out',
237        **SPOFF_kw
238    )
239    SPOFF = SPOFF.topological_sort()
240    SPOFF = SPOFF.balance()
241    # SPOFF = SPOFF.schur_form()
242
243    #print('SPOFF', SPOFF.iod)
244    #SPOFF = ssutil.balance_sys_gain(SPOFF)
245    print("SPOFF STATESPACE-----------------------------------------------------------")
246    try_block_diagonalize = False
247    if try_block_diagonalize:
248        SPOFF = SPOFF.schur_form()
249        print(SPOFF.print_nonzero())
250
251        sr = np.zeros(SPOFF.ss.Nstates, dtype=float)
252        SPOFF_b2 = SPOFF.balance(which='A', Dr=sr)
253        SPOFF_b2 = SPOFF
254
255        from wield.control.ss_bare.ssprint import print_dense_nonzero_A, print_dense_nonzero, nz_int
256        def flog2(arr):
257            #arr = np.asarray(arr)
258            #mant, exp = np.frexp(arr)
259            exp = np.round(np.log2(abs(arr)))
260            return exp
261        sc = np.block([[flog2(sr)]])
262        print("scaling?")
263        print(print_dense_nonzero_A(sc, scaling=nz_int))
264        Tr = np.zeros_like(SPOFF_b2.A)
265        SPOFF_b2 = SPOFF_b2.block_diagonalize(condition_number=1e6, Tright=Tr)
266        print("after balance2")
267        print(SPOFF_b2.print_nonzero())
268        print("Transfer Matrix")
269        print(print_dense_nonzero_A(Tr))
270        # SPOFF = SPOFF_b2
271        print("POLES")
272        print(SPOFF_b2.p)
273    print("/SPOFF STATESPACE-----------------------------------------------------------")
274    omega_limits=[1e-2, 1e3]
275
276    axB = mplfigB(Nrows=2)
277    F_Hz = np.geomspace(1e-2, 20, 1000)
278    with SISObode.multi_bode(axB=axB, F_Hz = F_Hz) as bode:
279        bode(P['P.out', 'P.in'], label='P alone', linewidth=2, color='dodgerblue')
280        bode(SPOFF['P.out', 'P.in'], label='P to P in SPOFF', color='orange')
281        bode(SPOFF['P.out', 'S.in'], label='S to P', color='green')
282        bode(SPOFF['S.out', 'S.in'], label='S to S', linestyle='dotted', linewidth=4, color='green')
283        bode(SPOFF['P.out', 'SA.in'], linestyle='--', label='P Recombined', linewidth=4, color='dodgerblue')
284        bode(SPOFF['S.out', 'SA.in'], label='P that moved to S', color='dodgerblue', linestyle='dotted', linewidth=6)
285        bode(SPOFF['G.out', 'S.in'], label='Orig. S (from SPOFF)', color='red')
286        bode(S['S.out', 'S.in'], label='Orig. S alone', linestyle='dotted', linewidth=4, color='red')
287    axB.ax1.legend(fontsize=5)
288    axB.save(tjoin('SPOFF_diagnostic_bode.pdf'))
289    axB.save(tjoin('SPOFF_diagnostic_bode.png'))
290
291    axB = mplfigB(Nrows=2)
292    F_Hz = np.geomspace(1e-2, 20, 1000)
293    with SISObode.multi_bode(axB=axB, F_Hz = F_Hz) as bode:
294        bode(sys=SPOFF['P.out', 'P.in'], label='P to P')
295        bode(sys=SPOFF['P.out', 'S.in'], label='S to P')
296        bode(sys=SPOFF['S.out', 'S.in'], label='S to S', linestyle=':', linewidth=2)
297        bode(sys=S['S.out', 'S.in'], label='S to S (orig)', linestyle=':', linewidth=2)
298        bode(sys=SPOFF['T.out', 'O.in'], label='O to Meas. Out')
299        bode(sys=SPOFF['T.out', 'S.in'], label='S to Meas. Out')
300
301    axB.ax1.legend(fontsize=5)
302    axB.save(tjoin('SPOFF_bode.pdf'))
303    axB.save(tjoin('SPOFF_bode.png'))
304
305    #print('SPOFF', SPOFF.iod)
306    #print(SPOFF['T.out', 'S.in']._zp[1])
307
308    #truncate_inputs = ['P.in', 'S.in', 'O.in', 'T.in.1', 'T.in.2', 'FBNS.in', 'F2.in', 'Zinf.in']
309    #truncate_outputs = ['P.out', 'O.out', 'S.out', 'T.out', 'FBNS.out', 'F2.out']
310    #SPOFF = ssutil.truncate_io(SPOFF, truncate_inputs, truncate_outputs)
311
312    control.bode(SPOFF.mod[SPOFF.iod['F2.out'], SPOFF.iod['P.in']], dB=True, Hz=True, omega_limits=omega_limits, label='P to Flat FOM')
313    control.bode(SPOFF.mod[SPOFF.iod[FBNS_eff_out], SPOFF.iod['P.in']], dB=True, Hz=True, omega_limits=omega_limits, label='P to BNS FOM')
314    control.bode(SPOFF.mod[SPOFF.iod['P.out'], SPOFF.iod['S.in']], dB=True, Hz=True, omega_limits=omega_limits, label='S to P')
315    control.bode(SPOFF.mod[SPOFF.iod['S.out'], SPOFF.iod['S.in']], dB=True, Hz=True, omega_limits=omega_limits, label='S to S', linestyle='dotted', linewidth=4)
316    control.bode(SPOFF.mod[SPOFF.iod['T.out'], SPOFF.iod['O.in']], dB=True, Hz=True, omega_limits=omega_limits, label='O to Meas. Out')
317    control.bode(SPOFF.mod[SPOFF.iod['T.out'], SPOFF.iod['S.in']], dB=True, Hz=True, omega_limits=omega_limits, label='S to Meas. Out')
318    plt.legend(fontsize=5)
319    plt.savefig(tjoin('SPOFF_all_bode.pdf'))
320    plt.savefig(tjoin('SPOFF_all_bode.png'))
321    plt.close()
322
323    # THIS MODIFIES THE ORIGINAL SYSTEM!!!!! WHAT - LEE
324    #SPOFF_bal = ssutil.balance_sys_gain(SPOFF)
325
326    axFOM_S = ssutil.bode(SPOFF.siso(FBNS_eff_out, FBNS_eff_in), omega_limits=omega_limits_fom, label='FBNS', color='red')
327    axFOM_S = ssutil.bode(SPOFF.siso(iodutil.listoutputs(FFlat)[0], iodutil.listinputs(FFlat)[0]), axB=axFOM_S, omega_limits=omega_limits_fom, label='FFlat', color='dodgerblue')
328    #axFOM_S = ssutil.bode(SPOFF_bal.siso(FBNS_eff_out, FBNS_eff_in), omega_limits=omega_limits_fom, axB=axFOM_S, label='FBNS SPOFF bal', color='green')
329    #axFOM_S = ssutil.bode(SPOFF_bal.siso(iodutil.listoutputs(FFlat)[0], iodutil.listinputs(FFlat)[0]), axB=axFOM_S, omega_limits=omega_limits_fom, label='FFlat SPOFF bal', color='green')
330    axFOM_S = ssutil.bode(FBNS.siso('FBNS.out', 'FBNS.in'), axB=axFOM_S, omega_limits=omega_limits_fom, label='FBNS orig.', linestyle='dotted', color='red', linewidth=4)
331    axFOM_S = ssutil.bode(FBNS_orig.siso('FBNS.out', 'FBNS.in'), axB=axFOM_S, omega_limits=omega_limits_fom, label='FBNS orig.s', linestyle='dotted', color='purple', linewidth=4)
332    axFOM_S = ssutil.bode(Coup.siso('COUP.out', 'COUP.in'), axB=axFOM_S, omega_limits=omega_limits_fom, label='FBNS orig.s', linestyle='-', color='magenta', linewidth=4)
333    axFOM_S = ssutil.bode(FBNS_zpk, axB=axFOM_S, omega_limits=omega_limits_fom, label='FBNS orig_zpk.', linestyle='dotted', color='orange', linewidth=4)
334    axFOM_S = ssutil.bode(FFlat.siso(iodutil.listoutputs(FFlat)[0], iodutil.listinputs(FFlat)[0]), axB=axFOM_S, omega_limits=omega_limits_fom, label='FFlat orig.', color='dodgerblue', linestyle='dotted', linewidth=4)
335    axFOM_S.save(tjoin('FOM_bode_from_SPOFF.pdf'))
336    axFOM_S.save(tjoin('FOM_bode_from_SPOFF.png'))
337
338    #SPOFF = ssutil.balance_sys_gain(SPOFF)
339
340    P_load2 = ssutil.loadSys(fjoin(folder, P_fname))
341    # assert(np.allclose(P_load2.A, P.A))
342    # assert(np.allclose(P_load2.B, P.B))
343    # assert(np.allclose(P_load2.C, P.C))
344    # assert(np.allclose(P_load2.D, P.D))
345
346    print("SYS?")
347    SPOFF.print_nonzero()
348
349    ssutil.savesys(SPOFF, tjoin('ADY_Sanex.mat'))
350    ssutil.savesys(P, tjoin('ADY_plant.mat'))
351
352    ssutil.savesys(SPOFF, fjoin(folder, 'ADY_Sanex.mat'))
353    ssutil.savesys(P, fjoin(folder, 'ADY_plant.mat'))
354
355    return
pytest information

This code is wrapped in a pytest function using conventions detailed in pytest_conventions. The full name of this test, as known by the documentation, is:

test.ASC_SOLVER.T_make_sys_ADY.test_Make_ADY

The full name is useful when building documentation, to link a reference to this page using :func:`name`, or directly include it with an autofunction directive. The collapse nodes below show every instance of the test run. There may only be one, but if the test was run multiple times through pytest parametrizations, the list can be longer.

test_Make_ADY[ExampleModels_newFOM_F3]
output
status: failed
duration: 0.026s
captured errors:
folder = 'ExampleModels_newFOM_F3'

    @pytest.mark.parametrize(
        'folder', [
            'ExampleModels_working',
            'ExampleModels_working_F3',
            'ExampleModels_newFOM',
            'ExampleModels_newFOM_F3',
            'ExampleModels_DARMFOM',
            'ExampleModels_DARMFOM_F3',
        ]
    )
    @pytest.mark.gitlabCI
    @pytest.mark.ADY
    def test_Make_ADY(folder):
        """
        This is the main function that is called to create the model for the ASC DHARD Y.
        """
        use_old_balancing = False
        # not helpful it seems
        use_alt_balancing = False

        if use_old_balancing:
            from wield.control.utilities import algorithm_choice
            # This fix is needed since updating several wield.controls algorithms
            algorithm_choice.algorithm_adjust_default('zpk2ss', 'zpk2ss_chain_poly_nobal', 200)

        S = ssutil.loadSys(fjoin(folder, 'ADY_E_from_fit.mat'))
>       S = S.balance(which='ABC')

/builds/buzz/test/ASC_SOLVER/T_make_sys_ADY.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = MIMOStateSpace with 
 inputs ['S.in'], 
 outputs ['S.out'], 
 and 16 dimensional states
kwargs = {'which': 'ABC'}

    def balance(self, **kwargs):
        return self.__build_similar__(
>           ss=self.ss.balanceA(**kwargs),
        )
E       TypeError: BareStateSpace.balanceA() got an unexpected keyword argument 'which'

/wield/wield-control/src/wield/control/ss_bare/ss.py:1680: TypeError
test_Make_ADY[ExampleModels_newFOM]
output
status: failed
duration: 0.002s
captured errors:
folder = 'ExampleModels_newFOM'

    @pytest.mark.parametrize(
        'folder', [
            'ExampleModels_working',
            'ExampleModels_working_F3',
            'ExampleModels_newFOM',
            'ExampleModels_newFOM_F3',
            'ExampleModels_DARMFOM',
            'ExampleModels_DARMFOM_F3',
        ]
    )
    @pytest.mark.gitlabCI
    @pytest.mark.ADY
    def test_Make_ADY(folder):
        """
        This is the main function that is called to create the model for the ASC DHARD Y.
        """
        use_old_balancing = False
        # not helpful it seems
        use_alt_balancing = False

        if use_old_balancing:
            from wield.control.utilities import algorithm_choice
            # This fix is needed since updating several wield.controls algorithms
            algorithm_choice.algorithm_adjust_default('zpk2ss', 'zpk2ss_chain_poly_nobal', 200)

        S = ssutil.loadSys(fjoin(folder, 'ADY_E_from_fit.mat'))
>       S = S.balance(which='ABC')

/builds/buzz/test/ASC_SOLVER/T_make_sys_ADY.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = MIMOStateSpace with 
 inputs ['S.in'], 
 outputs ['S.out'], 
 and 16 dimensional states
kwargs = {'which': 'ABC'}

    def balance(self, **kwargs):
        return self.__build_similar__(
>           ss=self.ss.balanceA(**kwargs),
        )
E       TypeError: BareStateSpace.balanceA() got an unexpected keyword argument 'which'

/wield/wield-control/src/wield/control/ss_bare/ss.py:1680: TypeError
test_Make_ADY[ExampleModels_working_F3]
output
status: failed
duration: 0.018s
captured errors:
folder = 'ExampleModels_working_F3'

    @pytest.mark.parametrize(
        'folder', [
            'ExampleModels_working',
            'ExampleModels_working_F3',
            'ExampleModels_newFOM',
            'ExampleModels_newFOM_F3',
            'ExampleModels_DARMFOM',
            'ExampleModels_DARMFOM_F3',
        ]
    )
    @pytest.mark.gitlabCI
    @pytest.mark.ADY
    def test_Make_ADY(folder):
        """
        This is the main function that is called to create the model for the ASC DHARD Y.
        """
        use_old_balancing = False
        # not helpful it seems
        use_alt_balancing = False

        if use_old_balancing:
            from wield.control.utilities import algorithm_choice
            # This fix is needed since updating several wield.controls algorithms
            algorithm_choice.algorithm_adjust_default('zpk2ss', 'zpk2ss_chain_poly_nobal', 200)

        S = ssutil.loadSys(fjoin(folder, 'ADY_E_from_fit.mat'))
>       S = S.balance(which='ABC')

/builds/buzz/test/ASC_SOLVER/T_make_sys_ADY.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = MIMOStateSpace with 
 inputs ['S.in'], 
 outputs ['S.out'], 
 and 16 dimensional states
kwargs = {'which': 'ABC'}

    def balance(self, **kwargs):
        return self.__build_similar__(
>           ss=self.ss.balanceA(**kwargs),
        )
E       TypeError: BareStateSpace.balanceA() got an unexpected keyword argument 'which'

/wield/wield-control/src/wield/control/ss_bare/ss.py:1680: TypeError
test_Make_ADY[ExampleModels_DARMFOM_F3]
output
status: failed
duration: 0.014s
captured errors:
folder = 'ExampleModels_DARMFOM_F3'

    @pytest.mark.parametrize(
        'folder', [
            'ExampleModels_working',
            'ExampleModels_working_F3',
            'ExampleModels_newFOM',
            'ExampleModels_newFOM_F3',
            'ExampleModels_DARMFOM',
            'ExampleModels_DARMFOM_F3',
        ]
    )
    @pytest.mark.gitlabCI
    @pytest.mark.ADY
    def test_Make_ADY(folder):
        """
        This is the main function that is called to create the model for the ASC DHARD Y.
        """
        use_old_balancing = False
        # not helpful it seems
        use_alt_balancing = False

        if use_old_balancing:
            from wield.control.utilities import algorithm_choice
            # This fix is needed since updating several wield.controls algorithms
            algorithm_choice.algorithm_adjust_default('zpk2ss', 'zpk2ss_chain_poly_nobal', 200)

        S = ssutil.loadSys(fjoin(folder, 'ADY_E_from_fit.mat'))
>       S = S.balance(which='ABC')

/builds/buzz/test/ASC_SOLVER/T_make_sys_ADY.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = MIMOStateSpace with 
 inputs ['S.in'], 
 outputs ['S.out'], 
 and 16 dimensional states
kwargs = {'which': 'ABC'}

    def balance(self, **kwargs):
        return self.__build_similar__(
>           ss=self.ss.balanceA(**kwargs),
        )
E       TypeError: BareStateSpace.balanceA() got an unexpected keyword argument 'which'

/wield/wield-control/src/wield/control/ss_bare/ss.py:1680: TypeError
test_Make_ADY[ExampleModels_working]
output
status: failed
duration: 0.022s
captured errors:
folder = 'ExampleModels_working'

    @pytest.mark.parametrize(
        'folder', [
            'ExampleModels_working',
            'ExampleModels_working_F3',
            'ExampleModels_newFOM',
            'ExampleModels_newFOM_F3',
            'ExampleModels_DARMFOM',
            'ExampleModels_DARMFOM_F3',
        ]
    )
    @pytest.mark.gitlabCI
    @pytest.mark.ADY
    def test_Make_ADY(folder):
        """
        This is the main function that is called to create the model for the ASC DHARD Y.
        """
        use_old_balancing = False
        # not helpful it seems
        use_alt_balancing = False

        if use_old_balancing:
            from wield.control.utilities import algorithm_choice
            # This fix is needed since updating several wield.controls algorithms
            algorithm_choice.algorithm_adjust_default('zpk2ss', 'zpk2ss_chain_poly_nobal', 200)

        S = ssutil.loadSys(fjoin(folder, 'ADY_E_from_fit.mat'))
>       S = S.balance(which='ABC')

/builds/buzz/test/ASC_SOLVER/T_make_sys_ADY.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = MIMOStateSpace with 
 inputs ['S.in'], 
 outputs ['S.out'], 
 and 16 dimensional states
kwargs = {'which': 'ABC'}

    def balance(self, **kwargs):
        return self.__build_similar__(
>           ss=self.ss.balanceA(**kwargs),
        )
E       TypeError: BareStateSpace.balanceA() got an unexpected keyword argument 'which'

/wield/wield-control/src/wield/control/ss_bare/ss.py:1680: TypeError
test_Make_ADY[ExampleModels_DARMFOM]
output
status: failed
duration: 0.017s
captured errors:
folder = 'ExampleModels_DARMFOM'

    @pytest.mark.parametrize(
        'folder', [
            'ExampleModels_working',
            'ExampleModels_working_F3',
            'ExampleModels_newFOM',
            'ExampleModels_newFOM_F3',
            'ExampleModels_DARMFOM',
            'ExampleModels_DARMFOM_F3',
        ]
    )
    @pytest.mark.gitlabCI
    @pytest.mark.ADY
    def test_Make_ADY(folder):
        """
        This is the main function that is called to create the model for the ASC DHARD Y.
        """
        use_old_balancing = False
        # not helpful it seems
        use_alt_balancing = False

        if use_old_balancing:
            from wield.control.utilities import algorithm_choice
            # This fix is needed since updating several wield.controls algorithms
            algorithm_choice.algorithm_adjust_default('zpk2ss', 'zpk2ss_chain_poly_nobal', 200)

        S = ssutil.loadSys(fjoin(folder, 'ADY_E_from_fit.mat'))
>       S = S.balance(which='ABC')

/builds/buzz/test/ASC_SOLVER/T_make_sys_ADY.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = MIMOStateSpace with 
 inputs ['S.in'], 
 outputs ['S.out'], 
 and 16 dimensional states
kwargs = {'which': 'ABC'}

    def balance(self, **kwargs):
        return self.__build_similar__(
>           ss=self.ss.balanceA(**kwargs),
        )
E       TypeError: BareStateSpace.balanceA() got an unexpected keyword argument 'which'

/wield/wield-control/src/wield/control/ss_bare/ss.py:1680: TypeError