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, as_zpk])

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)[source]
code
docstring
"""
"""
 1def FBNSSS_DARM(
 2    return_name=False,
 3    return_scale=False,
 4    as_zpk=False,
 5):
 6
 7    if return_name:
 8        name = "FOM BNS (Hand Fit)"
 9        return name
10
11    #BNS_zpk = file_io.load(fjoin('ExampleModels_DARMFOM/BNS_FOM_from_DARM.yml'))
12    BNS_zpk = file_io.load(fjoin('ExampleModels_DARMFOM/BNS_FOM_IR.yml'))
13    F_z = np.array(BNS_zpk["z"], dtype=np.complex128)
14    F_p = np.array(BNS_zpk["p"], dtype=np.complex128)
15    F_k = BNS_zpk["k"]
16
17    F_zpk = SISO.zpk(F_z, F_p, F_k)
18    F = F_zpk.asSS.mimo("FBNS.out", "FBNS.in")
19    F, scale = ssutil.normalize_gain(F, norm=1, return_scale=True)
20    if as_zpk:
21        return F_zpk * scale
22    if return_scale:
23        return scale
24    else:
25        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
135    # FBNS_alt = Coup.siso('COUP.out', 'COUP.in') * FBNS.siso('FBNS.out', 'FBNS.in')
136
137    print("FOM STATESPACE-with Coupling---------------------------------------------")
138    print(FBNS.inputs)
139    print(FBNS.print_nonzero())
140    print("/FOM STATESPACE-with coupling---------------------------------------------")
141
142    FBNS_scale = FBNS_scale * Coup_scale
143    np.savetxt(fjoin(folder, 'FBNS_scale.txt'), [FBNS_scale])
144    print('FBNS scale', FBNS_scale)
145
146    current_range = np.loadtxt(fjoin(folder, 'FBNS_Current_range.txt'))  # Saved by the normalization in the make function
147    io_scales = Bunch(
148        FBNS = FBNS_scale,  # will need to apply this to the BNS FOM
149        w2_rescale = w2_rescale,  # will need to divide by this on both FOMs
150        # will need to be applied only to the Flat fom since the A2L_coupling_with_cal includes it as a factor
151        ct2rad = 5.2e-11,  # Calibration from https://alog.ligo-wa.caltech.edu/aLOG/index.php?callRep=69551
152        strain2m = 1/3995,  # Representing the 4km arm length. Strain is h = dL/L where L = 3995 m. The coupling is "I" is
153        # in rad to displacement so we need to convert it to strain for the BNS FOM which is in strain
154        current_range = current_range,
155    )
156    io_scales.RMS_cal_F1 = 1/io_scales.FBNS * io_scales.strain2m / io_scales.w2_rescale
157    io_scales.RMS_cal_F2 = io_scales.ct2rad / io_scales.w2_rescale
158    file_io.save(fjoin(folder, 'io_scales.yml'), dict(io_scales))
159
160    omega_limits = [1e-2, 1e4]
161
162    omega_limits_noise = [1e-1, 1e3]
163    axN = ssutil.bode(ssutil.asSISO(S), omega_limits=omega_limits_noise, label='Seismic')
164    axN = ssutil.bode(ssutil.asSISO(O), axB=axN, omega_limits=omega_limits_noise, label='Meas. Noise')
165    axN = ssutil.bode(ssutil.asSISO(P), axB=axN, omega_limits=omega_limits_noise, label='Plant')
166    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')
167    axN.save(tjoin('Noise_bode.png'))
168    axN.save(tjoin('Noise_bode.pdf'))
169
170
171    # control.bode(S.mod, dB=False, Hz=True, omega_limits=omega_limits, label='Seismic')
172    # control.bode(O.mod, dB=False, Hz=True, omega_limits=omega_limits, label='Meas. Noise')
173    # control.bode(P.mod, dB=False, Hz=True, omega_limits=omega_limits, label='Plant')
174    # 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')
175    # plt.legend()
176    # plt.savefig(tjoin('Noise_bode.pdf'), bbox_inches='tight')
177    # plt.savefig(tjoin('Noise_bode.png'), bbox_inches='tight', dpi=300)
178    # plt.close()
179
180    omega_limits_fom = np.array([1e-1, 1e5])*2*np.pi
181    axFOM = ssutil.bode(FBNS.siso('FBNS.out', 'FBNS.in'), omega_limits=omega_limits_fom, label='FBNS')
182    axFOM = ssutil.bode(FFlat.siso(iodutil.listoutputs(FFlat)[0], iodutil.listinputs(FFlat)[0]), axB=axFOM, omega_limits=omega_limits_fom, label='FFlat')
183    axFOM.save(tjoin('FOM_bode.pdf'))
184    axFOM.save(tjoin('FOM_bode.png'))
185    # control.bode(FBNS.mod, dB=True, Hz=True, omega_limits=omega_limits, label='FBNS')
186    # control.bode(FFlat.mod, dB=True, Hz=True, omega_limits=omega_limits, label='FFlat')
187    # plt.legend()
188    # plt.savefig(tjoin('FOM_bode.pdf'))
189    # plt.savefig(tjoin('FOM_bode.png'))
190    # plt.close()
191
192    #make the SO
193    #conlist =[['T_SO.in.1', 'O.out'], ['T_SO.in.2','S.out']]
194    #T_SO = addSS(namespace='T_SO', sub=True)
195    #SO = ssutil.multiconnect([S, O, T_SO], conlist)
196    #SO = ssutil.truncate_io(SO, ['O.in', 'S.in'], ['T_SO.out', 'S.out'])
197    #SO = ssutil.rename_io(SO, 'T_SO.out', 'O.out')
198
199    #control.bode(SO.mod[SO.iod['S.out'], SO.iod['S.in']], dB=True, Hz=True, omega_limits=omega_limits, label='S to S')
200    #control.bode(SO.mod[SO.iod['O.out'], SO.iod['O.in']], dB=True, Hz=True, omega_limits=omega_limits, label='O to O')
201    #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)
202    #control.bode(S.mod, dB=True, Hz=True, omega_limits=[1e-2, 1e3], label='Orig. S', linestyle='dotted', linewidth=4)
203    #control.bode(O.mod, dB=True, Hz=True, omega_limits=[1e-2, 1e3], label='Orig. O', linestyle='dotted', linewidth=4)
204    #plt.legend(fontsize=8)
205    #plt.savefig(tjoin('SO_bode.pdf'))
206    #plt.close()
207    SPOFF_kw = {}
208    if '_F3' in folder:
209        extras = 'F3_withP'
210        SPOFF_kw['include_F1'] = False
211        FBNS_eff_in = 'F3.in'
212        FBNS_eff_out = 'F3.out'
213    else:
214        extras = None
215        FBNS_eff_in = 'FBNS.in'
216        FBNS_eff_out = 'FBNS.out'
217
218    # TODO, this will break the solve to use noC.in. but debugging breakage
219    SPOFF = ssutil.makeSPOFF(
220        S, P, O,
221        FBNS,
222        FFlat,
223        diagnostic=True,
224        extras=extras,
225        balance=use_old_balancing,
226        # F1in='FBNS.noC.in',
227        F1in='FBNS.in',
228        F1out='FBNS.out',
229        **SPOFF_kw
230    )
231    SPOFF = SPOFF.topological_sort()
232    SPOFF = SPOFF.balance()
233    # SPOFF = SPOFF.schur_form()
234
235    #print('SPOFF', SPOFF.iod)
236    #SPOFF = ssutil.balance_sys_gain(SPOFF)
237    print("SPOFF STATESPACE-----------------------------------------------------------")
238    try_block_diagonalize = False
239    if try_block_diagonalize:
240        SPOFF = SPOFF.schur_form()
241        print(SPOFF.print_nonzero())
242
243        sr = np.zeros(SPOFF.ss.Nstates, dtype=float)
244        SPOFF_b2 = SPOFF.balance(which='A', Dr=sr)
245        SPOFF_b2 = SPOFF
246
247        from wield.control.ss_bare.ssprint import print_dense_nonzero_A, print_dense_nonzero, nz_int
248        def flog2(arr):
249            #arr = np.asarray(arr)
250            #mant, exp = np.frexp(arr)
251            exp = np.round(np.log2(abs(arr)))
252            return exp
253        sc = np.block([[flog2(sr)]])
254        print("scaling?")
255        print(print_dense_nonzero_A(sc, scaling=nz_int))
256        Tr = np.zeros_like(SPOFF_b2.A)
257        SPOFF_b2 = SPOFF_b2.block_diagonalize(condition_number=1e6, Tright=Tr)
258        print("after balance2")
259        print(SPOFF_b2.print_nonzero())
260        print("Transfer Matrix")
261        print(print_dense_nonzero_A(Tr))
262        # SPOFF = SPOFF_b2
263        print("POLES")
264        print(SPOFF_b2.p)
265    print("/SPOFF STATESPACE-----------------------------------------------------------")
266    omega_limits=[1e-2, 1e3]
267
268    axB = mplfigB(Nrows=2)
269    F_Hz = np.geomspace(1e-2, 20, 1000)
270    with SISObode.multi_bode(axB=axB, F_Hz = F_Hz) as bode:
271        bode(P['P.out', 'P.in'], label='P alone', linewidth=2, color='dodgerblue')
272        bode(SPOFF['P.out', 'P.in'], label='P to P in SPOFF', color='orange')
273        bode(SPOFF['P.out', 'S.in'], label='S to P', color='green')
274        bode(SPOFF['S.out', 'S.in'], label='S to S', linestyle='dotted', linewidth=4, color='green')
275        bode(SPOFF['P.out', 'SA.in'], linestyle='--', label='P Recombined', linewidth=4, color='dodgerblue')
276        bode(SPOFF['S.out', 'SA.in'], label='P that moved to S', color='dodgerblue', linestyle='dotted', linewidth=6)
277        bode(SPOFF['G.out', 'S.in'], label='Orig. S (from SPOFF)', color='red')
278        bode(S['S.out', 'S.in'], label='Orig. S alone', linestyle='dotted', linewidth=4, color='red')
279    axB.ax1.legend(fontsize=5)
280    axB.save(tjoin('SPOFF_diagnostic_bode.pdf'))
281    axB.save(tjoin('SPOFF_diagnostic_bode.png'))
282
283    axB = mplfigB(Nrows=2)
284    F_Hz = np.geomspace(1e-2, 20, 1000)
285    with SISObode.multi_bode(axB=axB, F_Hz = F_Hz) as bode:
286        bode(sys=SPOFF['P.out', 'P.in'], label='P to P')
287        bode(sys=SPOFF['P.out', 'S.in'], label='S to P')
288        bode(sys=SPOFF['S.out', 'S.in'], label='S to S', linestyle=':', linewidth=2)
289        bode(sys=S['S.out', 'S.in'], label='S to S (orig)', linestyle=':', linewidth=2)
290        bode(sys=SPOFF['T.out', 'O.in'], label='O to Meas. Out')
291        bode(sys=SPOFF['T.out', 'S.in'], label='S to Meas. Out')
292
293    axB.ax1.legend(fontsize=5)
294    axB.save(tjoin('SPOFF_bode.pdf'))
295    axB.save(tjoin('SPOFF_bode.png'))
296
297    #print('SPOFF', SPOFF.iod)
298    #print(SPOFF['T.out', 'S.in']._zp[1])
299
300    #truncate_inputs = ['P.in', 'S.in', 'O.in', 'T.in.1', 'T.in.2', 'FBNS.in', 'F2.in', 'Zinf.in']
301    #truncate_outputs = ['P.out', 'O.out', 'S.out', 'T.out', 'FBNS.out', 'F2.out']
302    #SPOFF = ssutil.truncate_io(SPOFF, truncate_inputs, truncate_outputs)
303
304    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')
305    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')
306    control.bode(SPOFF.mod[SPOFF.iod['P.out'], SPOFF.iod['S.in']], dB=True, Hz=True, omega_limits=omega_limits, label='S to P')
307    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)
308    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')
309    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')
310    plt.legend(fontsize=5)
311    plt.savefig(tjoin('SPOFF_all_bode.pdf'))
312    plt.savefig(tjoin('SPOFF_all_bode.png'))
313    plt.close()
314
315    # THIS MODIFIES THE ORIGINAL SYSTEM!!!!! WHAT - LEE
316    #SPOFF_bal = ssutil.balance_sys_gain(SPOFF)
317
318    axFOM_S = ssutil.bode(SPOFF.siso(FBNS_eff_out, FBNS_eff_in), omega_limits=omega_limits_fom, label='FBNS', color='red')
319    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')
320    #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')
321    #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')
322    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)
323    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)
324    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)
325    axFOM_S = ssutil.bode(FBNS_zpk, axB=axFOM_S, omega_limits=omega_limits_fom, label='FBNS orig_zpk.', linestyle='dotted', color='orange', linewidth=4)
326    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)
327    axFOM_S.save(tjoin('FOM_bode_from_SPOFF.pdf'))
328    axFOM_S.save(tjoin('FOM_bode_from_SPOFF.png'))
329
330    #SPOFF = ssutil.balance_sys_gain(SPOFF)
331
332    P_load2 = ssutil.loadSys(fjoin(folder, P_fname))
333    # assert(np.allclose(P_load2.A, P.A))
334    # assert(np.allclose(P_load2.B, P.B))
335    # assert(np.allclose(P_load2.C, P.C))
336    # assert(np.allclose(P_load2.D, P.D))
337
338    print("SYS?")
339    SPOFF.print_nonzero()
340
341    ssutil.savesys(SPOFF, tjoin('ADY_Sanex.mat'))
342    ssutil.savesys(P, tjoin('ADY_plant.mat'))
343
344    ssutil.savesys(SPOFF, fjoin(folder, 'ADY_Sanex.mat'))
345    ssutil.savesys(P, fjoin(folder, 'ADY_plant.mat'))
346
347    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.001s
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:283: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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.001s
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:283: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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.001s
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:283: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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.013s
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:283: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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:283: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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.001s
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:283: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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