1 | function [OCS, OCS0, V, S, ErrorFlag] = setorbitbump(varargin) |
---|
2 | %SETORBITBUMP - Local bump program (uses setorbit) |
---|
3 | % [OCS, OCS0, V, S] = setorbitbump(BPMFamily, BPMDeviceList, GoalOrbit, CMFamily, CMIncrementList, NIter, SVDIndex, BPMWeight) |
---|
4 | % [OCS, OCS0, V, S] = setorbitbump(OCS, GoalOrbit, CMIncrementList, NIter, SVDIndex, BPMWeight) |
---|
5 | % |
---|
6 | % INPUTS |
---|
7 | % 1. BPMFamily - BPM family |
---|
8 | % 2. BPMDeviceList - BPM device list |
---|
9 | % 3. GoalOrbit - Goal orbit position (Referenced to an absolute or incremental orbit |
---|
10 | % depending on 'Incremental' or 'Absolute' flag) |
---|
11 | % 4. CMFamily - Corrector magnet family |
---|
12 | % 5. CMIncrementList - Magnet list upstream and downstream of the BPMs |
---|
13 | % For instance, [-2 1 3] uses the 2nd correctors upstream and |
---|
14 | % 1st and 3rd corrector downstream from the BPMs in the bump. |
---|
15 | % or |
---|
16 | % CMIncrementList can be an ordinary device list used for specifying correctors. |
---|
17 | % 6. NIter - Number of iterations {Default: 1} |
---|
18 | % (set NIter to 0 if no BPMs are functioning, see setorbit) |
---|
19 | % 7. SVDIndex - vector, maximum number, 'All', or |
---|
20 | % base on a threshold of min/max singular value {Default: see setorbit} |
---|
21 | % 8. BPMWeight - Weight applied to the BPMs inside the bump (GoalOrbit). BPM weighting |
---|
22 | % should only be required when the corrector are in a region of dispersion |
---|
23 | % and the RF frequency is not used in the orbit correction. |
---|
24 | % {Default BPMWeight is to weight the leakage twice as much as the GoalOrbit} |
---|
25 | % 9. Optional flags (any flags used in setorbit can also be used here) |
---|
26 | % 'Incremental' {Default} or 'Absolute' - Type of orbit change |
---|
27 | % 'Display' - Display bump characteristics (no display is the default) |
---|
28 | % 'SetPV' or 'SetSP' - Make the setpoint change {Default} |
---|
29 | % 'NoSetPV' or 'NoSetSP' - Don't set the magnets, just return the OCS |
---|
30 | % 'FitRF' or 'SetRF' - Flag to include the RF frequency as part of orbit correction. |
---|
31 | % 'LeakageCorrection' - Option to try to clean up the leakage after the bump is applied. |
---|
32 | % Note: 1. NIter for leakage correction is the same for the bump |
---|
33 | % 2. It's just like setting the weight to zero for a second set of iterations. |
---|
34 | % 3. For the horizontal plane, usually one should include the RF frequency |
---|
35 | % along with leakage correction. Otherwise, the goal orbit may not be attained. |
---|
36 | % 'Tolerance', Tol - Quit correction if the std(error) < Tol {Tol: 0} |
---|
37 | % 'RampSteps', NSteps - Number of steps to ramp in the correction {NSteps: 1} |
---|
38 | % This is used to avoid a large transient between setpoint changes. |
---|
39 | % |
---|
40 | % OUTPUTS (same as setorbit) |
---|
41 | % 1. OCS - Orbit correction structure (OCS) usable by setorbit |
---|
42 | % 2. OCS0 - Starting OCS |
---|
43 | % 3. V - Corrector magnet singular vectors |
---|
44 | % 4. Svalue - Singular values (vector) |
---|
45 | % |
---|
46 | % NOTES |
---|
47 | % 1. setorbitbump creates an OCS structure and uses setorbit to actually change the orbit. |
---|
48 | % |
---|
49 | % EXAMPLES |
---|
50 | % 1. 4 magnet horizontal incremental bump at BPM(6,6) and BPM(7,1) including the RF frequency |
---|
51 | % OCS = setorbitbump('BPMx',[6 6;7 1],[1;-1],'HCM',[-2 -1 1 2],'FitRF', 'Display'); |
---|
52 | % On 12-16-2003, [-2 -1 1 2] corresponded to HCM(6,3), HCM(6,4), HCM(7,1), HCM(7,3) |
---|
53 | % Display plots information before applying the bump. |
---|
54 | % |
---|
55 | % 2. If the response matrix is not perfect, a clean (minimal rms orbit error) bump can be created |
---|
56 | % by increasing the iteration (note: in regions of dispersion, all bumps will have leakage unless |
---|
57 | % the RF frequency is included). |
---|
58 | % [OCS, OCS0] = setorbitbump('BPMx',[6 6;7 1],[1;-1],'HCM',[-2 -1 1 2], 4, 'Display'); |
---|
59 | % DeltaHCM = OCS.CM.Data - OCS0.CM.Data; |
---|
60 | % BPMxDeviceList = OCS.BPM.DeviceList; |
---|
61 | % HCMDeviceList = OCS.CM.DeviceList; |
---|
62 | % |
---|
63 | % |
---|
64 | % See also setorbit, orbitcorrectionmethods, setorbitgui, rmdisp, plotcm, setorbitbumpgui |
---|
65 | % |
---|
66 | % Written by Greg Portmann |
---|
67 | |
---|
68 | |
---|
69 | %%%%%%%%%%%% |
---|
70 | % Defaults % |
---|
71 | %%%%%%%%%%%% |
---|
72 | OCS.BPM.FamilyName = []; |
---|
73 | OCS.BPM.DeviceList = []; |
---|
74 | GoalOrbit = []; |
---|
75 | OCS.CM.FamilyName = []; |
---|
76 | OCS.CM.DeviceList = []; |
---|
77 | CMIncrementList = []; |
---|
78 | OCS.NIter = 1; |
---|
79 | BPMWeight = []; |
---|
80 | OCS.Incremental = 1; |
---|
81 | DisplayFlag = 0; |
---|
82 | SetSPFlag = 1; |
---|
83 | NoLeakageFlag = 0; |
---|
84 | UnitsFlag = ''; |
---|
85 | ModeFlag = ''; |
---|
86 | |
---|
87 | L = getfamilydata('Circumference'); |
---|
88 | |
---|
89 | |
---|
90 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
91 | % Input parsing and checking % |
---|
92 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
93 | Flags = {}; |
---|
94 | for i = length(varargin):-1:1 |
---|
95 | if isstruct(varargin{i}) |
---|
96 | % Ignor structures |
---|
97 | elseif iscell(varargin{i}) |
---|
98 | % Ignor cells |
---|
99 | elseif strcmpi(varargin{i},'Golden') |
---|
100 | % Use the golden orbit |
---|
101 | %GoalOrbit = 'Golden'; |
---|
102 | %varargin(i) = []; |
---|
103 | elseif strcmpi(varargin{i},'Offset') |
---|
104 | % Use the offset orbit |
---|
105 | %GoalOrbit = 'Offset'; |
---|
106 | %varargin(i) = []; |
---|
107 | elseif strcmpi(varargin{i},'Display') |
---|
108 | Flags = [Flags varargin(i)]; |
---|
109 | DisplayFlag = 1; |
---|
110 | varargin(i) = []; |
---|
111 | elseif strcmpi(varargin{i},'NoDisplay') |
---|
112 | Flags = [Flags varargin(i)]; |
---|
113 | DisplayFlag = 0; |
---|
114 | varargin(i) = []; |
---|
115 | elseif strcmpi(varargin{i},'Inc') || strcmpi(varargin{i},'Incremental') |
---|
116 | OCS.Incremental = 1; |
---|
117 | varargin(i) = []; |
---|
118 | elseif strcmpi(varargin{i},'Abs') || strcmpi(varargin{i},'Absolute') |
---|
119 | OCS.Incremental = 0; |
---|
120 | varargin(i) = []; |
---|
121 | elseif strcmpi(varargin{i},'simulator') || strcmpi(varargin{i},'model') |
---|
122 | ModeFlag = 'SIMULATOR'; |
---|
123 | varargin(i) = []; |
---|
124 | elseif strcmpi(varargin{i},'Online') |
---|
125 | ModeFlag = 'Online'; |
---|
126 | varargin(i) = []; |
---|
127 | elseif strcmpi(varargin{i},'Manual') |
---|
128 | ModeFlag = 'Manual'; |
---|
129 | varargin(i) = []; |
---|
130 | elseif strcmpi(varargin{i},'physics') |
---|
131 | UnitsFlag = 'Physics'; |
---|
132 | varargin(i) = []; |
---|
133 | elseif strcmpi(varargin{i},'hardware') |
---|
134 | UnitsFlag = 'Hardware'; |
---|
135 | varargin(i) = []; |
---|
136 | elseif any(strcmpi(varargin{i},{'SetPV','SetSP'})) |
---|
137 | SetSPFlag = 1; |
---|
138 | varargin(i) = []; |
---|
139 | elseif any(strcmpi(varargin{i},{'NoSetPV','NoSetSP'})) |
---|
140 | SetSPFlag = 0; |
---|
141 | Flags = [Flags varargin(i)]; |
---|
142 | varargin(i) = []; |
---|
143 | elseif strcmpi(varargin{i},'LeakageCorrection') |
---|
144 | NoLeakageFlag = 1; |
---|
145 | varargin(i) = []; |
---|
146 | |
---|
147 | elseif strcmpi(varargin{i},'archive') || strcmpi(varargin{i},'noarchive') |
---|
148 | % Just remove |
---|
149 | varargin(i) = []; |
---|
150 | elseif strcmpi(varargin{i},'struct') || strcmpi(varargin{i},'numeric') |
---|
151 | % Just remove |
---|
152 | varargin(i) = []; |
---|
153 | |
---|
154 | elseif strcmpi(varargin{i},'CorrectorGain') |
---|
155 | Flags = [Flags varargin(i) varargin(i+1)]; |
---|
156 | varargin(i+1) = []; |
---|
157 | varargin(i) = []; |
---|
158 | |
---|
159 | elseif strcmpi(varargin{i},'Tolerance') |
---|
160 | Flags = [Flags varargin(i) varargin(i+1)]; |
---|
161 | varargin(i+1) = []; |
---|
162 | varargin(i) = []; |
---|
163 | |
---|
164 | elseif strcmpi(varargin{i},'RampSteps') |
---|
165 | Flags = [Flags varargin(i) varargin(i+1)]; |
---|
166 | varargin(i+1) = []; |
---|
167 | varargin(i) = []; |
---|
168 | |
---|
169 | elseif strcmpi(varargin{i},'ModelResp') |
---|
170 | Flags = [Flags varargin(i)]; |
---|
171 | varargin(i) = []; |
---|
172 | elseif strcmpi(varargin{i},'ModelDisp') |
---|
173 | Flags = [Flags varargin(i)]; |
---|
174 | varargin(i) = []; |
---|
175 | elseif strcmpi(varargin{i},'MeasDisp') |
---|
176 | Flags = [Flags varargin(i)]; |
---|
177 | varargin(i) = []; |
---|
178 | elseif strcmpi(varargin{i},'GoldenDisp') |
---|
179 | Flags = [Flags varargin(i)]; |
---|
180 | varargin(i) = []; |
---|
181 | |
---|
182 | elseif any(strcmpi(varargin{i},{'FitRF','SetRF','RFCorrector'})) |
---|
183 | Flags = [Flags varargin(i)]; |
---|
184 | varargin(i) = []; |
---|
185 | elseif any(strcmpi(varargin{i},{'FitRFHCM0','FitRFEnergy','SetRFHCM0','SetRFEnergy'})) |
---|
186 | Flags = [Flags varargin(i)]; |
---|
187 | varargin(i) = []; |
---|
188 | elseif any(strcmpi(varargin{i},{'FitRFDeltaHCM0','SetRFDeltaHCM0'})) |
---|
189 | Flags = [Flags varargin(i)]; |
---|
190 | varargin(i) = []; |
---|
191 | elseif any(strcmpi(varargin{i},{'FitRFDispersionOrbit','SetRFDispersionOrbit'})) |
---|
192 | Flags = [Flags varargin(i)]; |
---|
193 | varargin(i) = []; |
---|
194 | elseif any(strcmpi(varargin{i},{'FitRFDispersionHCM','SetRFDispersionHCM'})) |
---|
195 | Flags = [Flags varargin(i)]; |
---|
196 | varargin(i) = []; |
---|
197 | |
---|
198 | end |
---|
199 | end |
---|
200 | |
---|
201 | |
---|
202 | if length(varargin) >= 1 |
---|
203 | if isstruct(varargin{1}) |
---|
204 | OCS = varargin{1}; |
---|
205 | varargin(1) = []; |
---|
206 | if length(varargin) < 2 |
---|
207 | error('An OCS plus at least 2 inputs are required'); |
---|
208 | end |
---|
209 | if length(varargin) >= 1 |
---|
210 | GoalOrbit = varargin{1}; |
---|
211 | varargin(1) = []; |
---|
212 | end |
---|
213 | if length(varargin) >= 1 |
---|
214 | CMIncrementList = varargin{1}; |
---|
215 | varargin(1) = []; |
---|
216 | end |
---|
217 | else |
---|
218 | OCS.BPM.FamilyName = varargin{1}; |
---|
219 | varargin(1) = []; |
---|
220 | if length(varargin) >= 1 |
---|
221 | OCS.BPM.DeviceList = varargin{1}; |
---|
222 | varargin(1) = []; |
---|
223 | end |
---|
224 | if length(varargin) >= 1 |
---|
225 | GoalOrbit = varargin{1}; |
---|
226 | varargin(1) = []; |
---|
227 | end |
---|
228 | if length(varargin) >= 1 |
---|
229 | OCS.CM.FamilyName = varargin{1}; |
---|
230 | varargin(1) = []; |
---|
231 | end |
---|
232 | if length(varargin) >= 1 |
---|
233 | CMIncrementList = varargin{1}; |
---|
234 | varargin(1) = []; |
---|
235 | end |
---|
236 | end |
---|
237 | |
---|
238 | % Get NIter |
---|
239 | if length(varargin) >= 1 |
---|
240 | if isnumeric(varargin{1}) |
---|
241 | OCS.NIter = varargin{1}; |
---|
242 | varargin(1) = []; |
---|
243 | end |
---|
244 | end |
---|
245 | |
---|
246 | % Get SVDIndex (can be a fractional number, vector, or 'All') |
---|
247 | if length(varargin) >= 1 |
---|
248 | %if isnumeric(varargin{1}) |
---|
249 | OCS.SVDIndex = varargin{1}; |
---|
250 | varargin(1) = []; |
---|
251 | %end |
---|
252 | end |
---|
253 | |
---|
254 | % Get BPMWeight |
---|
255 | if length(varargin) >= 1 |
---|
256 | if isnumeric(varargin{1}) |
---|
257 | BPMWeight = varargin{1}; |
---|
258 | varargin(1) = []; |
---|
259 | end |
---|
260 | end |
---|
261 | end |
---|
262 | |
---|
263 | |
---|
264 | % Pass the extra inputs on |
---|
265 | if length(varargin) >= 1 |
---|
266 | Flags = [Flags varargin]; |
---|
267 | end |
---|
268 | |
---|
269 | |
---|
270 | % Fill the empty fields |
---|
271 | if isempty(OCS.BPM.FamilyName) |
---|
272 | i = menu('Select a plane','Horizontal','Vertical'); |
---|
273 | if i == 1 |
---|
274 | OCS.BPM.FamilyName = gethbpmfamily; |
---|
275 | OCS.CM.FamilyName = gethcmfamily; |
---|
276 | elseif i == 2 |
---|
277 | OCS.BPM.FamilyName = getvbpmfamily; |
---|
278 | OCS.CM.FamilyName = getvcmfamily; |
---|
279 | end |
---|
280 | end |
---|
281 | if isempty(OCS.BPM.DeviceList) |
---|
282 | OCS.BPM.DeviceList = editlist(family2dev(OCS.BPM.FamilyName), OCS.BPM.FamilyName, 0); |
---|
283 | % Getting a list can messes up the order for bumps going from the last sector to the first |
---|
284 | for i = 2:length(OCS.BPM.DeviceList) |
---|
285 | if getspos(OCS.BPM.FamilyName,OCS.BPM.DeviceList(i,:))-getspos(OCS.BPM.FamilyName,OCS.BPM.DeviceList(i-1,:)) > L/2 |
---|
286 | break; |
---|
287 | end |
---|
288 | end |
---|
289 | if i < length(OCS.BPM.DeviceList) |
---|
290 | OCS.BPM.DeviceList = [OCS.BPM.DeviceList(i:end,:); OCS.BPM.DeviceList(1:i-1,:)]; |
---|
291 | end |
---|
292 | end |
---|
293 | if isempty(OCS.CM.FamilyName) |
---|
294 | if strcmpi(OCS.BPM.FamilyName, gethbpmfamily) |
---|
295 | OCS.CM.FamilyName = gethcmfamily; |
---|
296 | else |
---|
297 | OCS.CM.FamilyName = getvcmfamily; |
---|
298 | end |
---|
299 | end |
---|
300 | |
---|
301 | if isempty(UnitsFlag) |
---|
302 | UnitsFlag = getunits(OCS.BPM.FamilyName); |
---|
303 | end |
---|
304 | |
---|
305 | if isempty(ModeFlag) |
---|
306 | ModeFlag = getmode(OCS.BPM.FamilyName); |
---|
307 | end |
---|
308 | |
---|
309 | if NoLeakageFlag && OCS.NIter==0 |
---|
310 | error('Leakage cleanup flag cannot be used with zero iterations.'); |
---|
311 | end |
---|
312 | %%%%%%%%%%%%%%%%%%%%%%%% |
---|
313 | % End of input parsing % |
---|
314 | %%%%%%%%%%%%%%%%%%%%%%%% |
---|
315 | |
---|
316 | |
---|
317 | % Possibly convert the GoalOrbit |
---|
318 | if any(isnan(GoalOrbit)) |
---|
319 | error('Goal orbit has a NaN'); |
---|
320 | end |
---|
321 | if isempty(GoalOrbit) |
---|
322 | % Input the goal orbit |
---|
323 | for i = 1:size(OCS.BPM.DeviceList,1) |
---|
324 | labels{i} = sprintf('Input the goal orbit at %s(%d,%d)',OCS.BPM.FamilyName, OCS.BPM.DeviceList(i,1), OCS.BPM.DeviceList(i,2)); |
---|
325 | StartingPoint{i} = '0'; |
---|
326 | end |
---|
327 | answer = inputdlg(labels,'Local Bump',1,StartingPoint); |
---|
328 | if isempty(answer) |
---|
329 | fprintf(' Local bump cancelled'); |
---|
330 | return |
---|
331 | end |
---|
332 | for i = 1:size(OCS.BPM.DeviceList,1) |
---|
333 | GoalOrbit(i,1) = str2num(answer{i}); |
---|
334 | end |
---|
335 | end |
---|
336 | if ischar(GoalOrbit) |
---|
337 | if strcmpi(GoalOrbit, 'Golden') |
---|
338 | GoalOrbit = getgolden(OCS.BPM.FamilyName, OCS.BPM.DeviceList); |
---|
339 | elseif strcmpi(GoalOrbit, 'Offset') |
---|
340 | GoalOrbit = getoffset(OCS.BPM.FamilyName, OCS.BPM.DeviceList); |
---|
341 | else |
---|
342 | error('Goal unknown'); |
---|
343 | end |
---|
344 | end |
---|
345 | GoalOrbit = GoalOrbit(:); |
---|
346 | |
---|
347 | % Check the length |
---|
348 | if length(GoalOrbit) ~= size(OCS.BPM.DeviceList,1) |
---|
349 | error('Length of the GoalOrbit must equal the number of devices in BPMList'); |
---|
350 | end |
---|
351 | |
---|
352 | |
---|
353 | % CMIncrementList must be a vector, no zeros, no repeats |
---|
354 | CheckCM = 0; |
---|
355 | if isempty(CMIncrementList) |
---|
356 | CheckCM = 1; |
---|
357 | Ncm = size(OCS.BPM.DeviceList,1)+2; |
---|
358 | if rem(Ncm,2) == 0 |
---|
359 | NcmDiv2 = Ncm / 2; |
---|
360 | CMIncrementList = [-(Ncm/2):-1 1:(Ncm/2)]; |
---|
361 | else |
---|
362 | NcmDiv2 = Ncm / 2; |
---|
363 | CMIncrementList = [-floor(Ncm/2):-1 1:(floor(Ncm/2)+1)]; |
---|
364 | end |
---|
365 | end |
---|
366 | |
---|
367 | % Check for a device list input |
---|
368 | if ~(size(CMIncrementList,2) == 2 && size(CMIncrementList,1) > 1) |
---|
369 | CMIncrementList = CMIncrementList(:); |
---|
370 | CMIncrementList = sort(CMIncrementList); |
---|
371 | CMIncrementList(find(CMIncrementList==0)) = []; |
---|
372 | CMIncrementList(find(diff(CMIncrementList)==0)) = []; |
---|
373 | end |
---|
374 | |
---|
375 | % Get BPM positions |
---|
376 | BPMListTotal = family2dev(OCS.BPM.FamilyName, 1); |
---|
377 | BPMsposTotal = getspos(OCS.BPM.FamilyName, BPMListTotal); |
---|
378 | BPMspos = getspos(OCS.BPM.FamilyName, OCS.BPM.DeviceList); |
---|
379 | |
---|
380 | |
---|
381 | % Stack 3 rings so you you don't have to worry about the L to 0 transition |
---|
382 | CMListTotal = family2dev(OCS.CM.FamilyName, 1); |
---|
383 | CMsposTotal = getspos(OCS.CM.FamilyName, CMListTotal); |
---|
384 | CMListTotal = [CMListTotal; CMListTotal; CMListTotal]; |
---|
385 | CMsposTotal = [CMsposTotal-L; CMsposTotal; CMsposTotal+L]; |
---|
386 | |
---|
387 | |
---|
388 | % Find the correctors |
---|
389 | % Check for a device list input |
---|
390 | if size(CMIncrementList,2) == 2 && size(CMIncrementList,1) > 1 |
---|
391 | % DeviceList |
---|
392 | OCS.CM.DeviceList = CMIncrementList; |
---|
393 | else |
---|
394 | for i = 1:length(CMIncrementList) |
---|
395 | if CMIncrementList(i) <= 0 |
---|
396 | j = find(CMsposTotal <= BPMspos(1)); |
---|
397 | OCS.CM.DeviceList(i,:) = CMListTotal(j(end)+CMIncrementList(i)+1,:); |
---|
398 | else |
---|
399 | j = find(CMsposTotal >= BPMspos(end)); |
---|
400 | OCS.CM.DeviceList(i,:) = CMListTotal(j(1)+CMIncrementList(i)-1,:); |
---|
401 | end |
---|
402 | end |
---|
403 | end |
---|
404 | |
---|
405 | if CheckCM |
---|
406 | DevTotal = family2dev(OCS.CM.FamilyName); |
---|
407 | checkvec = zeros(size(DevTotal,1),1); |
---|
408 | checkvec(findrowindex(OCS.CM.DeviceList, DevTotal)) = 1; |
---|
409 | OCS.CM.DeviceList = editlist(DevTotal, OCS.CM.FamilyName, checkvec); |
---|
410 | |
---|
411 | % Getting a list can messes up the order for bumps going from the last sector to the first |
---|
412 | for i = 2:length(OCS.CM.DeviceList) |
---|
413 | if getspos(OCS.CM.FamilyName,OCS.CM.DeviceList(i,:)) - getspos(OCS.CM.FamilyName,OCS.CM.DeviceList(i-1,:)) > L/2 |
---|
414 | break; |
---|
415 | end |
---|
416 | end |
---|
417 | if i < length(OCS.CM.DeviceList) |
---|
418 | OCS.CM.DeviceList = [OCS.CM.DeviceList(i:end,:); OCS.CM.DeviceList(1:i-1,:)]; |
---|
419 | end |
---|
420 | end |
---|
421 | |
---|
422 | |
---|
423 | % Find all BPMs outside the bump (leakage control BPMs) |
---|
424 | CMspos = getspos(OCS.CM.FamilyName, OCS.CM.DeviceList); |
---|
425 | if CMspos(1) > CMspos(end) |
---|
426 | j1 = intersect(find(BPMsposTotal < CMspos(1)), find(BPMsposTotal > CMspos(end))); |
---|
427 | j2 = []; |
---|
428 | else |
---|
429 | j1 = find(BPMsposTotal < CMspos(1)); |
---|
430 | j2 = find(BPMsposTotal > CMspos(end)); |
---|
431 | end |
---|
432 | if isempty(j1) && isempty(j2) |
---|
433 | error('Cound not find any leakage control BPMs'); |
---|
434 | end |
---|
435 | OCS.BPM.DeviceList = [BPMListTotal(j1,:); OCS.BPM.DeviceList; BPMListTotal(j2,:);]; |
---|
436 | BPMDeviceListLeakage = [BPMListTotal(j1,:); BPMListTotal(j2,:);]; |
---|
437 | |
---|
438 | |
---|
439 | if OCS.Incremental |
---|
440 | % Incremental |
---|
441 | OCS.GoalOrbit = [zeros(length(j1),1); GoalOrbit; zeros(length(j2),1)]; |
---|
442 | |
---|
443 | if OCS.NIter == 0 |
---|
444 | LeakageGoalOrbit = zeros(size(BPMDeviceListLeakage,1),1); |
---|
445 | else |
---|
446 | if isempty(j1) |
---|
447 | LeakageOrbit1 = []; |
---|
448 | else |
---|
449 | LeakageOrbit1 = getam(OCS.BPM.FamilyName,BPMListTotal(j1,:), UnitsFlag, ModeFlag); |
---|
450 | end |
---|
451 | if isempty(j2) |
---|
452 | LeakageOrbit2 = []; |
---|
453 | else |
---|
454 | LeakageOrbit2 = getam(OCS.BPM.FamilyName,BPMListTotal(j2,:), UnitsFlag, ModeFlag); |
---|
455 | end |
---|
456 | LeakageGoalOrbit = [LeakageOrbit1; LeakageOrbit2]; |
---|
457 | end |
---|
458 | elseif ~OCS.Incremental |
---|
459 | % Absolute |
---|
460 | if isempty(j1) |
---|
461 | LeakageOrbit1 = []; |
---|
462 | else |
---|
463 | LeakageOrbit1 = getam(OCS.BPM.FamilyName,BPMListTotal(j1,:), UnitsFlag, ModeFlag); |
---|
464 | end |
---|
465 | if isempty(j2) |
---|
466 | LeakageOrbit2 = []; |
---|
467 | else |
---|
468 | LeakageOrbit2 = getam(OCS.BPM.FamilyName,BPMListTotal(j2,:), UnitsFlag, ModeFlag); |
---|
469 | end |
---|
470 | OCS.GoalOrbit = [LeakageOrbit1; GoalOrbit; LeakageOrbit2]; |
---|
471 | LeakageGoalOrbit = [LeakageOrbit1; LeakageOrbit2]; |
---|
472 | else |
---|
473 | error('Absolute or incremental input unknown.'); |
---|
474 | end |
---|
475 | |
---|
476 | |
---|
477 | % Add a weight |
---|
478 | if isempty(BPMWeight) |
---|
479 | % Default BPMWeight is to weight the leakage twice as much as the bump goal |
---|
480 | BPMWeight = .5 * (length(j1) + length(j2)) / length(GoalOrbit); |
---|
481 | OCS.BPMWeight = [ones(length(j1),1); BPMWeight .* ones(length(GoalOrbit),1); ones(length(j2),1)]; |
---|
482 | else |
---|
483 | OCS.BPMWeight = [ones(length(j1),1); BPMWeight .* ones(length(GoalOrbit),1); ones(length(j2),1)]; |
---|
484 | end |
---|
485 | |
---|
486 | |
---|
487 | % Just to fill the data structure fields |
---|
488 | OCS.BPM = family2datastruct(OCS.BPM.FamilyName, 'Monitor', OCS.BPM.DeviceList, UnitsFlag, ModeFlag); |
---|
489 | OCS.CM = family2datastruct(OCS.CM.FamilyName, 'Setpoint', OCS.CM.DeviceList, UnitsFlag, ModeFlag); |
---|
490 | |
---|
491 | |
---|
492 | % Bumps stats |
---|
493 | if DisplayFlag |
---|
494 | % Corrector strength (meters/radian) and (mm/amp) |
---|
495 | % Warn on when to add RF frequency (generated dispersion is greater |
---|
496 | % than mm per amp or % of mm/amp bump) |
---|
497 | end |
---|
498 | |
---|
499 | |
---|
500 | % Set the bump |
---|
501 | [OCS, OCS0, V, S, ErrorFlag] = setorbit(OCS, UnitsFlag, ModeFlag, Flags{:}); |
---|
502 | |
---|
503 | |
---|
504 | % Clean up the leakage |
---|
505 | if NoLeakageFlag |
---|
506 | if DisplayFlag |
---|
507 | fprintf(' Correcting the leakage\n'); |
---|
508 | end |
---|
509 | OCS1 = OCS; |
---|
510 | OCS1.GoalOrbit = LeakageGoalOrbit; |
---|
511 | OCS1.BPM = family2datastruct(OCS.BPM.FamilyName, 'Monitor', BPMDeviceListLeakage); |
---|
512 | OCS1.BPMWeight = []; |
---|
513 | OCS1.Incremental = 0; |
---|
514 | OCS1 = setorbit(OCS1, UnitsFlag, ModeFlag); |
---|
515 | end |
---|
516 | |
---|