source: MML/trunk/machine/SOLEIL/StorageRing/setlocodata.m

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

To have a stable version on the server.

  • Property svn:executable set to *
File size: 15.1 KB
Line 
1function setlocodata(CommandInput, FileName)
2%SETLOCODATA - Applies the LOCO calibration data to both the middle layer & the accelerator
3%  setlocodata(CommandInput, FileName)
4%
5%  INPUTS
6%  1. CommandInput
7%     'Nominal'    - Sets nominal gains (1) / rolls (0) to the model.
8%     'SetGains'   - Set gains/coupling from a LOCO file.
9%     'Symmetrize' - Symmetry correction of the lattice based on a LOCO file.
10%     'CorrectCoupling' - Coupling correction of the lattice based on a LOCO file.
11%     'SetModel'   - Set the model from a LOCO file.  But it only changes
12%                    the part of the model that does not get corrected
13%                    in 'Symmetrize' (also does a SetGains).
14%     'LOCO2Model' - Set the model from a LOCO file (also does a 'SetGains').
15%                    This sets all lattice machines fit in the LOCO run to the model.
16%     'EtaWave'    - Set a dispersion wave.
17%  2. FileName - LOCO file name {Default: getfamilydata('OpsData', 'LOCOFile')}
18%                '' to browse for a file
19%
20%  NOTES
21%  How one uses this function depends on how LOCO was setup.
22%  1. Use setlocodata('Nominal') if no model calibration information is known.
23%  2. The most typical situation is to apply:
24%         setlocodata('Symmetrize') to the accelerator
25%         setlocodata('SetModel')   to the middle layer (usually done in setoperationalmode)
26%  3. If a LOCO run was done on the present lattice with no changes made to lattice
27%     after LOCO run, then setting all the LOCO fits to the model makes sense.
28%         setlocodata('LOCO2Model')
29%  4. This function obviously has machine dependent parts.
30%
31% See Also plotlocodata, gcr2loco, getgain, getroll, getcrunch
32
33
34%
35%  Written by Greg Portmann
36
37
38global THERING
39
40if nargin < 1
41    %CommandInput = 'Default';
42    ModeCell = {'Nominal - Set Gain=1 & Rolls=0 in the model', 'SetGains - Set gains/rolls from a LOCO file','Symmetrize - Symmetry correction of the lattice', 'CorrectCoupling - Coupling correction of the lattice', 'SetModel - Set the model from a LOCO file','LOCO2Model - Set the model from a LOCO file (also does a SetGains)', 'see "help setlocodata" for more details'};
43    [ModeNumber, OKFlag] = listdlg('Name','Soleil','PromptString', ...
44        'Select the proper set LOCO data command:', ...
45        'SelectionMode','single', 'ListString', ModeCell, 'ListSize', [500 200]);
46    if OKFlag ~= 1
47        fprintf('   setlocodata cancelled\n');
48        return
49    end
50    if ModeNumber == 1
51        CommandInput = 'Nominal';
52    elseif ModeNumber == 2
53        CommandInput = 'SetGains';
54    elseif ModeNumber == 3
55        CommandInput = 'Symmetrize';
56    elseif ModeNumber == 4
57        CommandInput = 'CorrectCoupling';
58    elseif ModeNumber == 5
59        CommandInput = 'SetModel';
60    elseif ModeNumber == 6
61        CommandInput = 'LOCO2Model';
62    elseif ModeNumber == 7
63        help setlocodata;
64        return
65    end
66end
67
68
69if nargin < 2
70    % Default (Golden) LOCO file
71    % If empty, the user will be prompted if needed.
72    FileName = getfamilydata('OpsData','LOCOFile');
73end
74
75
76% Device list
77BPMxFamily = 'BPMx';
78
79BPMxDeviceList = family2dev(BPMxFamily);
80BPMxDeviceListTotal = family2dev(BPMxFamily,0);
81
82BPMzFamily = 'BPMz';
83BPMzDeviceList = family2dev(BPMzFamily);
84BPMzDeviceListTotal = family2dev(BPMzFamily,0);
85
86HCMFamily = 'HCOR';
87HCMDeviceList = family2dev(HCMFamily);
88HCMDeviceListTotal = family2dev(HCMFamily,0);
89
90VCMFamily = 'VCOR';
91VCMDeviceList = family2dev(VCMFamily);
92VCMDeviceListTotal = family2dev(VCMFamily,0);
93
94
95if any(strcmpi(CommandInput, 'Nominal'))
96    fprintf('   Using nominal BPM and corrector Gain=1 and Roll=0\n');
97
98    % To speed things up, put Gains/Rolls/etc in the AO
99    AO = getao;
100
101    % Zero or one the gains and rolls
102    AO.(BPMxFamily).Gain   = ones(size(BPMxDeviceListTotal,1),1);
103    AO.(BPMzFamily).Gain   = ones(size(BPMzDeviceListTotal,1),1);
104    AO.(BPMxFamily).Roll   = zeros(size(BPMxDeviceListTotal,1),1);
105    AO.(BPMzFamily).Roll   = zeros(size(BPMzDeviceListTotal,1),1);
106    AO.(BPMxFamily).Crunch = zeros(size(BPMxDeviceListTotal,1),1);
107    AO.(BPMzFamily).Crunch = zeros(size(BPMzDeviceListTotal,1),1);
108
109    AO.(VCMFamily).Gain = ones(size(HCMDeviceListTotal,1),1);
110    AO.(HCMFamily).Gain = ones(size(VCMDeviceListTotal,1),1);
111    AO.(VCMFamily).Roll = zeros(size(HCMDeviceListTotal,1),1);
112    AO.(HCMFamily).Roll = zeros(size(VCMDeviceListTotal,1),1);
113
114
115    % Set the roll, crunch to the AT model to be used by getpvmodel, setpvmodel, etc
116    setatfield(BPMxFamily, 'GCR', [AO.(BPMxFamily).Gain AO.(BPMzFamily).Gain AO.(BPMxFamily).Crunch AO.(BPMxFamily).Roll], BPMxDeviceListTotal);
117
118    % Set the gains to the AT model to be used by getpvmodel, setpvmodel, etc
119    % Make sure the Roll field is 1x2 even for single plane correctors
120
121    % First set the cross planes to zero
122    setatfield(HCMFamily, 'Roll', 0*AO.(HCMFamily).Roll, HCMDeviceListTotal, 1, 2);
123    setatfield(VCMFamily, 'Roll', 0*AO.(VCMFamily).Roll, VCMDeviceListTotal, 1, 1);
124
125    % Then set the roll field
126    setatfield(HCMFamily, 'Roll', AO.(HCMFamily).Roll, HCMDeviceListTotal, 1, 1);
127    setatfield(VCMFamily, 'Roll', AO.(VCMFamily).Roll, VCMDeviceListTotal, 1, 2);
128
129    setao(AO);
130
131
132elseif any(strcmpi(CommandInput, 'SetGains'))
133
134    if isempty(FileName) || strcmp(FileName, '.')
135        if isempty(FileName)
136            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?', [getfamilydata('Directory','DataRoot'), 'LOCO', filesep]);
137        else
138            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?');
139        end
140        drawnow;
141        if isequal(FileName,0) || isequal(DirectoryName,0)
142            fprintf('   setlocodata canceled\n');
143            return
144        end
145        FileName = [DirectoryName FileName];
146    end
147
148    % Set the model gains
149    setlocodata('Nominal');
150
151    AO = getao;
152
153    % Load the LOCO data
154    fprintf('   Setting BPM and corrector gains and rolls based on %s.\n', FileName);
155    load(FileName);
156
157
158    % Get the device list from the LOCO file
159    try
160        BPMxDeviceList = LocoMeasData.HBPM.DeviceList;
161        BPMzDeviceList = LocoMeasData.VBPM.DeviceList;
162        HCMDeviceList  = LocoMeasData.HCM.DeviceList;
163        VCMDeviceList  = LocoMeasData.VCM.DeviceList;
164    catch
165        % Legacy
166        BPMxDeviceList = LocoMeasData.HBPM.DeviceList;
167        BPMzDeviceList = LocoMeasData.VBPM.DeviceList;
168        HCMDeviceList  = LocoMeasData.HCM.DeviceList;
169        VCMDeviceList  = LocoMeasData.VCM.DeviceList;
170    end
171
172
173    % Change to Gain, Roll, Crunch system (Need to add a logic for single view BPMs???)
174    i = findrowindex(BPMxDeviceList, BPMxDeviceListTotal);
175    for j = 1:length(BPMData(end).HBPMGain)
176        MLOCO = [BPMData(end).HBPMGain(j)     BPMData(end).HBPMCoupling(j)
177            BPMData(end).VBPMCoupling(j) BPMData(end).VBPMGain(j) ];
178
179        [AO.(BPMxFamily).Gain(i(j),:), AO.(BPMzFamily).Gain(i(j),:), AO.(BPMxFamily).Crunch(i(j),:), AO.(BPMxFamily).Roll(i(j),:)] = loco2gcr(MLOCO);
180    end
181    AO.(BPMzFamily).Roll   = AO.(BPMxFamily).Roll;
182    AO.(BPMzFamily).Crunch = AO.(BPMxFamily).Crunch;
183
184    if ~isreal(AO.(BPMxFamily).Gain)
185        error('Horizontal BPM gain is complex.');
186    end
187    if ~isreal(AO.(BPMzFamily).Gain)
188        error('Vertical BPM gain is complex.');
189    end
190    if ~isreal(AO.(BPMxFamily).Crunch)
191        error('BPM Crunch is complex.');
192    end
193    if ~isreal(AO.(BPMxFamily).Roll)
194        error('BPM roll is complex.');
195    end
196
197
198
199    %%%%%%%%%%%%%%
200    % Correctors %
201    %%%%%%%%%%%%%%
202
203    % Kick strength (LOCO is in milliradian)
204    % LOCO is run with the original gain in hw2physics (stored in LocoMeasData.VCMGain/LocoMeasData.HCMGain).
205    % The new gain must combine the new CM gain and the one used in buildlocoinput.
206    % hw2physics:  Rad = G * amps   (original)
207    % LOCO gain:   Gloco = KickNew/KickStart
208    % New hw2physics gain: Gloco * G
209
210    % HCM
211    i = findrowindex(HCMDeviceList, HCMDeviceListTotal);
212
213    HCMGainOldLOCO  = LocoMeasData.HCMGain .* cos(LocoMeasData.HCMRoll);
214    HCMGainLOCO     = HCMGainOldLOCO .* CMData(end).HCMKicks ./ CMData(1).HCMKicks;
215    HCMCouplingLOCO = HCMGainLOCO .* CMData(end).HCMCoupling;
216
217    %AO.(HCMFamily).Roll(i) = atan2(-HCMCouplingLOCO, HCMGainLOCO);
218    AO.(HCMFamily).Roll(i) = atan(HCMCouplingLOCO ./ abs(HCMGainLOCO));
219    AO.(HCMFamily).Gain(i) = sign(HCMGainLOCO) .* sqrt(HCMCouplingLOCO.^2 + HCMGainLOCO.^2);
220
221
222    % VCM
223    i = findrowindex(VCMDeviceList, VCMDeviceListTotal);
224
225    VCMGainOldLOCO  = LocoMeasData.VCMGain .* cos(LocoMeasData.VCMRoll);
226    VCMGainLOCO     = VCMGainOldLOCO .* CMData(end).VCMKicks ./ CMData(1).VCMKicks;
227    VCMCouplingLOCO = VCMGainLOCO .* CMData(end).VCMCoupling;
228
229    %AO.(VCMFamily).Roll(i) = atan2(-VCMCouplingLOCO, VCMGainLOCO);
230    AO.(VCMFamily).Roll(i) = atan(-VCMCouplingLOCO ./ abs(VCMGainLOCO));
231    AO.(VCMFamily).Gain(i) = sign(VCMGainLOCO) .* sqrt(VCMCouplingLOCO.^2 + VCMGainLOCO.^2);
232
233
234    % Set the roll, crunch to the AT model to be used by getpvmodel, setpvmodel, etc
235    setatfield(BPMxFamily, 'GCR', [AO.(BPMxFamily).Gain AO.(BPMzFamily).Gain AO.(BPMxFamily).Crunch AO.(BPMxFamily).Roll], BPMxDeviceListTotal);
236
237    % Set the gains to the AT model to be used by getpvmodel, setpvmodel, etc
238    % Make sure the Roll field is 1x2 even for single plane correctors
239
240    % First set the cross planes to zero
241    setatfield(HCMFamily, 'Roll', 0*AO.(HCMFamily).Roll, HCMDeviceListTotal, 1, 2);
242    setatfield(VCMFamily, 'Roll', 0*AO.(VCMFamily).Roll, VCMDeviceListTotal, 1, 1);
243
244    % Then set the roll field
245    setatfield(HCMFamily, 'Roll', AO.(HCMFamily).Roll, HCMDeviceListTotal, 1, 1);
246    setatfield(VCMFamily, 'Roll', AO.(VCMFamily).Roll, VCMDeviceListTotal, 1, 2);
247
248
249    % If other magnet fits were done (like roll), it should be add to the AT model as well
250
251    setao(AO);
252
253
254elseif any(strcmpi(CommandInput, 'SetModel'))
255
256       % Some LOCO errors are applied to the accelerator 'SetMachine' and some
257    % go to the model.  If errors detected by LOCO are not applied to the accelerator,
258    % then include them in the AT and Middle Layer model.
259
260    % The assumption is that setlocodata('SetMachine') has already been run.
261    % So QF, QD, QFA, QDA, SQSF, SQSD have changed in the accelerator to match
262    % the LOCO run.
263
264    if isempty(FileName) || strcmp(FileName, '.')
265        if isempty(FileName)
266            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?', [getfamilydata('Directory','DataRoot'), 'LOCO', filesep]);
267        else
268            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?');
269        end
270        drawnow;
271        if isequal(FileName,0) || isequal(DirectoryName,0)
272            fprintf('   setlocodata canceled\n');
273            return
274        end
275        FileName = [DirectoryName FileName];
276    end
277
278
279    % Load the LOCO data
280    load(FileName);
281
282
283    % Set the model gains
284    setlocodata('SetGains', FileName);
285
286
287elseif any(strcmpi(CommandInput, 'SetMachine'))
288
289    if isempty(FileName) || strcmp(FileName, '.')
290        if isempty(FileName)
291            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?', [getfamilydata('Directory','DataRoot'), 'LOCO', filesep]);
292        else
293            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?');
294        end
295        drawnow;
296        if isequal(FileName,0) || isequal(DirectoryName,0)
297            fprintf('   setlocodata canceled\n');
298            return
299        end
300        FileName = [DirectoryName FileName];
301    end
302
303    % Load the LOCO data
304    load(FileName);
305   
306    le = length(FitParameters);
307
308    QFamilies = findmemberof('QUAD');
309
310    ioffset = 0;
311    for k=1:length(QFamilies),
312        ifam = QFamilies{k};
313        if family2status(ifam)
314            nquad = length(family2dev(ifam));
315            iparam = (1:length(family2dev(ifam)))+ioffset;
316            ioffset = iparam(end);
317            Qscale = FitParameters(le).Values(iparam)./FitParameters(1).Values(iparam);
318            setsp(ifam, getsp(ifam).*Qscale);
319        end
320    end
321
322elseif any(strcmpi(CommandInput, 'CorrectCoupling'))
323
324    if isempty(FileName) || strcmp(FileName, '.')
325        if isempty(FileName)
326            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?', [getfamilydata('Directory','DataRoot'), 'LOCO', filesep]);
327        else
328            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?');
329        end
330        drawnow;
331        if isequal(FileName,0) || isequal(DirectoryName,0)
332            fprintf('   setlocodata canceled\n');
333            return
334        end
335        FileName = [DirectoryName FileName];
336    end
337
338   
339    % Load the LOCO data
340    load(FileName);
341
342    NQT = size(family2dev('QT'),1);
343    fprintf('   Correcting the coupling based on LOCO file %s.\n', FileName);
344    fprintf('   It is assumed that the QT are in FitParameters.Values(end-%d:end)\n', NQT-1);
345
346    QT = FitParameters(end).Values(end-(NQT-1):end);
347
348    % Starting point for the skew quadrupoles when LOCO data was measured
349    MachineConfig = LocoMeasData.MachineConfig;
350    setpv(MachineConfig.QT.Setpoint);
351
352    QThw = physics2hw('QT', 'Setpoint', -QT);
353
354    % Maximum setpoint check
355    if any(abs(MachineConfig.QT.Setpoint.Data+QThw)>maxsp('QT'))
356        error('At least one of the QT would go beyond it''s limit ... aborting coupling correction');
357    end
358
359    % Make the setpoint change
360    stepsp('QT', QThw);
361
362    % Keep the change?
363    CorrectFlag = questdlg('Keep the new skew quadrupole setpoints or return to the old values?','SETLOCOGAINS(''CorrectCoupling'')','Keep this lattice','Restore Old Lattice','Keep this lattice');
364    if strcmpi(CorrectFlag, 'Restore Old Lattice') || isempty(CorrectFlag)
365        fprintf('   Changing the skew quadrupole magnets back to the original setpoints.\n');
366        stepsp('QT', QThw);
367    end
368
369
370elseif any(strcmpi(CommandInput, 'LOCO2Model'))
371
372    % LOCO is usually used to correct the model.  If the LOCO fit parameters are
373    % not applied to the accelerator, then the entire model needs to be updated.
374    % Ie, the machine lattice file is the same as it was when the LOCO data was
375    % taken, then put the LOCO output settings in the model.
376
377    if isempty(FileName) || strcmp(FileName, '.')
378        if isempty(FileName)
379            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?', [getfamilydata('Directory','DataRoot'), 'LOCO', filesep]);
380        else
381            [FileName, DirectoryName] = uigetfile('*.mat', 'LOCO Output File Name?');
382        end
383        drawnow;
384        if isequal(FileName,0) || isequal(DirectoryName,0)
385            fprintf('   setlocodata canceled\n');
386            return
387        end
388        FileName = [DirectoryName FileName];
389    end
390
391
392    % Load the LOCO data
393    load(FileName);
394
395
396    % Use loco file for the lattice and the fit parameter
397    % Using everything in the loco lattice may not be what you want!
398    global THERING
399    RINGData.Lattice = THERING;
400    for i = 1:length(FitParameters(end).Params)
401        RINGData = locosetlatticeparam(RINGData, FitParameters(end).Params{i}, FitParameters(end).Values(i));
402    end
403    THERING = RINGData.Lattice;
404
405
406    % Since the lattice may have changed
407    %updateatindex;
408
409
410    % Set the model gains (this added GCR field to lattice)
411    setlocodata('SetGains', FileName);
412
413else
414
415    error('   ');
416
417end
Note: See TracBrowser for help on using the repository browser.