1 | function varargout = fittunedisp2(newtunes_disp, quadfam1, quadfam2, quadfam3, dispind, varargin) |
---|
2 | %FITTUNEDISP2 - Fits the linear tunes and the dispersion of model using 3 quadrupole families. |
---|
3 | % fittune2([nux nuy disp], QUADFAMILY1, QUADFAMILY2, QUADFAMILY3, DISPIND) |
---|
4 | % |
---|
5 | % INPUTS |
---|
6 | % 1. nux and nuy - the tunes (indlucing the integer parts) |
---|
7 | % disp - dispersion at the position (AT index) given by DISPIND |
---|
8 | % 2. QUADFAMILY1 - Quadrupole family #1 |
---|
9 | % 3. QUADFAMILY2 - Quadrupole family #2 |
---|
10 | % 4. QUADFAMILY3 - Quadrupole family #3 |
---|
11 | % 5. DISPIND - AT index to measure dispersion |
---|
12 | % |
---|
13 | % ALGORITHM |
---|
14 | % Iteratively calculate the required quadrupole strengths to fit the new tunes and dispersion. |
---|
15 | % |
---|
16 | % Written by Eugene Tan |
---|
17 | |
---|
18 | |
---|
19 | % Must declare THERING as global in order for the function to modify quadrupole values |
---|
20 | global THERING |
---|
21 | MAXDEPTH = 5; |
---|
22 | threshold = 1e-9; |
---|
23 | if nargin > 5 % use externally supplied step size for quadrupole K-values |
---|
24 | delta = varargin{1}; |
---|
25 | else |
---|
26 | delta = 1e-6; % default step size for quadrupole K-values |
---|
27 | end |
---|
28 | if nargin > 6 |
---|
29 | recursion_depth = varargin{2}; |
---|
30 | else |
---|
31 | recursion_depth = 0; |
---|
32 | end |
---|
33 | try |
---|
34 | THERING{dispind}; |
---|
35 | catch |
---|
36 | fprintf('Invalid position/index to measure dispersion %d\n',dispind); |
---|
37 | end |
---|
38 | |
---|
39 | % find indexes of the 2 quadrupole families use for fitting |
---|
40 | Q1I = findcells(THERING,'FamName',quadfam1); |
---|
41 | if isempty(Q1I); fprintf('Cannot find quadfamily: %s\n',quadfam1); return; end; |
---|
42 | Q2I = findcells(THERING,'FamName',quadfam2); |
---|
43 | if isempty(Q2I); fprintf('Cannot find quadfamily: %s\n',quadfam2); return; end; |
---|
44 | Q3I = findcells(THERING,'FamName',quadfam3); |
---|
45 | if isempty(Q3I); fprintf('Cannot find quadfamily: %s\n',quadfam3); return; end; |
---|
46 | |
---|
47 | |
---|
48 | InitialK1 = getcellstruct(THERING,'K',Q1I); |
---|
49 | InitialK2 = getcellstruct(THERING,'K',Q2I); |
---|
50 | InitialK3 = getcellstruct(THERING,'K',Q3I); |
---|
51 | InitialPolB1 = getcellstruct(THERING,'PolynomB',Q1I,2); |
---|
52 | InitialPolB2 = getcellstruct(THERING,'PolynomB',Q2I,2); |
---|
53 | InitialPolB3 = getcellstruct(THERING,'PolynomB',Q3I,2); |
---|
54 | |
---|
55 | % Compute initial tunes before fitting |
---|
56 | % [ LD, InitialTunes] = linopt(THERING,0); |
---|
57 | mach = machine_at; |
---|
58 | TempTunes = [mach.nux(end);mach.nuy(end)]; |
---|
59 | TempDisp = mach.etax(1); |
---|
60 | TempK1 = InitialK1; |
---|
61 | TempK2 = InitialK2; |
---|
62 | TempK3 = InitialK3; |
---|
63 | TempPolB1 = InitialPolB1; |
---|
64 | TempPolB2 = InitialPolB2; |
---|
65 | TempPolB3 = InitialPolB3; |
---|
66 | |
---|
67 | if recursion_depth == 0 |
---|
68 | fprintf('\n==== Fitting Tunes and Dispersion ====\n'); |
---|
69 | fprintf('Desired Tunes and Dispersion: %14.10f (H) %14.10f (V) %14.10f (D)\n',... |
---|
70 | newtunes_disp); |
---|
71 | fprintf('Initial Tunes and Dispersion: %14.10f (H) %14.10f (V) %14.10f (D)\n',... |
---|
72 | TempTunes(1),TempTunes(2),TempDisp); |
---|
73 | fprintf('Inital K values: %9.7f (%s) %9.7f (%s) %9.7f (%s)\n',... |
---|
74 | InitialK1(1), quadfam1, InitialK2(1), quadfam2, InitialK3(1), quadfam3); |
---|
75 | end |
---|
76 | |
---|
77 | % Take Derivative |
---|
78 | THERING = setcellstruct(THERING,'K',Q1I,TempK1+delta); |
---|
79 | THERING = setcellstruct(THERING,'PolynomB',Q1I,TempPolB1+delta,2); |
---|
80 | mach = machine_at; |
---|
81 | Tunes_dK1 = [mach.nux(end);mach.nuy(end)]; |
---|
82 | Disp_dK1 = mach.etax(1); |
---|
83 | THERING = setcellstruct(THERING,'K',Q1I,TempK1); |
---|
84 | THERING = setcellstruct(THERING,'PolynomB',Q1I,TempPolB1,2); |
---|
85 | |
---|
86 | THERING = setcellstruct(THERING,'K',Q2I,TempK2+delta); |
---|
87 | THERING = setcellstruct(THERING,'PolynomB',Q2I,TempPolB2+delta,2); |
---|
88 | mach = machine_at; |
---|
89 | Tunes_dK2 = [mach.nux(end);mach.nuy(end)]; |
---|
90 | Disp_dK2 = mach.etax(1); |
---|
91 | THERING = setcellstruct(THERING,'K',Q2I,TempK2); |
---|
92 | THERING = setcellstruct(THERING,'PolynomB',Q2I,TempPolB2,2); |
---|
93 | |
---|
94 | THERING = setcellstruct(THERING,'K',Q3I,TempK3+delta); |
---|
95 | THERING = setcellstruct(THERING,'PolynomB',Q3I,TempPolB3+delta,2); |
---|
96 | mach = machine_at; |
---|
97 | Tunes_dK3 = [mach.nux(end);mach.nuy(end)]; |
---|
98 | Disp_dK3 = mach.etax(1); |
---|
99 | THERING = setcellstruct(THERING,'K',Q3I,TempK3); |
---|
100 | THERING = setcellstruct(THERING,'PolynomB',Q3I,TempPolB3,2); |
---|
101 | |
---|
102 | |
---|
103 | %Construct the Jacobian |
---|
104 | change_dK = zeros(3); |
---|
105 | tempTunesDisp = zeros(3); |
---|
106 | |
---|
107 | change_dK(:,1) = [Tunes_dK1(1); Tunes_dK1(2); Disp_dK1]; |
---|
108 | change_dK(:,2) = [Tunes_dK2(1); Tunes_dK2(2); Disp_dK2]; |
---|
109 | change_dK(:,3) = [Tunes_dK3(1); Tunes_dK3(2); Disp_dK3]; |
---|
110 | tempTunesDisp(:,1) = [TempTunes(1); TempTunes(2); TempDisp]; |
---|
111 | tempTunesDisp(:,2) = [TempTunes(1); TempTunes(2); TempDisp]; |
---|
112 | tempTunesDisp(:,3) = [TempTunes(1); TempTunes(2); TempDisp]; |
---|
113 | |
---|
114 | |
---|
115 | J = (change_dK - tempTunesDisp)/delta; |
---|
116 | Jinv = inv(J); |
---|
117 | |
---|
118 | dnu = (newtunes_disp(:) - tempTunesDisp(:,1)); |
---|
119 | dK = Jinv*dnu; |
---|
120 | |
---|
121 | |
---|
122 | TempK1 = TempK1+dK(1); |
---|
123 | TempK2 = TempK2+dK(2); |
---|
124 | TempK3 = TempK3+dK(3); |
---|
125 | TempPolB1 = TempPolB1+dK(1); |
---|
126 | TempPolB2 = TempPolB2+dK(2); |
---|
127 | TempPolB3 = TempPolB3+dK(3); |
---|
128 | |
---|
129 | |
---|
130 | THERING = setcellstruct(THERING,'K',Q1I,TempK1); |
---|
131 | THERING = setcellstruct(THERING,'PolynomB',Q1I,TempPolB1,2); |
---|
132 | THERING = setcellstruct(THERING,'K',Q2I,TempK2); |
---|
133 | THERING = setcellstruct(THERING,'PolynomB',Q2I,TempPolB2,2); |
---|
134 | THERING = setcellstruct(THERING,'K',Q3I,TempK3); |
---|
135 | THERING = setcellstruct(THERING,'PolynomB',Q3I,TempPolB3,2); |
---|
136 | |
---|
137 | mach = machine_at; |
---|
138 | newTunes = [mach.nux(end);mach.nuy(end)]; |
---|
139 | newDisp = mach.etax(1); |
---|
140 | if sqrt((newtunes_disp - [newTunes(:); newDisp]').^2)/3 > threshold | recursion_depth > MAXDEPTH |
---|
141 | % disp('looping again') |
---|
142 | [Kvals newTunes] = fittunedisp2(newtunes_disp,quadfam1,quadfam2,quadfam3,dispind,delta,recursion_depth+1); |
---|
143 | else |
---|
144 | fprintf('Finished calculations. Recursion depth %d\n',recursion_depth); |
---|
145 | Kvals = [TempK1(1) TempK2(1) TempK3(1)]; |
---|
146 | newTunes = [mach.nux(end) mach.nuy(end) mach.etax(1)]; |
---|
147 | end |
---|
148 | |
---|
149 | if recursion_depth == 0 |
---|
150 | fprintf('Final K values: %9.7f (%s) %9.7f (%s) %9.7f (%s)\n',... |
---|
151 | Kvals(1), quadfam1, Kvals(2), quadfam2, Kvals(3), quadfam3); |
---|
152 | fprintf('Change : %9.7f (%s) %9.7f (%s) %9.7f (%s)\n',... |
---|
153 | 1-(InitialK1(1)/Kvals(1)), quadfam1, 1-(InitialK2(1)/Kvals(2)), quadfam2, 1-(InitialK3(1)/Kvals(3)), quadfam3); |
---|
154 | fprintf('Final Tunes and Dispersion: %14.10f (H) %14.10f (V) %14.10f (D)\n',... |
---|
155 | newTunes(1), newTunes(2), newTunes(3)); |
---|
156 | end |
---|
157 | |
---|
158 | varargout{1} = Kvals; |
---|
159 | varargout{2} = newTunes; |
---|