source: MML/trunk/mml/settune.m @ 4

Last change on this file since 4 was 4, checked in by zhangj, 10 years ago

Initial import--MML version from SOLEIL@2013

File size: 6.9 KB
Line 
1function [DelQuad, ActuatorFamily] = settune(varargin)
2%SETTUNE - Set the tune
3%  [DelQuad, QuadFamily] = settune(NuDesired, InteractiveFlag, TuneResponseMatrix);
4%
5%  INPUTS
6%  1. NuDesired - Desired tune   [NuX; NuY] (2x1) {Default: golden tunes}
7%  2. InteractiveFlag - 0    -> No display information
8%                       else -> display tune information before setting magnets {Default}
9%  3. TuneResponseMatrix - Tune response matrix {Default: gettuneresp}
10%  4. ActuatorFamily -  Quadrupole to vary, ex {'Q7', 'Q9'} {Default: gettuneresp}
11%  5. Optional override of the units:
12%     'Physics'  - Use physics  units
13%     'Hardware' - Use hardware units
14%  6. Optional override of the mode:
15%     'Online'    - Set/Get data online 
16%     'Model'     - Set/Get data on the simulated accelerator using AT
17%     'Simulator' - Set/Get data on the simulated accelerator using AT
18%     'Manual'    - Set/Get data manually
19%     'FBT'       - For golden correction, used tune from FBT system
20%
21%  OUTPUTS
22%  1. DelQuad
23%  2. QuadFamily - Families used (cell array)
24%
25%  Algorithm: 
26%     SVD method
27%     DelQuad = inv(TuneResponseMatrix) * DeltaTune
28%     instead of
29%     DelQuad = inv(TuneResponseMatrix) * (Nu-gettune)
30%              DelQuad = [Q7; Q9]
31%
32%  NOTES
33%  1. If gettune only uses the fractional tune then NuDesired should only have fractional tunes.
34%  2. The tune measurement system must be running correctly for this routine to work properly.
35%
36%  EXAMPLES
37%  1. use 2 defaults family if specified in 'Tune Corrector'
38%     settune([18.23 10.3]
39%  2. use 10 families
40%     Qfam = findmemberof('QUAD');
41%     RTune = meastuneresp(Qfam, 'Model')
42%     [DK Fam] = settune([18.12 10.3],1,RTune,Qfam,'Model')
43%
44%  See Also steptune, gettune
45
46%
47%  Written by Gregory J. Portmann
48%  Modified by Laurent S. Nadolski
49%    Adaptation for SOLEIL
50%    Modification ALGO : use SVD as in steptune
51%    Tune measured using FBT exciation at large stored beam current
52
53%% Case of 2 families or more
54ActuatorFamily = findmemberof('Tune Corrector')';
55if isempty(ActuatorFamily) % Default 2 families
56    ActuatorFamily = {'QF','QD'};
57end
58
59%% Input parser
60%ActuatorFamily = {};
61UnitsFlag = {};
62ModeFlag = {};
63FBTFlag = 0; % tune measured using FBT
64
65for i = length(varargin):-1:1
66    if strcmpi(varargin{i},'physics')
67        UnitsFlag = varargin(i);
68        varargin(i) = [];
69    elseif strcmpi(varargin{i},'hardware')
70        UnitsFlag = varargin(i);
71        varargin(i) = [];
72    elseif strcmpi(varargin{i},'simulator') | strcmpi(varargin{i},'model')
73        ModeFlag = varargin(i);
74        varargin(i) = [];
75    elseif strcmpi(varargin{i},'online')
76        ModeFlag = varargin(i);
77        varargin(i) = [];
78    elseif strcmpi(varargin{i},'manual')
79        ModeFlag = varargin(i);
80        varargin(i) = [];
81    elseif strcmpi(varargin{i},'FBT')
82        FBTFlag = 1;
83        varargin(i) = [];
84    elseif strcmpi(varargin{i},'NoFBT')
85        FBTFlag = 0;
86        varargin(i) = [];
87    end       
88end
89
90
91if length(varargin) >= 1
92    Nu = varargin{1};
93else
94    Nu =[];
95end
96
97%% Golden values
98if isempty(Nu)
99    Nu = getgolden('TUNE',[1 1;1 2]);
100end
101
102if isempty(Nu)
103    error('Tune must be an input or the golden tunes must be available.');
104end
105Nu = Nu(:);
106if ~all(size(Nu) == [2 1])
107    error('Nu must be a 2x1 vector.');
108end
109
110if length(varargin) >= 2
111    InteractiveFlag = varargin{2};
112else
113    InteractiveFlag = 1;
114end
115
116%% Get tune response matrix
117if length(varargin) >= 3
118    TuneResponseMatrix = varargin{3};
119else
120    TuneResponseMatrix = [];
121end
122
123%% Get ActuatorFamilies
124if length(varargin) >= 4
125    ActuatorFamily1 = varargin{4};
126else
127    ActuatorFamily1 = ActuatorFamily;
128end
129
130%% Interactive part
131if InteractiveFlag
132    Flag = 1;
133    if isempty(TuneResponseMatrix)
134        TuneResponseMatrix = gettuneresp(UnitsFlag{:});
135    end
136    if isempty(TuneResponseMatrix)
137        error('The tune response matrix must be an input or available in one of the default response matrix files.');
138    end
139    while Flag
140        if FBTFlag
141            TuneOld = gettuneFBT;
142        else
143            TuneOld = gettune;
144        end
145        fprintf('\n');
146        fprintf('  Present tune: Horizontal = %.4f   Vertical = %.4f\n', TuneOld(1), TuneOld(2));
147        fprintf('     Goal tune: Horizontal = %.4f   Vertical = %.4f\n', Nu(1), Nu(2));
148
149        DelNu = Nu - TuneOld;
150
151        % 1. SVD Tune Correction
152        % Decompose the tune response matrix:
153        [U, S, V] = svd(TuneResponseMatrix, 'econ');
154        % TuneResponseMatrix = U*S*V'
155        %
156        % The V matrix columns are the singular vectors in the quadrupole magnet space
157        % The U matrix columns are the singular vectors in the TUNE space
158        % U'*U=I and V*V'=I
159        %
160        % TUNECoef is the projection onto the columns of TuneResponseMatrix*V(:,Ivec) (same space as spanned by U)
161        % Sometimes it's interesting to look at the size of these coefficients with singular value number.
162        TUNECoef = diag(diag(S).^(-1)) * U' * DelNu;
163        %
164        % Convert the vector TUNECoef back to coefficents of TuneResponseMatrix
165        DelQuad = V * TUNECoef;
166
167        % 2. Square matrix solution
168        % DelQuad = inv(TuneResponseMatrix) * DelNu; %  DelQuad = [Q7; Q9];
169
170
171        % 3. Least squares solution
172        % DelQuad = inv(TuneResponseMatrix'*TuneResponseMatrix)*TuneResponseMatrix' * DeltaTune;
173        %
174        % see Matlab help for "Matrices and Linear Algebra" to see what this does
175        % If overdetermined, then "\" is least squares
176        %
177        % If underdetermined (like more than 2 quadrupole families), then only the
178        % columns with the 2 biggest norms will be keep.  The rest of the quadupole
179        % families with have zero effect.  Hence, constraints would have to be added for
180        % this method to work.
181        % DelQuad = TuneResponseMatrix \ DelNu;
182
183        for k = 1:length(ActuatorFamily1)
184            fprintf('   Quad change:   Delta %3s = %+.4f Amps', ...
185                ActuatorFamily1{k}, DelQuad(k));
186            if rem(k,2) == 0
187                fprintf('\n')
188            end
189        end
190
191        fprintf('\n')
192
193        tmp = menu('Choose an option?','Step quadrupoles','Remeasure Tunes','Change goal tune','Exit');
194        if tmp == 1
195            Flag = 0;
196        elseif tmp == 2
197            Flag = 1;
198        elseif tmp == 3
199            Nu(1) = input('  Input new horizontal tune = ');
200            Nu(2) = input('  Input new   vertical tune = ');
201            % Nu(1) = rem(Nu(1),1);
202            % Nu(2) = rem(Nu(2),1);
203        else
204            disp('  Tunes not changed.');
205            return
206        end
207    end
208
209    disp('  Changing quadrupoles...');
210   
211else % Non interactive part
212    if FBTFlag
213        TuneOld = gettuneFBT;
214    else
215        TuneOld = gettune;
216    end
217end
218
219
220% Set the tune
221DeltaTune = Nu - TuneOld;
222if size(DeltaTune,1) ~= 2
223        error('Input must be a 2x1 column vector.');
224end
225
226% Step the tune
227[DelQuad, ActuatorFamily] = steptune(DeltaTune, TuneResponseMatrix, UnitsFlag{:}, ModeFlag{:});
228
229
230if InteractiveFlag
231   disp('  Set tune complete.');
232end
233
Note: See TracBrowser for help on using the repository browser.