1 | function Amps = k2amp(Family, Field, k, DeviceList, Energy, C, K2AmpScaleFactor) |
---|
2 | %K2AMP - Converts simulator values to amperes |
---|
3 | % Amps = k2amp(Family, Field, k, DeviceList, Energy, Coefficients, K2AmpScaleFactor) |
---|
4 | % or |
---|
5 | % Amps = k2amp(Family, Field, k, DeviceList, Energy, MagnetCoreType, K2AmpScaleFactor) |
---|
6 | % |
---|
7 | % Calculates the current [amperes] from the coefficients (or MagnetCoreType), "K-value", energy, and linear scale factor |
---|
8 | % |
---|
9 | % INPUTS |
---|
10 | % 1. Family - Family name |
---|
11 | % 2. Field - Sub-field (like 'Setpoint') |
---|
12 | % 3. K - "K-value" in AT convention |
---|
13 | % For dipole: K = B / Brho |
---|
14 | % For quadrupole: K = B'/ Brho |
---|
15 | % For sextupole: K = B"/ Brho / 2 |
---|
16 | % 4. DeviceList - Device list (Amps and DeviceList must have the same number of rows) |
---|
17 | % 5. Energy - Energy in GeV {Default: getenergy} |
---|
18 | % If Energy is a vector, each output column will correspond to that energy. |
---|
19 | % Energy can be anything getenergy accepts, like 'Model' or 'Online'. |
---|
20 | % (Note: If Energy is a vector, then Amps can only have 1 column) |
---|
21 | % 6. Coefficients - A Coefficients vector or a MagnetCoreType string (coefficient found from magnetcoefficents.m) can be used |
---|
22 | % k and Coefficients must have equal number of rows or one must only have |
---|
23 | % one row |
---|
24 | % 7. K2AmpScaleFactor - linearly scales the output current: Amps = |
---|
25 | % K2AmpScaleFactor .* Amps |
---|
26 | % |
---|
27 | % NOTES |
---|
28 | % 1. If energy is not an input or empty, then the energy is obtained from getenergy. |
---|
29 | % 2. Family and Field inputs are not used but there automatically part of the physics2hw call. |
---|
30 | % |
---|
31 | % See Also amp2k, magnetcoefficients |
---|
32 | |
---|
33 | % ALGORITHM |
---|
34 | % |
---|
35 | % p = root(-k*Brho + (c0 + c1*I + ... + cn*I^n)) |
---|
36 | % I = root(p) closest to linear solution rlin |
---|
37 | % Linear solution is |
---|
38 | % rlin = (k*Brho - c0)/c1 |
---|
39 | |
---|
40 | % |
---|
41 | % M. Yoon 4/8/03 |
---|
42 | % Adapted by Laurent S. Nadolski |
---|
43 | % Closest solution to linear takes into account the offset term |
---|
44 | |
---|
45 | |
---|
46 | if nargin < 4 |
---|
47 | error('At least 4 inputs required'); |
---|
48 | end |
---|
49 | |
---|
50 | if nargin < 6 |
---|
51 | C = []; |
---|
52 | end |
---|
53 | if isempty(C) |
---|
54 | %[CC, Leff, MagnetName] = magnetcoefficients(Family); |
---|
55 | C = getfamilydata(Family, Field, 'HW2PhysicsParams', DeviceList); |
---|
56 | C = C{1}; |
---|
57 | end |
---|
58 | |
---|
59 | if nargin < 5 |
---|
60 | Energy = []; |
---|
61 | end |
---|
62 | if isempty(Energy) |
---|
63 | Energy = getenergy; |
---|
64 | elseif ischar(Energy) |
---|
65 | Energy = getenergy(Energy); |
---|
66 | end |
---|
67 | |
---|
68 | |
---|
69 | % If k is a row vector make it a column vector |
---|
70 | k = k(:); |
---|
71 | |
---|
72 | |
---|
73 | brho = getbrho(Energy); |
---|
74 | |
---|
75 | |
---|
76 | % Compute roots for the expansion: 0 = -BLeff + c0*I + c1*I^2 ... |
---|
77 | % For dipole: BLeff = B * Leff |
---|
78 | % For quadrupole: BLeff = B' * Leff |
---|
79 | % For sextupole: BLeff = B" * Leff |
---|
80 | |
---|
81 | %polynom = (C(8)+C(7)*Amps+C(6)*Amps^2+C(5)*Amps^3+C(4)*Amps^4+C(3)*Amps^5+C(2)*Amps^6+C(1)*Amps^7) |
---|
82 | %polynom = (c0+c1*Amps+c2*Amps^2+c3*Amps^3+c4*Amps^4+c5*Amps^5+c6*Amps^6+c7*Amps^7) |
---|
83 | |
---|
84 | |
---|
85 | if isstr(C) |
---|
86 | TableLookUpFlag = 1; |
---|
87 | MagnetCoreType = C; |
---|
88 | [C, Leff, MagnetName] = magnetcoefficients(MagnetCoreType, k(1), 'k'); |
---|
89 | fprintf('k2amp: Warning magnetcoeeficient called\n'); |
---|
90 | k0 = k(1); |
---|
91 | else |
---|
92 | TableLookUpFlag = 0; |
---|
93 | end |
---|
94 | |
---|
95 | if any(size(C,1) ~= length(k)) |
---|
96 | if length(k) == 1 |
---|
97 | k = ones(size(C,1),1) * k; |
---|
98 | elseif size(C,1) == 1 |
---|
99 | % Ok as is |
---|
100 | %C = ones(size(k,1),1) * C; |
---|
101 | else |
---|
102 | error('k and Coefficients must have equal number of rows or one must only have one row'); |
---|
103 | end |
---|
104 | end |
---|
105 | |
---|
106 | for j = 1:length(k) |
---|
107 | % For piecewise tables, get a new polynomial |
---|
108 | if TableLookUpFlag |
---|
109 | if k(j) ~= k0; |
---|
110 | [C, Leff, MagnetName] = magnetcoefficients(MagnetCoreType, k(j), 'k'); |
---|
111 | fprintf('k2amp: Warning magnetcoeeficient called\n'); |
---|
112 | k0 = k(j); |
---|
113 | end |
---|
114 | end |
---|
115 | |
---|
116 | |
---|
117 | |
---|
118 | % Solve for roots based on polynomial coefficient (coefficients already divided by Leff) |
---|
119 | % p = [C(1) C(2) C(3) C(4) C(5) C(6) C(7) C(8) C(9)-k(j)*brho]; |
---|
120 | |
---|
121 | if size(C,1) == 1 |
---|
122 | p = [C(1:end-1) C(end)-k(j)*brho]; |
---|
123 | r1inear = (k(j)*brho-C(end))/C(end-1); |
---|
124 | else |
---|
125 | p = [C(j,1:end-1) C(j,end)-k(j)*brho]; |
---|
126 | r1inear = (k(j)*brho-C(end))/C(j,end-1); |
---|
127 | end |
---|
128 | |
---|
129 | r = roots(p); |
---|
130 | |
---|
131 | % Choose the closest solution to the linear one |
---|
132 | Amps(j,1) = Inf; |
---|
133 | FitError = Inf; |
---|
134 | for i = 1:length(r) |
---|
135 | if isreal(r(i)) |
---|
136 | %if r(i)>0 & abs(r(i)) < Amps(j,1) % Smallest, positive |
---|
137 | |
---|
138 | % Closest to linear method |
---|
139 | if abs(r(i)-r1inear) < abs(Amps(j,1)-r1inear) |
---|
140 | Amps(j,1) = r(i); |
---|
141 | end |
---|
142 | end |
---|
143 | end |
---|
144 | |
---|
145 | if isinf(Amps(j,1)) |
---|
146 | error(sprintf('Solution for k=%.3f not found (all roots are complex)', k(j))); |
---|
147 | end |
---|
148 | end |
---|
149 | |
---|
150 | % Scale solution if required |
---|
151 | if nargin >= 7 |
---|
152 | Amps = Amps .* K2AmpScaleFactor; |
---|
153 | end |
---|