1 | function [LocoMeasData, BPMData, CMData, RINGData, FitParameters, LocoFlags] = buildlocofitparameters(FileName) |
---|
2 | %BUILDLOCOFITPARAMETERS - SOLEIL LOCO fit parameters |
---|
3 | % |
---|
4 | % [LocoMeasData, BPMData, CMData, RINGData, FitParameters, LocoFlags] = buildlocoinput(FileName) |
---|
5 | |
---|
6 | % |
---|
7 | %% Written By Laurent S. Nadolski |
---|
8 | |
---|
9 | %%%%%%%%%%%%%% |
---|
10 | % Input file % |
---|
11 | %%%%%%%%%%%%%% |
---|
12 | if nargin == 0 |
---|
13 | [FileName, DirectoryName, FilterIndex] = uigetfile('*.mat','Select a LOCO input file'); |
---|
14 | if FilterIndex == 0 |
---|
15 | return; |
---|
16 | end |
---|
17 | FileName = [DirectoryName, FileName]; |
---|
18 | end |
---|
19 | |
---|
20 | load(FileName); |
---|
21 | |
---|
22 | %%%%%%%%%%%%%%%%%%%%%% |
---|
23 | % Remove bad devices % |
---|
24 | %%%%%%%%%%%%%%%%%%%%%% |
---|
25 | RemoveHCMDeviceList = []; |
---|
26 | RemoveVCMDeviceList = []; |
---|
27 | |
---|
28 | RemoveHBPMDeviceList = []; |
---|
29 | RemoveVBPMDeviceList = []; |
---|
30 | |
---|
31 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
32 | % This function only works on the first iteration % |
---|
33 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
34 | if exist('BPMData','var') && length(BPMData)>1 |
---|
35 | BPMData = BPMData(1); |
---|
36 | end |
---|
37 | if exist('CMData','var') && length(CMData)>1 |
---|
38 | CMData = CMData(1); |
---|
39 | end |
---|
40 | if exist('FitParameters','var') && length(FitParameters)>1 |
---|
41 | FitParameters = FitParameters(1); |
---|
42 | end |
---|
43 | if exist('LocoFlags','var') && length(LocoFlags)>1 |
---|
44 | LocoFlags = LocoFlags(1); |
---|
45 | end |
---|
46 | if exist('LocoModel','var') && length(LocoModel)>1 |
---|
47 | LocoModel = LocoModel(1); |
---|
48 | end |
---|
49 | |
---|
50 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
51 | % Make sure the start point in loaded in the AT model % |
---|
52 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
53 | if ~isempty(FitParameters) |
---|
54 | for i = 1:length(FitParameters.Params) |
---|
55 | RINGData = locosetlatticeparam(RINGData, FitParameters.Params{i}, FitParameters.Values(i)); |
---|
56 | end |
---|
57 | end |
---|
58 | |
---|
59 | |
---|
60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
61 | % LocoFlags to change from the default % |
---|
62 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
63 | % LocoFlags.Threshold = 1e-5; |
---|
64 | % LocoFlags.OutlierFactor = 10; |
---|
65 | % LocoFlags.SVmethod = 1e-2; |
---|
66 | LocoFlags.SVmethod = 1:895; |
---|
67 | % LocoFlags.HorizontalDispersionWeight = 12.5; |
---|
68 | % LocoFlags.VerticalDispersionWeight = 12.5; |
---|
69 | % LocoFlags.AutoCorrectDelta = 'Yes'; |
---|
70 | % LocoFlags.Coupling = 'No'; |
---|
71 | % LocoFlags.Dispersion = 'No'; |
---|
72 | % LocoFlags.Normalize = 'Yes'; |
---|
73 | % LocoFlags.ResponseMatrixCalculatorFlag1 = 'Linear'; |
---|
74 | % LocoFlags.ResponseMatrixCalculatorFlag2 = 'FixedPathLength'; |
---|
75 | % LocoFlags.CalculateSigma = 'No'; |
---|
76 | % LocoFlags.SinglePrecision = 'Yes'; |
---|
77 | |
---|
78 | % CMData.FitKicks = 'Yes'; |
---|
79 | % CMData.FitCoupling = 'No'; |
---|
80 | % |
---|
81 | % BPMData.FitGains = 'Yes'; |
---|
82 | % BPMData.FitCoupling = 'No'; |
---|
83 | |
---|
84 | |
---|
85 | % Corrector magnets to disable |
---|
86 | j = findrowindex(RemoveHCMDeviceList, LocoMeasData.HCM.DeviceList); |
---|
87 | if ~isempty(j) |
---|
88 | irm = findrowindex(j(:),CMData.HCMGoodDataIndex(:)); |
---|
89 | CMData.HCMGoodDataIndex(irm) = []; |
---|
90 | end |
---|
91 | |
---|
92 | j = findrowindex(RemoveVCMDeviceList, LocoMeasData.VCM.DeviceList); |
---|
93 | if ~isempty(j) |
---|
94 | irm = findrowindex(j(:),CMData.VCMGoodDataIndex(:)); |
---|
95 | CMData.VCMGoodDataIndex(irm) = []; |
---|
96 | end |
---|
97 | |
---|
98 | |
---|
99 | % BPMs to disable |
---|
100 | j = findrowindex(RemoveHBPMDeviceList, LocoMeasData.HBPM.DeviceList); |
---|
101 | if ~isempty(j) |
---|
102 | irm = findrowindex(j(:),BPMData.HBPMGoodDataIndex(:)); |
---|
103 | BPMData.HBPMGoodDataIndex(irm) = []; |
---|
104 | end |
---|
105 | |
---|
106 | j = findrowindex(RemoveVBPMDeviceList, LocoMeasData.VBPM.DeviceList); |
---|
107 | if ~isempty(j) |
---|
108 | irm = findrowindex(j(:),BPMData.VBPMGoodDataIndex(:)); |
---|
109 | BPMData.VBPMGoodDataIndex(irm) = []; |
---|
110 | end |
---|
111 | |
---|
112 | %%%%%%%%%%%%%%%%% |
---|
113 | % FitParameters % |
---|
114 | %%%%%%%%%%%%%%%%% |
---|
115 | |
---|
116 | % Individual magnets |
---|
117 | % For each parameter which is fit in the model a numerical response matrix |
---|
118 | % gradient needs to be determined. The FitParameters data structure determines what |
---|
119 | % parameter in the model get varied and how are they grouped. For no parameter fits, set |
---|
120 | % FitParameters.Params to an empty vector. |
---|
121 | % FitParameters.Params = parameter group definition (cell array for AT) |
---|
122 | % FitParameters.Values = Starting value for the parameter fit |
---|
123 | % FitParameters.Deltas = change in parameter value used to compute the gradient (NaN forces loco to choose, see auto-correct delta flag below) |
---|
124 | % FitParameters.FitRFFrequency = ('Yes'/'No') Fit the RF frequency? |
---|
125 | % FitParameters.DeltaRF = Change in RF frequency when measuring "dispersion". |
---|
126 | % If the RF frequency is being fit the output is stored here. |
---|
127 | % |
---|
128 | % The FitParameters structure also contains the standard deviations of the fits: |
---|
129 | % LocoValuesSTD |
---|
130 | % FitParameters.DeltaRFSTD |
---|
131 | % |
---|
132 | % Note: FitParameters.DeltaRF is used when including dispersion in the response matrix. |
---|
133 | % LocoMeasData.DeltaRF is not used directly in loco. Usually one would set |
---|
134 | % FitParameters.DeltaRF = LocoMeasData.DeltaRF as a starting point for the RF frequency. |
---|
135 | |
---|
136 | |
---|
137 | ModeCell = {'Fit by family', 'Fit magnets by power supply', 'Fit selected quad', 'Fit magnets by power supply Nanoscopium'}; |
---|
138 | [ButtonName, OKFlag] = listdlg('Name','BUILDLOCOINPUT','PromptString',{'Fit Parameter Selection:','(Not including skew quadrupoles)'}, 'SelectionMode','single', 'ListString', ModeCell, 'ListSize', [350 125], 'InitialValue', 2); |
---|
139 | if OKFlag ~= 1 |
---|
140 | ButtonName = 1; |
---|
141 | end |
---|
142 | drawnow; |
---|
143 | FitParameters = []; |
---|
144 | n = 0; |
---|
145 | global THERING; % TODO remove not clean at all |
---|
146 | |
---|
147 | switch ButtonName |
---|
148 | case 1 % By family |
---|
149 | |
---|
150 | n = 0; |
---|
151 | FitParameters.Deltas = []; |
---|
152 | FitParameters.Values = []; |
---|
153 | |
---|
154 | for k=1:10, |
---|
155 | % Q1 K-values |
---|
156 | n = n+1; |
---|
157 | QI = findcells(THERING,'FamName',['Q' num2str(k)]); |
---|
158 | FitParameters.Params{n} = mkparamgroup(THERING, QI, 'K'); |
---|
159 | FitParameters.Values = [FitParameters.Values; getcellstruct(THERING, 'K', QI(1))]; |
---|
160 | FitParameters.Deltas = [FitParameters.Deltas; NaN]; |
---|
161 | end |
---|
162 | |
---|
163 | |
---|
164 | case 2 % Fit by power supply |
---|
165 | |
---|
166 | n = 0; |
---|
167 | FitParameters.Deltas = []; |
---|
168 | FitParameters.Values = []; |
---|
169 | |
---|
170 | % K-values |
---|
171 | for k=1:10, |
---|
172 | QI = findcells(THERING,'FamName',['Q' num2str(k)]); |
---|
173 | for loop=1:length(QI) |
---|
174 | n = n + 1; |
---|
175 | FitParameters.Params{n} = mkparamgroup(THERING, QI(loop), 'K'); |
---|
176 | end |
---|
177 | FitParameters.Values = [FitParameters.Values; getcellstruct(THERING, 'K', QI)]; |
---|
178 | FitParameters.Deltas = [FitParameters.Deltas; NaN * ones(length(QI),1)]; |
---|
179 | end |
---|
180 | |
---|
181 | case 3 % Fit by power supply less than 160 |
---|
182 | |
---|
183 | n = 0; |
---|
184 | FitParameters.Deltas = []; |
---|
185 | FitParameters.Values = []; |
---|
186 | |
---|
187 | % K-values |
---|
188 | for k= [1 2 4 7 9], |
---|
189 | QI = findcells(THERING,'FamName',['Q' num2str(k)]); |
---|
190 | for loop=1:length(QI) |
---|
191 | n = n + 1; |
---|
192 | FitParameters.Params{n} = mkparamgroup(THERING, QI(loop), 'K'); |
---|
193 | end |
---|
194 | FitParameters.Values = [FitParameters.Values; getcellstruct(THERING, 'K', QI)]; |
---|
195 | FitParameters.Deltas = [FitParameters.Deltas; NaN * ones(length(QI),1)]; |
---|
196 | end |
---|
197 | |
---|
198 | case 4 % Fit by power supply with Nanoscopium: 163 quads |
---|
199 | |
---|
200 | n = 0; |
---|
201 | FitParameters.Deltas = []; |
---|
202 | FitParameters.Values = []; |
---|
203 | |
---|
204 | % K-values |
---|
205 | for k=1:12, |
---|
206 | QI = findcells(THERING,'FamName',['Q' num2str(k)]); |
---|
207 | for loop=1:length(QI) |
---|
208 | n = n + 1; |
---|
209 | FitParameters.Params{n} = mkparamgroup(THERING, QI(loop), 'K'); |
---|
210 | end |
---|
211 | FitParameters.Values = [FitParameters.Values; getcellstruct(THERING, 'K', QI)]; |
---|
212 | FitParameters.Deltas = [FitParameters.Deltas; NaN * ones(length(QI),1)]; |
---|
213 | end |
---|
214 | otherwise |
---|
215 | end |
---|
216 | |
---|
217 | %%%%%%%%%%%%%%%%%%%%%%% |
---|
218 | % Skew quadrupole fits |
---|
219 | %%%%%%%%%%%%%%%%%%%%%%% |
---|
220 | |
---|
221 | ModeCell = {'Fit at Sextupoles', 'Fit By Power Supply', 'Do Not Fit Skew Quadrupoles'}; |
---|
222 | [ButtonName, OKFlag] = listdlg('Name','BUILDLOCOINPUT','PromptString','Skew Quadrupole Fits?', 'SelectionMode','single', 'ListString', ModeCell, 'ListSize', [350 125], 'InitialValue', 2); |
---|
223 | if OKFlag ~= 1 |
---|
224 | ButtonName = length(ModeCell); % Default |
---|
225 | end |
---|
226 | |
---|
227 | switch ButtonName |
---|
228 | case 1 |
---|
229 | fprintf(' Skew fit at Sextupoles needs work.\n\n'); |
---|
230 | % case 1 |
---|
231 | % % Fit skew quadrupoles in the sextupoles |
---|
232 | % SFI = findcells(RINGData.Lattice,'FamName','SF'); |
---|
233 | % SFn = size(family2dev('SF'),1); |
---|
234 | % |
---|
235 | % for loop = 1:length(SFI) |
---|
236 | % if length(SFI) == SFn |
---|
237 | % n = n + 1; |
---|
238 | % FitParameters.Params{n} = mkparamgroup(RINGData.Lattice,SFI(loop),'s'); |
---|
239 | % elseif length(SFI) == 2*SFn |
---|
240 | % % Split sextupoles |
---|
241 | % N1 = 2*loop-1; |
---|
242 | % N2 = 2*loop; |
---|
243 | % n = n + 1; |
---|
244 | % FitParameters.Params{n} = mkparamgroup(RINGData.Lattice,SFI([N1 N2]),'s'); |
---|
245 | % else |
---|
246 | % error(' Error setting the SF parameter group.'); |
---|
247 | % end |
---|
248 | % end |
---|
249 | % |
---|
250 | % FitParameters.Values = [FitParameters.Values; zeros(SFn,1)]; |
---|
251 | % FitParameters.Deltas = [FitParameters.Deltas; 0.5e-2 * ones(SFn,1)]; % automatic delta determination does not work if starting value is 0 |
---|
252 | % |
---|
253 | % |
---|
254 | % % Fit skew quadrupoles in the sextupoles |
---|
255 | % SDI = findcells(RINGData.Lattice,'FamName','SD'); |
---|
256 | % SDn = size(family2dev('SD'),1); |
---|
257 | % |
---|
258 | % for loop = 1:length(SDI) |
---|
259 | % if length(SDI) == SDn |
---|
260 | % n = n + 1; |
---|
261 | % FitParameters.Params{n} = mkparamgroup(RINGData.Lattice,SDI(loop),'s'); |
---|
262 | % elseif length(SDI) == 2*SDn |
---|
263 | % % Split sextupoles |
---|
264 | % N1 = 2*loop-1; |
---|
265 | % N2 = 2*loop; |
---|
266 | % n = n + 1; |
---|
267 | % FitParameters.Params{n} = mkparamgroup(RINGData.Lattice,SDI([N1 N2]),'s'); |
---|
268 | % else |
---|
269 | % error(' Error setting the SD parameter group.'); |
---|
270 | % end |
---|
271 | % end |
---|
272 | % |
---|
273 | % FitParameters.Values = [FitParameters.Values; zeros(SDn,1)]; |
---|
274 | % FitParameters.Deltas = [FitParameters.Deltas; 0.5e-2 * ones(SDn,1)]; % automatic delta determination does not work if starting value is 0 |
---|
275 | % |
---|
276 | case 2 % 'Fit by Power Supply' |
---|
277 | % skew quad |
---|
278 | QTI = family2atindex('QT',family2dev('QT')); |
---|
279 | for loop=1:length(QTI), |
---|
280 | n = n + 1; |
---|
281 | FitParameters.Params{n} = mkparamgroup(THERING, QTI(loop), 'KS1'); |
---|
282 | end |
---|
283 | FitParameters.Values = [FitParameters.Values; zeros(length(QTI),1)]; |
---|
284 | FitParameters.Deltas = [FitParameters.Deltas; 1 * ones(length(QTI),1)]; |
---|
285 | |
---|
286 | case 3 %'Don't Fit' |
---|
287 | fprintf(' Skew quadrupole not fit.\n\n'); |
---|
288 | |
---|
289 | otherwise |
---|
290 | fprintf(' Skew quadrupole not fit.\n\n'); |
---|
291 | end |
---|
292 | |
---|
293 | fprintf('\n'); |
---|
294 | |
---|
295 | |
---|
296 | % |
---|
297 | % %%%%%%%%%%%%%%%%%%%%% |
---|
298 | % % Parameter Weights % |
---|
299 | % %%%%%%%%%%%%%%%%%%%%% |
---|
300 | % |
---|
301 | % % For each cell of FitParameters.Weight.Value, a rows is added to the A matrix |
---|
302 | % % Index of the row of A: FitParameters.Weight.Index{i} |
---|
303 | % % Value of the weight: FitParameters.Weight.Value{i} / mean(Mstd) |
---|
304 | % |
---|
305 | % ModeCell = {'No Parameter Weigths', 'Add Parameter Weights'}; |
---|
306 | % [ButtonName, OKFlag] = listdlg('Name','BUILDLOCOINPUT','PromptString','Weights?', 'SelectionMode','single', 'ListString', ModeCell, 'ListSize', [200 75], 'InitialValue', 2); |
---|
307 | % if OKFlag ~= 1 |
---|
308 | % ButtonName = 1; % Default |
---|
309 | % end |
---|
310 | % |
---|
311 | % switch ButtonName |
---|
312 | % case 1 |
---|
313 | % % No Weights |
---|
314 | % if isfield(FitParameters, 'Weight') |
---|
315 | % FitParameters = rmfield(FitParameters, 'Weight'); |
---|
316 | % end |
---|
317 | % case 2 |
---|
318 | % %for ii = 1:length(FitParameters.Values) |
---|
319 | % for ii = 1:160, % specific weight for K-values |
---|
320 | % FitParameters.Weight.Index{ii,1} = ii; |
---|
321 | % %FitParameters.Weight.Value{ii,1} = 0.1; % for old BPM noise |
---|
322 | % FitParameters.Weight.Value{ii,1} = 0.001; % for new BPM noise (sept 07) |
---|
323 | % end |
---|
324 | % end |
---|
325 | |
---|
326 | |
---|
327 | |
---|
328 | % RF parameter fit setup (There is a flag to actually do the fit) |
---|
329 | if isempty(LocoMeasData.DeltaRF) |
---|
330 | FitParameters.DeltaRF = 100; % It's good to have something here so that LOCO will compute a model dispersion |
---|
331 | else |
---|
332 | FitParameters.DeltaRF = LocoMeasData.DeltaRF; |
---|
333 | end |
---|
334 | |
---|
335 | |
---|
336 | % File check |
---|
337 | [BPMData, CMData, LocoMeasData, LocoModel, FitParameters, LocoFlags, RINGData] = locofilecheck({BPMData, CMData, LocoMeasData, LocoModel, FitParameters, LocoFlags, RINGData}); |
---|
338 | |
---|
339 | |
---|
340 | % Save |
---|
341 | save(FileName, 'LocoModel', 'FitParameters', 'BPMData', 'CMData', 'RINGData', 'LocoMeasData', 'LocoFlags'); |
---|
342 | |
---|