1 | function OCS = makebump(varargin) |
---|
2 | %MAKEBUMP - Creates and orbit correction structure (OCS) usable by setorbit |
---|
3 | % OCS = makebump(BPMFamily, BPMDeviceList, GoalOrbit, CMFamily, CMIncrementList, BPMWeight {optional}) |
---|
4 | % OCS = makebump(OCS, GoalOrbit, CMIncrementList, BPMWeight {optional}) |
---|
5 | % |
---|
6 | % INPUTS |
---|
7 | % 1. BPMFamily |
---|
8 | % 2. BPMDeviceList |
---|
9 | % 3. GoalOrbit |
---|
10 | % 4. CMFamily |
---|
11 | % 5. CMIncrementList |
---|
12 | % 6. BPMWeight - Weight applied to the BPMs inside the bump (GoalOrbit). BPM weighting |
---|
13 | % should only be required when the corrector are in a region of dispersion |
---|
14 | % and the RF frequency is not used in the orbit correction. |
---|
15 | % {Default BPMWeight is to weight the leakage twice as much as the GoalOrbit} |
---|
16 | % 7. 'Display' - Display bump characteristics |
---|
17 | % 8. Optional flags used in setorbit can also be used: |
---|
18 | % 'FitRF' flag to include the RF frequency as part of orbit correction. |
---|
19 | % |
---|
20 | % NOTES |
---|
21 | % 1. makebump creates an OCS structure. Use setorbit to actually change the orbit. |
---|
22 | % |
---|
23 | % See also setbump, setbumpgui, setorbit |
---|
24 | % |
---|
25 | % Written by Greg Portmann |
---|
26 | |
---|
27 | |
---|
28 | %%%%%%%%%%%% |
---|
29 | % Defaults % |
---|
30 | %%%%%%%%%%%% |
---|
31 | nIter = 3; |
---|
32 | BPMWeight = []; |
---|
33 | GoalOrbit = []; |
---|
34 | IncrementalFlag = 1; |
---|
35 | DisplayFlag = 0; |
---|
36 | |
---|
37 | |
---|
38 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
39 | % Input parsing and checking % |
---|
40 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
41 | OCS.Flags = {}; |
---|
42 | for i = length(varargin):-1:1 |
---|
43 | if isstruct(varargin{i}) |
---|
44 | % Ignor structures |
---|
45 | elseif iscell(varargin{i}) |
---|
46 | % Ignor cells |
---|
47 | elseif strcmpi(varargin{i},'Golden') |
---|
48 | % Use the golden orbit |
---|
49 | GoalOrbit = 'Golden'; |
---|
50 | varargin(i) = []; |
---|
51 | elseif strcmpi(varargin{i},'Offset') |
---|
52 | % Use the offset orbit |
---|
53 | GoalOrbit = 'Golden'; |
---|
54 | varargin(i) = []; |
---|
55 | elseif strcmpi(varargin{i},'Display') |
---|
56 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
57 | DisplayFlag = 1; |
---|
58 | varargin(i) = []; |
---|
59 | elseif strcmpi(varargin{i},'ModelResp') |
---|
60 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
61 | varargin(i) = []; |
---|
62 | elseif strcmpi(varargin{i},'FitRF') |
---|
63 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
64 | varargin(i) = []; |
---|
65 | elseif strcmpi(varargin{i},'ModelDisp') |
---|
66 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
67 | varargin(i) = []; |
---|
68 | elseif strcmpi(varargin{i},'MeasDisp') |
---|
69 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
70 | varargin(i) = []; |
---|
71 | elseif strcmpi(varargin{i},'GoldenDisp') |
---|
72 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
73 | varargin(i) = []; |
---|
74 | elseif strcmpi(varargin{i},'Inc') || strcmpi(varargin{i},'Incremental') |
---|
75 | IncrementalFlag = 1; |
---|
76 | varargin(i) = []; |
---|
77 | elseif strcmpi(varargin{i},'Abs') || strcmpi(varargin{i},'Absolute') |
---|
78 | IncrementalFlag = 0; |
---|
79 | varargin(i) = []; |
---|
80 | elseif strcmpi(varargin{i},'simulator') || strcmpi(varargin{i},'model') |
---|
81 | ModeFlag = 'SIMULATOR'; |
---|
82 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
83 | varargin(i) = []; |
---|
84 | elseif strcmpi(varargin{i},'Online') |
---|
85 | ModeFlag = 'Online'; |
---|
86 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
87 | varargin(i) = []; |
---|
88 | elseif strcmpi(varargin{i},'Manual') |
---|
89 | ModeFlag = 'Manual'; |
---|
90 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
91 | varargin(i) = []; |
---|
92 | elseif strcmpi(varargin{i},'physics') |
---|
93 | UnitsFlag = 'Physics'; |
---|
94 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
95 | varargin(i) = []; |
---|
96 | elseif strcmpi(varargin{i},'hardware') |
---|
97 | UnitsFlag = 'Hardware'; |
---|
98 | OCS.Flags = [OCS.Flags varargin(i)]; |
---|
99 | varargin(i) = []; |
---|
100 | elseif strcmpi(varargin{i},'archive') |
---|
101 | % Just remove |
---|
102 | varargin(i) = []; |
---|
103 | elseif strcmpi(varargin{i},'noarchive') |
---|
104 | % Just remove |
---|
105 | varargin(i) = []; |
---|
106 | elseif strcmpi(varargin{i},'struct') |
---|
107 | % Just remove |
---|
108 | varargin(i) = []; |
---|
109 | elseif strcmpi(varargin{i},'numeric') |
---|
110 | % Just remove |
---|
111 | varargin(i) = []; |
---|
112 | end |
---|
113 | end |
---|
114 | i=length(OCS.Flags); |
---|
115 | if IncrementalFlag |
---|
116 | OCS.Flags{i+1} = 'Incremental'; |
---|
117 | else |
---|
118 | OCS.Flags{i+1} = 'Absolute'; |
---|
119 | end |
---|
120 | |
---|
121 | |
---|
122 | if isstruct(varargin{1}) |
---|
123 | OCS = varargin{1}; |
---|
124 | varargin(1) = []; |
---|
125 | if length(varargin) < 2 |
---|
126 | error('An OCS plus at least 2 inputs are required'); |
---|
127 | end |
---|
128 | GoalOrbit = varargin{1}; |
---|
129 | varargin(1) = []; |
---|
130 | CMIncrementList = varargin{1}; |
---|
131 | varargin(1) = []; |
---|
132 | else |
---|
133 | if length(varargin) < 5 |
---|
134 | error('At least 5 inputs or an orbit correction structure is required'); |
---|
135 | end |
---|
136 | OCS.BPM.FamilyName = varargin{1}; |
---|
137 | OCS.BPM.DeviceList = varargin{2}; |
---|
138 | GoalOrbit = varargin{3}; |
---|
139 | OCS.CM.FamilyName = varargin{4}; |
---|
140 | CMIncrementList = varargin{5}; |
---|
141 | varargin(1:5) = []; |
---|
142 | end |
---|
143 | |
---|
144 | if length(varargin) >= 1 |
---|
145 | if isnumeric(varargin{1}) |
---|
146 | BPMWeight = varargin{1}; |
---|
147 | varargin(1) = []; |
---|
148 | end |
---|
149 | end |
---|
150 | |
---|
151 | % Pass the extra inputs on |
---|
152 | if length(varargin) >= 1 |
---|
153 | OCS.Flags = [OCS.Flags varargin]; |
---|
154 | end |
---|
155 | |
---|
156 | |
---|
157 | % Possibly convert the GoalOrbit |
---|
158 | if ischar(GoalOrbit) |
---|
159 | if strcmpi(GoalOrbit, 'Golden') |
---|
160 | GoalOrbit = getgolden(OCS.BPM.FamilyName, OCS.BPM.DeviceList); |
---|
161 | elseif strcmpi(GoalOrbit, 'Offset') |
---|
162 | GoalOrbit = getoffset(OCS.BPM.FamilyName, OCS.BPM.DeviceList); |
---|
163 | else |
---|
164 | error('Goal unknown'); |
---|
165 | end |
---|
166 | end |
---|
167 | GoalOrbit = GoalOrbit(:); |
---|
168 | |
---|
169 | % Check the length |
---|
170 | if length(GoalOrbit) ~= size(OCS.BPM.DeviceList,1) |
---|
171 | error('Length of the GoalOrbit must equal the number of devices in BPMList'); |
---|
172 | end |
---|
173 | |
---|
174 | |
---|
175 | % CMIncrementList must be a vector, no zeros, no repeats |
---|
176 | CMIncrementList = CMIncrementList(:); |
---|
177 | CMIncrementList = sort(CMIncrementList); |
---|
178 | CMIncrementList(find(CMIncrementList==0)) = []; |
---|
179 | CMIncrementList(find(diff(CMIncrementList)==0)) = []; |
---|
180 | |
---|
181 | |
---|
182 | % Get BPM postions |
---|
183 | BPMListTotal = family2dev(OCS.BPM.FamilyName, 1); |
---|
184 | BPMsposTotal = getspos(OCS.BPM.FamilyName, BPMListTotal); |
---|
185 | BPMspos = getspos(OCS.BPM.FamilyName, OCS.BPM.DeviceList); |
---|
186 | |
---|
187 | |
---|
188 | % Stack 3 rings so you you don't have to worry about the L to 0 transition |
---|
189 | CMListTotal = family2dev(OCS.CM.FamilyName, 1); |
---|
190 | CMsposTotal = getspos(OCS.CM.FamilyName, CMListTotal); |
---|
191 | L = getfamilydata('Circumference'); |
---|
192 | CMListTotal = [CMListTotal; CMListTotal; CMListTotal]; |
---|
193 | CMsposTotal = [CMsposTotal-L; CMsposTotal; CMsposTotal+L]; |
---|
194 | |
---|
195 | |
---|
196 | % Find the correctors |
---|
197 | for i = 1:length(CMIncrementList) |
---|
198 | if CMIncrementList(i) <= 0 |
---|
199 | j = find(CMsposTotal <= BPMspos(1)); |
---|
200 | OCS.CM.DeviceList(i,:) = CMListTotal(j(end)+CMIncrementList(i)+1,:); |
---|
201 | else |
---|
202 | j = find(CMsposTotal >= BPMspos(end)); |
---|
203 | OCS.CM.DeviceList(i,:) = CMListTotal(j(1)+CMIncrementList(i)-1,:); |
---|
204 | end |
---|
205 | end |
---|
206 | |
---|
207 | |
---|
208 | % Find all BPMs outside the bump (leakage control BPMs) |
---|
209 | CMspos = getspos(OCS.CM.FamilyName, OCS.CM.DeviceList); |
---|
210 | j1 = find(BPMsposTotal < CMspos(1)); |
---|
211 | j2 = find(BPMsposTotal > CMspos(end)); |
---|
212 | if isempty(j1) && isempty(j2) |
---|
213 | error('Cound not find any leakage control BPMs'); |
---|
214 | end |
---|
215 | OCS.BPM.DeviceList = [BPMListTotal(j1,:); OCS.BPM.DeviceList; BPMListTotal(j2,:);]; |
---|
216 | |
---|
217 | if IncrementalFlag |
---|
218 | OCS.GoalOrbit = [zeros(length(j1),1); GoalOrbit; zeros(length(j2),1)]; |
---|
219 | else |
---|
220 | OCS.GoalOrbit = [getam(OCS.BPM.FamilyName,BPMListTotal(j1,:)); GoalOrbit; getam(OCS.BPM.FamilyName,BPMListTotal(j2,:))]; |
---|
221 | end |
---|
222 | |
---|
223 | |
---|
224 | % Add a weight |
---|
225 | if isempty(BPMWeight) |
---|
226 | % Default BPMWeight is to weight the leakage twice as much as the bump goal |
---|
227 | BPMWeight = .5 * (length(j1) + length(j2)) / length(GoalOrbit); |
---|
228 | OCS.BPMWeight = [ones(length(j1),1); BPMWeight .* ones(length(GoalOrbit),1); ones(length(j2),1)]; |
---|
229 | else |
---|
230 | OCS.BPMWeight = [ones(length(j1),1); BPMWeight .* ones(length(GoalOrbit),1); ones(length(j2),1)]; |
---|
231 | end |
---|
232 | |
---|
233 | |
---|
234 | % Create data structure |
---|
235 | OCS.BPM = family2datastruct(OCS.BPM.FamilyName, OCS.BPM.DeviceList); |
---|
236 | OCS.CM = family2datastruct(OCS.CM.FamilyName, OCS.CM.DeviceList); |
---|
237 | |
---|
238 | |
---|
239 | % Bumps stats |
---|
240 | if DisplayFlag |
---|
241 | % Corrector strength (meters/radian) and (mm/amp) |
---|
242 | % Warn on when to add RF frequency (generated dispersion is greater than mm per amp or % of mm/amp bump) |
---|
243 | end |
---|