1 | function [ConfigSetpointEnd, ConfigSetpointStart, ConfigSetpointPhysics] = setenergy(varargin) |
---|
2 | %SETENERGY - Sets the storage ring energy (GeV) by ramping all lattice magnets |
---|
3 | % [ConfigSetpointEnd, ConfigSetpointStart] = setenergy(Energy, NSteps, Delay) |
---|
4 | % |
---|
5 | % INPUTS |
---|
6 | % 1. Energy - Desired beam energy in GeV |
---|
7 | % Energy can be a vector to do a energy ramp (or use input #2) |
---|
8 | % 2. NSteps - Number of energy step when ramping between the |
---|
9 | % present energy and Energy. {Default: 1} |
---|
10 | % 3. Delay - Time delay between steps {Default: .1 seconds} |
---|
11 | % |
---|
12 | % OUTPUTS |
---|
13 | % 1. ConfigSetpointEnd - Ending lattice configuration |
---|
14 | % 2. ConfigSetpointStart - Starting lattice configuration |
---|
15 | % (same structure as returned by getmachineconfig) |
---|
16 | % |
---|
17 | % ALGORITHM |
---|
18 | % 1. Update the simulator with the present online setpoints (except the |
---|
19 | % BEND). The "K-values" in the simulator will then be based on the |
---|
20 | % hw2physics conversion which are based on magnet measurements |
---|
21 | % and the present energy as returned by getenergy (AD.Energy). The |
---|
22 | % BEND magnet is not updated in the simulator because the "K-value" |
---|
23 | % of the BEND never changes. |
---|
24 | % 2. Change the energy variable used by getenergy (AD.Energy) to |
---|
25 | % the new desired energy. |
---|
26 | % 3. Get the new lattice setpoints in hardware units from the simulator. |
---|
27 | % In doing so a physics2hw conversion will be done at the new energy. |
---|
28 | % 4. Set the new lattice setpoints to the online machine. |
---|
29 | % |
---|
30 | % NOTES AND ASSUMPTIONS |
---|
31 | % 1. hw2physics and physics2hw must adjust the output values based |
---|
32 | % on energy (ie, what is returned by getenergy (AD.Energy)). |
---|
33 | % 2. Before calling setenergy, the present lattice is assumed to be at |
---|
34 | % the value returned by getenergy (AD.Energy). If bend2gev does not match |
---|
35 | % AD.Energy |
---|
36 | % 3. All the lattice magnets, except the BEND, are relatively scaled based |
---|
37 | % on the energy changes. The BEND is an absolute setpoint w.r.t. energy. |
---|
38 | % That is, setting the machine to 3.1 GeV will always be the same BEND |
---|
39 | % magnet current. Where as setting the machine to 3.1 will change the |
---|
40 | % other (non-BEND) lattice magnets relative to the present energy. |
---|
41 | % 4. Setting the BEND magnet with setsp('BEND', NewGeV, 'Physics') will also |
---|
42 | % change the energy but the reset of the lattice does not get scaled "properly." |
---|
43 | % 5. The bend magnet family must be called 'BEND'. |
---|
44 | % |
---|
45 | % Also see getenergy, sweepenergy, bend2gev, gev2bend |
---|
46 | % |
---|
47 | % Written by Greg Portmann |
---|
48 | |
---|
49 | |
---|
50 | ModeFlag = ''; |
---|
51 | UnitsFlag = ''; |
---|
52 | for i = length(varargin):-1:1 |
---|
53 | if isstruct(varargin{i}) |
---|
54 | % Ignor structures |
---|
55 | elseif iscell(varargin{i}) |
---|
56 | % Ignor cells |
---|
57 | elseif strcmpi(varargin{i},'simulator') | strcmpi(varargin{i},'model') |
---|
58 | ModeFlag = 'Simulator'; |
---|
59 | varargin(i) = []; |
---|
60 | elseif strcmpi(varargin{i},'Online') |
---|
61 | ModeFlag = 'Online'; |
---|
62 | varargin(i) = []; |
---|
63 | elseif strcmpi(varargin{i},'physics') |
---|
64 | UnitsFlag = 'Physics'; |
---|
65 | varargin(i) = []; |
---|
66 | elseif strcmpi(varargin{i},'hardware') |
---|
67 | UnitsFlag = 'Hardware'; |
---|
68 | varargin(i) = []; |
---|
69 | end |
---|
70 | end |
---|
71 | |
---|
72 | if length(varargin) == 0 |
---|
73 | Energy = getenergy('Present'); % same as bend2gev |
---|
74 | %error('Energy input required'); |
---|
75 | end |
---|
76 | if length(varargin) >= 1 |
---|
77 | Energy = varargin{1}; |
---|
78 | end |
---|
79 | if length(varargin) >= 2 |
---|
80 | NSteps = varargin{2}; |
---|
81 | else |
---|
82 | NSteps = 1; |
---|
83 | end |
---|
84 | if length(varargin) >= 3 |
---|
85 | TimeDelay = varargin{3}; |
---|
86 | else |
---|
87 | TimeDelay = .1; |
---|
88 | end |
---|
89 | |
---|
90 | |
---|
91 | if isempty(ModeFlag) |
---|
92 | ModeFlag = getmode('BEND'); |
---|
93 | end |
---|
94 | |
---|
95 | |
---|
96 | % Get the starting lattice configuration |
---|
97 | ConfigSetpointStart = getmachineconfig(ModeFlag); |
---|
98 | |
---|
99 | |
---|
100 | % Remove some families |
---|
101 | if isfield(ConfigSetpointStart, 'RF') |
---|
102 | ConfigSetpointStart = rmfield(ConfigSetpointStart, 'RF'); |
---|
103 | end |
---|
104 | |
---|
105 | |
---|
106 | if strcmpi(getfamilydata('Machine'),'ALS') |
---|
107 | % Remove some more families |
---|
108 | % Skew quadrupoles? |
---|
109 | RemoveFamilyNames = {'HCMCHICANE','HCMCHICANEM','VCMCHICANE','SQEPU','RF','GeV'}; |
---|
110 | j = find(isfield(ConfigSetpointStart, RemoveFamilyNames)); |
---|
111 | ConfigSetpointStart = rmfield(ConfigSetpointStart, RemoveFamilyNames(j)); |
---|
112 | |
---|
113 | % Remove RampRate, etc fields |
---|
114 | RemoveFieldNames = {'RampRate','TimeConstant','DAC','Trim','FF1','FF2'}; |
---|
115 | Fields = fieldnames(ConfigSetpointStart); |
---|
116 | for i = 1:length(Fields) |
---|
117 | j = find(isfield(ConfigSetpointStart.(Fields{i}), RemoveFieldNames)); |
---|
118 | ConfigSetpointStart.(Fields{i}) = rmfield(ConfigSetpointStart.(Fields{i}), RemoveFieldNames(j)); |
---|
119 | end |
---|
120 | end |
---|
121 | ConfigFamilies = fieldnames(ConfigSetpointStart); |
---|
122 | |
---|
123 | |
---|
124 | % Present energy |
---|
125 | PresentEnergy = getenergy(ModeFlag); % same as bend2gev |
---|
126 | |
---|
127 | % Build the energy vector |
---|
128 | Energy = linspace(PresentEnergy, Energy(end), NSteps+1); |
---|
129 | Energy = Energy(:)'; |
---|
130 | |
---|
131 | |
---|
132 | % Get the setpoints in physics units |
---|
133 | for j = 1:length(ConfigFamilies) |
---|
134 | ConfigSetpointPhysics.(ConfigFamilies{j}).Setpoint = hw2physics(ConfigSetpointStart.(ConfigFamilies{j}).Setpoint, PresentEnergy); |
---|
135 | end |
---|
136 | |
---|
137 | |
---|
138 | if strcmpi(ModeFlag,'Simulator') | strcmpi(ModeFlag,'Model') |
---|
139 | |
---|
140 | setenergymodel(Energy(end)); |
---|
141 | |
---|
142 | % Get the setpoint change |
---|
143 | if nargout >= 1 |
---|
144 | %ConfigSetpointEnd = getmachineconfig('Simulator'); |
---|
145 | for j = 1:length(ConfigFamilies) |
---|
146 | ConfigSetpointEnd.(ConfigFamilies{j}).Setpoint = physics2hw(ConfigSetpointPhysics.(ConfigFamilies{j}).Setpoint, Energy); |
---|
147 | end |
---|
148 | end |
---|
149 | |
---|
150 | else |
---|
151 | |
---|
152 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
153 | % Online Energy Ramping Loop % |
---|
154 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
155 | |
---|
156 | if length(Energy) > 1 |
---|
157 | fprintf(' 0. Starting energy %f GeV\n', PresentEnergy(1)); |
---|
158 | else |
---|
159 | fprintf(' Starting energy %f GeV\n', PresentEnergy(1)); |
---|
160 | end |
---|
161 | |
---|
162 | for i = 2:length(Energy) |
---|
163 | |
---|
164 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
165 | % Keep the "K-values" fixed but change the energy % |
---|
166 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
167 | |
---|
168 | % Change the AD.Energy |
---|
169 | setfamilydata(Energy(i), 'Energy'); |
---|
170 | |
---|
171 | |
---|
172 | % Set the hysteresis branch for the ramp direction (this determines the tabled used in hw2physics & physics2hw) |
---|
173 | if Energy(i) > Energy(i-1) |
---|
174 | setfamilydata('Lower', 'HysteresisBranch'); |
---|
175 | elseif Energy(i) < Energy(i-1) |
---|
176 | setfamilydata('Upper', 'HysteresisBranch'); |
---|
177 | end |
---|
178 | |
---|
179 | |
---|
180 | % Get the setpoint change (could speed this up if Energy was monotonic) |
---|
181 | for j = 1:length(ConfigFamilies) |
---|
182 | ConfigSetpointEnd.(ConfigFamilies{j}).Setpoint = physics2hw(ConfigSetpointPhysics.(ConfigFamilies{j}).Setpoint, Energy(i)); |
---|
183 | end |
---|
184 | |
---|
185 | |
---|
186 | % Set with zero wait |
---|
187 | for j = 1:length(ConfigFamilies) |
---|
188 | setpv(ConfigSetpointEnd.(ConfigFamilies{j}).Setpoint, 0); |
---|
189 | end |
---|
190 | |
---|
191 | |
---|
192 | % Wait on SP-AM |
---|
193 | %for j = 1:length(ConfigFamilies) |
---|
194 | % getpv(ConfigSetpointEnd.(ConfigFamilies{j}).Setpoint, -1); |
---|
195 | %end |
---|
196 | |
---|
197 | |
---|
198 | %%%%%%%%%%%%%%%%% |
---|
199 | % Print results % |
---|
200 | %%%%%%%%%%%%%%%%% |
---|
201 | PresentEnergy = bend2gev; |
---|
202 | if length(Energy) > 1 |
---|
203 | fprintf(' %d. Storage ring at %f GeV\n', i, PresentEnergy(1)); |
---|
204 | else |
---|
205 | fprintf(' Storage ring at %f GeV\n', PresentEnergy(1)); |
---|
206 | end |
---|
207 | drawnow; |
---|
208 | |
---|
209 | if i < length(Energy) |
---|
210 | pause(TimeDelay); |
---|
211 | end |
---|
212 | end |
---|
213 | |
---|
214 | % Change the AT model energy just to keep it insync with the accelerator |
---|
215 | setenergymodel(Energy(end)); |
---|
216 | |
---|
217 | end |
---|
218 | |
---|