1 | function [DxOut, DyOut, FileName] = plotdisp(varargin) |
---|
2 | %PLOTDISP - Plots the dispersion function |
---|
3 | % |
---|
4 | % For structure inputs: |
---|
5 | % [Dx, Dy] = plotdisp(Dx, Dy) Plots in the units stored in the structure |
---|
6 | % [Dx, Dy] = plotdisp(FileName) Plots in the units stored in a file ('' to browse) |
---|
7 | % [Dx, Dy] = plotdisp(Dx, Dy,'Hardware') Plots in hardware units (converts if necessary) |
---|
8 | % [Dx, Dy] = plotdisp(Dx, Dy,'Physics') Plots in physics units (converts if necessary) |
---|
9 | % |
---|
10 | % When not using structure inputs, assumptions have to be made about the units |
---|
11 | % This function assumes that hardware units are mm/MHz and physics units are meters/Hz |
---|
12 | % [Dx,Dy] = plotdisp(Dx, Dy) Assumes that the units of Dx,Dy are mm/MHz |
---|
13 | % [Dx,Dy] = plotdisp(Dx, Dy, 'Physics') Assumes that the units of Dx,Dy are m/(dp/p) (no conversion) |
---|
14 | % ie, was measured using [Dx, Dy] = measdisp('Physics') |
---|
15 | % [Dx,Dy] = plotdisp(Dx, Dy, 'Physics',mcf,rf) Converts Dx,Dy from mm/MHz to m/(dp/p) |
---|
16 | % ie, was measured using [Dx, Dy] = measdisp('Hardware') |
---|
17 | % |
---|
18 | % INPUTS |
---|
19 | % 1. d (dispersion structure) or Dx and Dy (vectors) as measure by measdisp |
---|
20 | % 2. 'Physics' is a flag to plot dispersion function in physics units |
---|
21 | % 'Hardware' is a flag to plot dispersion function in hardware units |
---|
22 | % ('Eta' can be used instead of 'Physics') |
---|
23 | % 3. mcf = momentum compaction factor (linear) |
---|
24 | % 4. rf = rf frequency (MHz) |
---|
25 | % rf and mcf input are only for nonstructure inputs when using the 'Physics' flag |
---|
26 | % |
---|
27 | % |
---|
28 | % OPTIONAL |
---|
29 | % 1. 'BPMCOUPLING' - Correct for BPM gains and coupling (from LOCO) only if 'Online measurementà |
---|
30 | % |
---|
31 | % OUTPUT |
---|
32 | % 1. [Dx, Dy] is the dispersion function which may be different from the input |
---|
33 | % if units were changed. |
---|
34 | % |
---|
35 | % NOTE |
---|
36 | % 1. 'Hardware' and 'Physics' are not case sensitive |
---|
37 | % |
---|
38 | % See also measdisp, getdisp |
---|
39 | |
---|
40 | % |
---|
41 | % Written by William J. Corbett and Gregory J. Portmann |
---|
42 | % Modified by Laurent S. Nadolski |
---|
43 | % More generic, Eta option was not working |
---|
44 | % March 2009, Add option for BPM coupling ang gain |
---|
45 | |
---|
46 | CouplingFlag = 1; |
---|
47 | MCF = []; |
---|
48 | RF0 = []; |
---|
49 | FileName = -1; |
---|
50 | Dx = []; |
---|
51 | Dy = []; |
---|
52 | ModeString = ''; |
---|
53 | |
---|
54 | BPMxFamily = gethbpmfamily; |
---|
55 | BPMyFamily = getvbpmfamily; |
---|
56 | |
---|
57 | % Input parsing |
---|
58 | UnitsFlag = {'Physics'}; |
---|
59 | for i = length(varargin):-1:1 |
---|
60 | if isstruct(varargin{i}) |
---|
61 | % Ignore structures |
---|
62 | elseif iscell(varargin{i}) |
---|
63 | % Ignore cells |
---|
64 | elseif strcmpi(varargin{i},'Eta') || strcmpi(varargin{i},'Physics') |
---|
65 | UnitsFlag = {'Physics'}; |
---|
66 | varargin(i) = []; |
---|
67 | if length(varargin) >= i % Not sure if I'm using these inputs at the moment |
---|
68 | if isnumeric(varargin{i}) |
---|
69 | MCF = varargin{i}; |
---|
70 | if length(varargin) >= i+1 |
---|
71 | if isnumeric(varargin{i+1}) |
---|
72 | RF0 = varargin{i+1}; |
---|
73 | varargin(i+1) = []; |
---|
74 | end |
---|
75 | end |
---|
76 | varargin(i) = []; |
---|
77 | end |
---|
78 | end |
---|
79 | elseif strcmpi(varargin{i},'Hardware') |
---|
80 | UnitsFlag = varargin(i); |
---|
81 | varargin(i) = []; |
---|
82 | elseif strcmpi(varargin{i},'BPMCoupling') |
---|
83 | CouplingFlag = 1; |
---|
84 | varargin(i) = []; |
---|
85 | elseif strcmpi(varargin{i},'NoBPMCoupling') |
---|
86 | CouplingFlag = 0; |
---|
87 | varargin(i) = []; |
---|
88 | end |
---|
89 | end |
---|
90 | |
---|
91 | % Check if the input is a structure |
---|
92 | if isempty(varargin) |
---|
93 | elseif ischar(varargin{1}) |
---|
94 | FileName = varargin{1}; |
---|
95 | elseif length(varargin) < 2 |
---|
96 | error('Dx and Dy dispersion or a filename input are required.'); |
---|
97 | else |
---|
98 | if (isstruct(varargin{1}) || isnumeric(varargin{1})) && (isstruct(varargin{2}) || isnumeric(varargin{2})) |
---|
99 | Dx = varargin{1}; |
---|
100 | Dy = varargin{2}; |
---|
101 | else |
---|
102 | error('Dx and Dy dispersion or a filename input are required.'); |
---|
103 | end |
---|
104 | end |
---|
105 | |
---|
106 | if isempty(Dx) |
---|
107 | if ischar(FileName) |
---|
108 | [Dx, FileName] = getdisp(BPMxFamily, 'Struct', FileName, UnitsFlag{:}); |
---|
109 | else |
---|
110 | [Dx, FileName] = getdisp(BPMxFamily, 'Struct', UnitsFlag{:}); |
---|
111 | end |
---|
112 | if isempty(FileName) || ~ischar(FileName) |
---|
113 | return; |
---|
114 | else |
---|
115 | Dy = getdisp(BPMyFamily, FileName, 'Struct', UnitsFlag{:}); |
---|
116 | end |
---|
117 | end |
---|
118 | |
---|
119 | if isstruct(Dx) |
---|
120 | if isempty(UnitsFlag) |
---|
121 | UnitsFlag = Dx.Units; |
---|
122 | end |
---|
123 | ModeString = Dx.Monitor.Mode; |
---|
124 | |
---|
125 | MCF = Dx.MCF; |
---|
126 | if strcmpi(UnitsFlag,'Physics') && strcmpi(Dx.Units,'Hardware') |
---|
127 | % Change to physics units |
---|
128 | Dx = hw2physics(Dx); |
---|
129 | end |
---|
130 | if strcmpi(UnitsFlag,'Physics') && strcmpi(Dy.Units,'Hardware') |
---|
131 | % Change to physics units |
---|
132 | Dy = hw2physics(Dy); |
---|
133 | end |
---|
134 | % Change to denominator to energy shift (dp/p) |
---|
135 | %RF0 = Dx.Actuator.Data; |
---|
136 | %RF0 = RF0(1); % Just in case someone has a vector for multiple cavities |
---|
137 | %Dx.Data = -RF0 * MCF * Dx.Data; |
---|
138 | %Dy.Data = -RF0 * MCF * Dy.Data; |
---|
139 | % |
---|
140 | %Dx.UnitsString = [Dx.Monitor.UnitsString,'/(dp/p)']; |
---|
141 | %Dy.UnitsString = [Dy.Monitor.UnitsString,'/(dp/p)']; |
---|
142 | |
---|
143 | if strcmpi(UnitsFlag,'Hardware') && strcmpi(Dx.Units,'Physics') |
---|
144 | % Change to hardware units |
---|
145 | Dx = physics2hw(Dx); |
---|
146 | end |
---|
147 | if strcmpi(UnitsFlag,'Hardware') && strcmpi(Dy.Units,'Physics') |
---|
148 | % Change to hardware units |
---|
149 | Dy = physics2hw(Dy); |
---|
150 | end |
---|
151 | % Change to denominator to RF change |
---|
152 | %RF0 = Dx.Actuator.Data; |
---|
153 | %RF0 = RF0(1); % Just in case someone has a vector for multiple cavities |
---|
154 | %Dx.Data = Dx.Data / (-RF0 * MCF); |
---|
155 | %Dy.Data = Dy.Data / (-RF0 * MCF); |
---|
156 | % Change to hardware units |
---|
157 | %Dx = physics2hw(Dx); |
---|
158 | %Dy = physics2hw(Dy); |
---|
159 | %Dx.UnitsString = [Dx.Monitor.UnitsString,'/',Dx.Actuator.UnitsString]; |
---|
160 | %Dy.UnitsString = [Dy.Monitor.UnitsString,'/',Dy.Actuator.UnitsString]; |
---|
161 | |
---|
162 | DeltaRF = Dx.ActuatorDelta; |
---|
163 | TimeStamp = Dx.TimeStamp; |
---|
164 | |
---|
165 | if isempty(strfind(Dx.UnitsString,'dp')) |
---|
166 | TitleString = sprintf('"Dispersion" Function: %s (\\Deltaf=%g %s)', texlabel('{Delta}Orbit / {Delta}f'), DeltaRF, Dx.Actuator.UnitsString); |
---|
167 | else |
---|
168 | TitleString = sprintf('Dispersion Function: %s (\\alpha=%.5f, f=%f %s, \\Deltaf=%g %s)', texlabel('-alpha f {Delta}Orbit / {Delta}f'), MCF, Dx.Actuator.Data, Dx.Actuator.UnitsString, DeltaRF, Dx.Actuator.UnitsString); |
---|
169 | end |
---|
170 | |
---|
171 | |
---|
172 | % Plot dispersion |
---|
173 | if isfamily(Dx.Monitor.FamilyName) |
---|
174 | sx = getspos(Dx.Monitor.FamilyName,Dx.Monitor.DeviceList); |
---|
175 | X1LabelString = sprintf('%s Position [m]', Dx.Monitor.FamilyName); |
---|
176 | elseif strcmpi(Dx.Monitor.FamilyName, 'all'); |
---|
177 | global THERING |
---|
178 | sx = findspos(THERING, 1:length(THERING)+1); |
---|
179 | X1LabelString = 'Position [m]'; |
---|
180 | else |
---|
181 | sx = 1:length(Dx.Data); |
---|
182 | X1LabelString = 'BPM Number'; |
---|
183 | |
---|
184 | global THERING |
---|
185 | if ~isempty(THERING) |
---|
186 | Index = findcells(THERING, 'FamName', Dx.Monitor.FamilyName); |
---|
187 | if ~isempty(Index) |
---|
188 | sx = findspos(THERING, Index); |
---|
189 | X1LabelString = sprintf('%s Position [m]', Dx.Monitor.FamilyName); |
---|
190 | end |
---|
191 | end |
---|
192 | end |
---|
193 | |
---|
194 | if isfamily(Dy.Monitor.FamilyName) |
---|
195 | sy = getspos(Dy.Monitor.FamilyName, Dy.Monitor.DeviceList); |
---|
196 | X2LabelString = sprintf('%s Position [m]', Dy.Monitor.FamilyName); |
---|
197 | elseif strcmpi(Dy.Monitor.FamilyName, 'all'); |
---|
198 | global THERING |
---|
199 | sy = findspos(THERING, 1:length(THERING)+1); |
---|
200 | X2LabelString = 'Position [m]'; |
---|
201 | else |
---|
202 | sy = 1:length(Dy.Data); |
---|
203 | X2LabelString = 'BPM Number'; |
---|
204 | |
---|
205 | global THERING |
---|
206 | if ~isempty(THERING) |
---|
207 | Index = findcells(THERING, 'FamName', Dy.Monitor.FamilyName); |
---|
208 | if ~isempty(Index) |
---|
209 | sy = findspos(THERING, Index); |
---|
210 | X2LabelString = sprintf('%s Position [m]', Dy.Monitor.FamilyName); |
---|
211 | end |
---|
212 | end |
---|
213 | end |
---|
214 | |
---|
215 | Y1LabelString = sprintf('Horizontal [%s]', Dx.UnitsString); |
---|
216 | Y2LabelString = sprintf('Vertical [%s]', Dx.UnitsString); |
---|
217 | |
---|
218 | DxOut = Dx; |
---|
219 | DyOut = Dy; |
---|
220 | |
---|
221 | Dx = Dx.Data; |
---|
222 | Dy = Dy.Data; |
---|
223 | else |
---|
224 | % Non structure inputs |
---|
225 | if nargin == 2 || nargin == 3 || nargin == 5 |
---|
226 | % OK |
---|
227 | else |
---|
228 | error('2, 3, or 5 inputs required'); |
---|
229 | end |
---|
230 | |
---|
231 | if strcmpi(UnitsFlag,'Physics') |
---|
232 | Y1LabelString = sprintf('Horizontal [m/(dp/p)]'); |
---|
233 | Y2LabelString = sprintf('Vertical [m/(dp/p)]'); |
---|
234 | |
---|
235 | % Convert to physics units (if RF0 and MCF were not input, then assume that the units were already in mm/(dp/p)) |
---|
236 | if ~isempty(RF0) && ~isempty(MCF) |
---|
237 | TitleString = sprintf('Dispersion Function: %s (\\alpha=%3.2e, f=%f)', texlabel('-alpha f {Delta}Orbit / {Delta}f'), MCF, RF0); |
---|
238 | % Change units to meters/(dp/p) |
---|
239 | Dx = -RF0(1) * MCF * Dx / 1000; |
---|
240 | Dy = -RF0(1) * MCF * Dy / 1000; |
---|
241 | else |
---|
242 | TitleString = sprintf('Dispersion Function: %s', texlabel('-alpha f {Delta}Orbit / {Delta}f')); |
---|
243 | end |
---|
244 | else |
---|
245 | TitleString = sprintf('"Dispersion" Function: %s', texlabel('{Delta}Orbit / {Delta}f')); |
---|
246 | Y1LabelString = sprintf('Horizontal [mm/MHz]'); |
---|
247 | Y2LabelString = sprintf('Vertical [mm/MHz]'); |
---|
248 | end |
---|
249 | |
---|
250 | % Plot dispersion in terms of mm/MHz |
---|
251 | sx = 1:length(Dx); |
---|
252 | sy = 1:length(Dy); |
---|
253 | X1LabelString = 'BPM Number'; |
---|
254 | X2LabelString = 'BPM Number'; |
---|
255 | |
---|
256 | DxOut = Dx; |
---|
257 | DyOut = Dy; |
---|
258 | end |
---|
259 | |
---|
260 | |
---|
261 | % Plot |
---|
262 | clf reset |
---|
263 | %set(gcf,'NumberTitle','off','Name','Dispersion '); |
---|
264 | %set(gcf,'Name','Dispersion '); |
---|
265 | |
---|
266 | if CouplingFlag && strcmpi(DxOut.Mode, 'Online') |
---|
267 | % get BPM gains and coupling for LOCO file nominal |
---|
268 | Data = family2coupling(DxOut.Monitor.DeviceList); |
---|
269 | for ik =1:size(DxOut.Monitor.DeviceList,1), |
---|
270 | eta = deal(Data.Cinv{ik}(:,:)*[Dx(ik); Dy(ik)]); |
---|
271 | Dx(ik) = eta(1); Dy(ik) = eta(2); |
---|
272 | end |
---|
273 | DxOut = Dx; |
---|
274 | DyOut = Dy; |
---|
275 | end |
---|
276 | |
---|
277 | subplot(2,1,1); |
---|
278 | if length(Dx) > 125 |
---|
279 | plot(sx, Dx, 'b'); |
---|
280 | else |
---|
281 | plot(sx, Dx, '.-b'); |
---|
282 | end |
---|
283 | xlabel(X1LabelString); |
---|
284 | ylabel(Y1LabelString); |
---|
285 | title(TitleString); |
---|
286 | grid on |
---|
287 | |
---|
288 | subplot(2,1,2); |
---|
289 | if length(Dy) > 125 |
---|
290 | plot(sy, Dy, 'b'); |
---|
291 | else |
---|
292 | plot(sy, Dy, '.-b'); |
---|
293 | end |
---|
294 | xlabel(X2LabelString); |
---|
295 | ylabel(Y2LabelString); |
---|
296 | grid on |
---|
297 | orient tall |
---|
298 | |
---|
299 | if exist('TimeStamp','var') |
---|
300 | %addlabel(1,0,sprintf('%s', datestr(TimeStamp,0))); |
---|
301 | if any(strcmpi(ModeString, {'Model','Simulator'})) |
---|
302 | addlabel(1,0,sprintf('%s (Model)', datestr(TimeStamp,0))); |
---|
303 | else |
---|
304 | addlabel(1,0,sprintf('%s', datestr(TimeStamp,0))); |
---|
305 | end |
---|
306 | end |
---|
307 | |
---|
308 | if FileName == -1 |
---|
309 | FileName = []; |
---|
310 | end |
---|