source: MML/trunk/mml/at/setpvmodel.m @ 4

Last change on this file since 4 was 4, checked in by zhangj, 11 years ago

Initial import--MML version from SOLEIL@2013

File size: 25.0 KB
Line 
1function ErrorFlag = setpvmodel(varargin)
2%SETPVMODEL - Sets the model
3%  ErrorFlag = setpvmodel(Family, Field, NewSP, DeviceList)
4%  ErrorFlag = setpvmodel(Family, NewSP, DeviceList)
5%  ErrorFlag = setpvmodel(Family, NewSP)
6%  ErrorFlag = setpvmodel(Family)
7%
8%  INPUTS
9%  1. Family - Family Name
10%              Data Structure
11%              Accelerator Object
12%  2. Field - Middle layer field name ('Monitor', 'Setpoint', etc) {'Monitor'}
13%             AT field name
14%             or
15%             'K','Quad','Quadrupole'
16%             'K2','Sext','Sextupole'
17%             'K3','Octupole'
18%             'KS1','SkewQuad','Skew'
19%             'Roll' or 'Tilt'  [radian] (for a magnet, uses mksrollmat)
20%             'RollX' or 'TiltX' and 'RollY' or 'TiltY'  (for a corrector magnet)
21%             Note: setpvmodel('TwissData', 'ClosedOrbit') - Sets the start condition at the first AT element
22%                   setpvmodel('TwissData', Field) - Sets the TwissData.(Field) twiss parameters at the first AT element
23%                                                    See twissline for the definition of TwissData. 
24%                                                   'dP' and 'dL' are also stored in TwissData for 6-Dim tracking.
25%
26%  3. NewSP - Desired values {Default: getgolden}
27%  4. DeviceList ([Sector Device #] or [element #]) {Default: whole family}
28%  5. 'Physics'  - Use physics  units (optional override of units)
29%     'Hardware' - Use hardware units (optional override of units)
30%
31%  OUTPUTS
32%  1. NewSP - The actual values set
33%  2. ErrorFlag
34%
35%  NOTES
36%  1. If Family is a cell array, then DeviceList and Field can also be a cell arrays
37
38%
39%  Written by Gregory J. Portmann
40% Revision
41%
42% January 25, 2005 Laurent S. Nadolski
43% ATparamgroup part modified to handle structure
44% Roll commented for correctors
45% Add new family names for BPM and correctors (machine dependent?)
46
47ErrorFlag = 0;
48
49%%%%%%%%%%%%%%%%%
50% Input parsing %
51%%%%%%%%%%%%%%%%%
52UnitsFlag = {};
53for i = length(varargin):-1:1
54    if isstruct(varargin{i})
55        % Ignore structures
56    elseif iscell(varargin{i})
57        % Ignore cells
58    elseif strcmpi(varargin{i},'struct') || strcmpi(varargin{i},'numeric')
59        % Remove and ignor
60        varargin(i) = [];
61    elseif strcmpi(varargin{i},'Simulator') || ...
62            strcmpi(varargin{i},'Model') || ...
63            strcmpi(varargin{i},'Online') || ...
64            strcmpi(varargin{i},'Manual')
65        % Remove and ignor
66        varargin(i) = [];
67    elseif strcmpi(varargin{i},'physics')
68        UnitsFlag = {'Physics'};
69        varargin(i) = [];
70    elseif strcmpi(varargin{i},'hardware')
71        UnitsFlag = {'Hardware'};
72        varargin(i) = [];
73    end
74end
75
76if length(varargin) == 0
77    error('Must have at least a family name input');
78else
79    Family = varargin{1};
80    if length(varargin) >= 2
81        Field = varargin{2};
82    end
83    if length(varargin) >= 3
84        NewSP = varargin{3};
85    end
86    if length(varargin) >= 4
87        DeviceList = varargin{4};
88    end
89end
90
91
92%%%%%%%%%%%%%%
93% Cell input %
94%%%%%%%%%%%%%%
95if iscell(Family)
96    for i = 1:length(Family)
97        if length(varargin) < 2
98            ErrorFlag{i} = setpvmodel(Family{i}, UnitsFlag{:});
99        elseif length(varargin) < 3
100            if iscell(Field)
101                ErrorFlag{i} = setpvmodel(Family{i}, Field{i}, UnitsFlag{:});
102            else
103                ErrorFlag{i} = setpvmodel(Family{i}, Field, UnitsFlag{:});
104            end
105        elseif length(varargin) < 4
106            if iscell(Field)
107                if iscell(NewSP)
108                    ErrorFlag{i} = setpvmodel(Family{i}, Field{i}, NewSP{i}, UnitsFlag{:});
109                else
110                    ErrorFlag{i} = setpvmodel(Family{i}, Field{i}, NewSP, UnitsFlag{:});
111                end
112            else
113                if iscell(NewSP)
114                    ErrorFlag{i} = setpvmodel(Family{i}, Field, NewSP{i}, UnitsFlag{:});
115                else
116                    ErrorFlag{i} = setpvmodel(Family{i}, Field, NewSP, UnitsFlag{:});
117                end
118            end
119        else
120            if iscell(Field)
121                if iscell(NewSP)
122                    if iscell(DeviceList)
123                        ErrorFlag{i} = setpvmodel(Family{i}, Field{i}, NewSP{i}, DeviceList{i}, UnitsFlag{:});
124                    else
125                        ErrorFlag{i} = setpvmodel(Family{i}, Field{i}, NewSP{i}, DeviceList, UnitsFlag{:});
126                    end
127                else
128                    if iscell(DeviceList)
129                        ErrorFlag{i} = setpvmodel(Family{i}, Field{i}, NewSP, DeviceList{i}, UnitsFlag{:});
130                    else
131                        ErrorFlag{i} = setpvmodel(Family{i}, Field{i}, NewSP, DeviceList, UnitsFlag{:});
132                    end
133                end
134            else
135                if iscell(NewSP)
136                    if iscell(DeviceList)
137                        ErrorFlag{i} = setpvmodel(Family{i}, Field, NewSP{i}, DeviceList{i}, UnitsFlag{:});
138                    else
139                        ErrorFlag{i} = setpvmodel(Family{i}, Field, NewSP{i}, DeviceList, UnitsFlag{:});
140                    end
141                else
142                    if iscell(DeviceList)
143                        ErrorFlag{i} = setpvmodel(Family{i}, Field, NewSP, DeviceList{i}, UnitsFlag{:});
144                    else
145                        ErrorFlag{i} = setpvmodel(Family{i}, Field, NewSP, DeviceList, UnitsFlag{:});
146                    end
147                end
148            end
149        end
150    end
151    return
152end
153
154
155%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
156% Family or data structure inputs beyond this point %
157%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158% Only change StructOutputFlag if 'numeric' is not on the input line
159if isstruct(Family)
160    % Data structure inputs
161    if length(varargin) < 2
162        if isfield(Family,'Field')
163            Field = Family.Field;
164        else
165            Field = '';
166        end
167    end
168    if length(varargin) < 3
169        if isfield(Family,'Data')
170            NewSP = Family.Data;
171        else
172            error('NewSP input required (or a .Data field must exist for data structure inputs)');
173        end
174    end
175    if length(varargin) < 4
176        if isfield(Family,'DeviceList')
177            DeviceList = Family.DeviceList;
178        else
179            DeviceList = [];
180        end
181    end
182    if isempty(UnitsFlag)
183        if isfield(Family,'Units')
184            UnitsFlag{1} = Family.Units;
185        end
186    end
187    if isfield(Family,'FamilyName')
188        Family = Family.FamilyName;
189    else
190        error('For data structure inputs FamilyName field must exist')
191    end
192else
193    % Family string input
194    if length(varargin) < 2
195        Field = '';
196    end
197    if length(varargin) < 3
198        NewSP = [];
199    end
200    if length(varargin) < 4
201        DeviceList = [];
202    end
203end
204
205if isnumeric(Field)
206    DeviceList = NewSP;
207    NewSP = Field;
208    Field = '';
209end
210if isempty(Field)
211    Field = 'Setpoint';
212end
213
214if isempty(NewSP)
215    NewSP = getgolden(Family, Field, DeviceList, 'numeric', UnitsFlag{:});
216end
217
218if isempty(DeviceList)
219    if isfamily(Family)
220        DeviceList = family2dev(Family);
221    end
222end
223if isfamily(Family)
224    if (size(DeviceList,2) == 1)
225        DeviceList = elem2dev(Family, DeviceList);
226    end
227end
228
229if isempty(UnitsFlag)
230    UnitsFlag = 'Hardware';
231else
232    UnitsFlag = UnitsFlag{1};
233end
234
235
236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237% Change to physics units if requested %
238%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239NewSP_HW = [];
240if strcmpi(UnitsFlag,'Hardware') && isfamily(Family, Field)
241    NewSP_HW = NewSP;
242    NewSP = hw2physics(Family, Field, NewSP, DeviceList, getenergymodel);
243end
244
245
246% Look to see it the AT model needs to be changed for this family
247ATModelNumber = getfamilydata(Family, 'AT', 'ATModel');
248if ~isempty(ATModelNumber)
249    % Change THERING
250    THERING = THERINGCELL{ATModelNumber};
251
252    % Set AD.Circumference
253    setfamilydata(findspos(THERING,length(THERING)+1), 'Circumference');
254   
255    if isfield(THERING{1}, 'MachineType')
256        setfamilydata(THERING{1}.MachineType, 'MachineType');
257    end
258    if isfield(THERING{1}, 'Energy')
259        setfamilydata(THERING{1}.Energy, 'Energy');
260    end
261    if isfield(THERING{1}, 'InjectionEnergy')
262        setfamilydata(THERING{1}.InjectionEnergy, 'InjectionEnergy');
263    end
264    if isfield(THERING{1}, 'MCF')
265        setfamilydata(THERING{1}.MCF, 'MCF');
266    else
267        % Recompute the MCF if it's likely if a new accelerator
268        %try
269        %    setfamilydata(getmcf('Model'), 'MCF');
270        %catch
271        %end
272    end
273end
274
275global THERING
276% Simulator (AT)
277if isempty(THERING)
278    error('Simulator variable is not setup properly.');
279end
280
281
282%%%%%%%%%%%%
283% Set Data %
284%%%%%%%%%%%%
285
286% Do families that do not require at AT field first
287if strcmp(Family, 'RF')
288    % RF
289    iCavity = findcells(THERING,'Frequency');
290    for i = 1:length(iCavity)
291        THERING{iCavity(i)}.Frequency = NewSP(1);
292    end
293   
294elseif any(strcmpi(Family,{'Energy','GeV'}))
295   
296    % Set energy in AT
297    % Noter: Changing the energy of the model is only a variable change
298    setenergymodel(NewSP(1));
299   
300elseif strcmp(Family, 'TwissData')
301   
302    if isfield(THERING{1}, 'TwissData')
303        InATFlag = 1;
304        TwissData = THERING{1}.TwissData;
305    else
306        InATFlag = 0;
307        TwissData = getfamilydata('TwissData');
308        if isempty(TwissData)
309            % Store in AT
310            InATFlag = 1;
311        end
312    end
313   
314    if any(strcmpi(Field, {'ClosedOrbit','dP','dL'}))
315        if ~isfield(TwissData, 'ClosedOrbit')
316            TwissData.ClosedOrbit = [0 0 0 0]';
317        end
318        if ~isfield(TwissData, 'dP')
319            TwissData.dP = 0;
320        end
321        if ~isfield(TwissData, 'dL')
322            TwissData.dL = 0;
323        end
324        if strcmpi(Field, 'ClosedOrbit')
325            if length(NewSP) < 4 || length(NewSP) == 5 || length(NewSP) > 6
326                error('Closed orbit input must be length 4 or 6');
327            elseif length(NewSP) == 4
328                TwissData.ClosedOrbit = NewSP(1:4);
329            else
330                TwissData.ClosedOrbit = NewSP(1:4);
331                TwissData.dP = NewSP(5);
332                TwissData.dL = NewSP(6);
333            end
334        elseif strcmpi(Field, 'dP')
335            TwissData.dP = NewSP(1);
336        elseif strcmpi(Field, 'dL')
337            TwissData.dL = NewSP(1);
338        end
339    else
340        if any(strcmpi(Field, {'Setpoint','Monitor'}))
341            TwissData = NewSP;
342        else
343            TwissData.(Field) = NewSP;
344        end
345    end
346               
347    % Store TwissData where it was found
348    if InATFlag
349        THERING{1}.TwissData = TwissData;
350    else
351        setfamilydata(TwissData, 'TwissData');
352    end
353   
354else
355   
356    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357    % Families that require an AT field %
358    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
359   
360    % Find the index for where the desired data is in the total device list
361    if isfamily(Family)
362        DeviceListTotal = family2dev(Family, 0);
363        [DeviceIndex, iNotFound] = findrowindex(DeviceList, DeviceListTotal);
364        if length(iNotFound) > 0
365            % Device not found
366            for i = 1:length(iNotFound)
367                fprintf('   No devices to set for Family %s(%d,%d)\n', Family, DeviceList(i,1), DeviceList(i,2));
368            end
369            error(sprintf('%d Devices not found', length(iNotFound)));
370        end
371       
372        % Find the AT structure if it exists
373        AT = getfamilydata(Family, Field, 'AT');
374        if isempty(AT)
375            if any(strcmpi(Field,{'Setpoint','Monitor','Sum','Set','Read','Readback'}))
376                AT = getfamilydata(Family, 'AT');
377                if isempty(AT)
378                    % AT.ATType must be defined
379                    %warning('Simulator not setup for %s.%s family (data filled with NaN)\n', Family, Field);
380                    fprintf('WARNING: Simulator not setup for %s.%s family (data filled with NaN)\n', Family, Field);
381                    AM = NaN * ones(length(DeviceIndex),1);
382                    ErrorFlag = 1;
383                    DataTime = 0+0*sqrt(-1);
384                    return
385                end
386            else
387                AT.ATType = Field;
388            end
389        end
390       
391        % Set methods
392        if isfield(AT, 'SpecialFunctionSet')
393            ErrorFlag = feval(AT.SpecialFunctionSet, Family, Field, NewSP, DeviceList);
394            return
395        end
396       
397        % Make sure AT.Index exists
398        if ~isfield(AT,'ATIndex')
399            AT.ATIndex = family2atindex(Family, DeviceListTotal);
400        end   
401    else
402        % Look for an AT family
403        if strcmpi(Family, 'All')
404            AT.ATIndex = (1:length(THERING))';
405        else
406            AT.ATIndex = findcells(THERING, 'FamName', Family);
407        end
408        DeviceIndex = 1:length(AT.ATIndex);
409        if isempty(DeviceList)
410            DeviceList = [ones(length(DeviceIndex),1) DeviceIndex(:)];
411        end
412        AT.ATType = Field;
413    end
414   
415   
416
417    % Check for a split magnet
418    Nsplit = size(AT.ATIndex,2);
419    if Nsplit > 1
420        % Make a large column out of the split magnets
421        NewSP = NewSP*ones(1,Nsplit);
422        NewSP = NewSP';
423        NewSP = NewSP(:);
424
425        if any(strcmpi(AT.ATType, {'HCM', 'HCOR', 'FHCOR', 'CH'})) || ...
426                any(strcmpi(AT.ATType, {'VCM', 'CVOR', 'FVCOR', 'CV'}))
427            % Correctors are in radians so the kick needs to be divided amoung the splits
428            % Note: NaN's in the ATIndex are not splits for instance [45 46; 67 NaN] means
429            %       the first magnet is split but the second is not.
430            Nsplits = ones(size(AT.ATIndex));
431            Nsplits(find(isnan(AT.ATIndex))) = 0;
432            Nsplits = sum(Nsplits')';
433            NewSP = NewSP ./ Nsplits;
434            %for i = 1:size(NewSP,1)
435            %    NewSP(i,:) = NewSP(i,:) / (Nsplit - sum(isnan(AT.ATIndex(i,:))));
436            %end
437        else
438            ATIndexList = AT.ATIndex(DeviceIndex,:)';
439            ATIndexList = ATIndexList(:);
440
441            iNaN = find(isnan(ATIndexList));
442            ATIndexList(iNaN) = [];
443            NewSP(iNaN) = [];
444        end
445    else
446        ATIndexList = AT.ATIndex(DeviceIndex);
447    end
448
449
450    % Make the setpoint changes
451
452    if isfield(AT, 'ATParameterGroup')
453
454        for i = 1:1; %size(NewSP,1)
455            if iscell(AT.ATParameterGroup)
456                % If cell, set the parameter group
457                ParameterGroup = AT.ATParameterGroup{DeviceIndex(i)};
458                THERING = setparamgroup(THERING, ParameterGroup, NewSP(i));
459            elseif ischar(AT.ATParameterGroup)
460                % Set the field
461                ATField = AT.ATParameterGroup;
462                THERING{ATIndexList(i)}.(ATField) = NewSP(i);
463            end
464        end
465
466    else
467
468        if any(strcmpi(AT.ATType, {'HCM', 'CH', 'HCOR', 'FHCOR', 'Kicker'}))
469            % HCM
470            for i = 1:size(NewSP,1)
471                % Coupling: Magnet roll is part of the AT model
472                %           The gain is part of hw2physics/physics2hw
473                if isfield(THERING{ATIndexList(i)}, 'Roll')
474                    Roll = THERING{ATIndexList(i)}.Roll;
475                else
476                    % Knowing the cross-plane family name can be a problem
477                    % If the VCM family has the same AT index, then use it.
478                    % Begin Laurent
479                    %Roll = [getroll(Family, Field, DeviceList(i,:))  0];
480                    %VCMDevList = family2dev('VCM');
481                    %iVCM = findrowindex(DeviceList(i,:), VCMDevList);
482                    %if ~isempty(iVCM)
483                    %   try
484                    %        ATIndexVCM = family2atindex('VCM', DeviceList(i,:));
485                    %        if ATIndexVCM == ATIndexList(i)
486                    %            Roll = [Roll(1) getroll('VCM', Field, DeviceList(i,:))];
487                    %        else
488                                Roll = [0 0];
489                    %        end
490                    %    catch
491                    %    end
492                    %end
493                    % End Laurent
494                end
495
496                % New X-Kick, but the Y-Kick needs to be maintained (middle layer coordinates)
497                XKick = NewSP(i);
498                YKick = [-sin(Roll(1)) cos(Roll(1))] * THERING{ATIndexList(i)}.KickAngle(:) / (cos(Roll(1)-Roll(2)));
499
500                % Superimpose the X and Y kicks
501                THERING{ATIndexList(i)}.KickAngle(1) = XKick * cos(Roll(1)) - YKick * sin(Roll(2));
502                THERING{ATIndexList(i)}.KickAngle(2) = XKick * sin(Roll(1)) + YKick * cos(Roll(2));
503                %fprintf('kick(%d,%d)=%g %g  AT=%g %g  Roll=%g  %g\n',DeviceList(i,:), XKick, YKick, THERING{ATIndexList(i)}.KickAngle, Roll);
504
505                %% X only kick
506                %THERING{ATIndexList(i)}.KickAngle(1) = NewSP(i) * cos(Roll(1));
507                %THERING{ATIndexList(i)}.KickAngle(2) = NewSP(i) * sin(Roll(1));
508            end
509
510        elseif any(strcmpi(AT.ATType, {'VCM', 'CV', 'VCOR', 'FVCOR'}))
511            % VCM
512            for i = 1:size(NewSP,1)
513                % Coupling: Magnet roll is part of the model
514                %           The gain is part of hw2physics/physics2hw
515
516                %if isfield(THERING{ATIndexList(i)}, 'Roll')
517                %    Roll = THERING{ATIndexList(i)}.Roll;
518                %else
519                %    % Setting to zero may cause a problem.  It would be better
520                %    % to call getroll but the cross-plane family name is not known.
521                %    Roll = [0 0];
522                %end
523
524                if isfield(THERING{ATIndexList(i)}, 'Roll')
525                    Roll = THERING{ATIndexList(i)}.Roll;
526                else
527                    % Knowing the cross-plane family name can be a problem
528                    % If the VCM family has the same AT index, then use it.
529                    % Begin Laurent
530                    %Roll = [0 getroll(Family, Field, DeviceList(i,:))];
531                    %HCMDevList = family2dev('HCM');
532                    %iHCM = findrowindex(DeviceList(i,:), HCMDevList);
533                    %if ~isempty(iHCM)
534                    %    try
535                    %        ATIndexHCM = family2atindex('HCM', DeviceList(i,:));
536                    %        if ATIndexHCM == ATIndexList(i)
537                    %            Roll = [getroll('HCM', Field, DeviceList(i,:)) Roll(2)];
538                    %        else
539                                Roll = [0 0];
540                    %        end
541                    %    catch
542                    %    end
543                    %end
544                    % End Laurent
545                end
546
547                % New Y-Kick, but the X-Kick needs to be maintained (middle layer coordinates)
548                XKick = [cos(Roll(2)) sin(Roll(2))] * THERING{ATIndexList(i)}.KickAngle(:) / (cos(Roll(1)-Roll(2)));
549                YKick = NewSP(i);
550
551                % Superimpose the X and Y kicks
552                THERING{ATIndexList(i)}.KickAngle(1) = XKick * cos(Roll(1)) - YKick * sin(Roll(2));
553                THERING{ATIndexList(i)}.KickAngle(2) = XKick * sin(Roll(1)) + YKick * cos(Roll(2));
554                %fprintf('kick(%d,%d)=%g %g  AT=%g %g  Roll=%g  %g\n',DeviceList(i,:), XKick, YKick, THERING{ATIndexList(i)}.KickAngle, Roll);
555
556                %% Y only kick
557                %THERING{ATIndexList(i)}.KickAngle(1) = -1 * NewSP(i) * sin(Roll(2));
558                %THERING{ATIndexList(i)}.KickAngle(2) =      NewSP(i) * cos(Roll(2));
559            end
560
561        elseif any(strcmpi(AT.ATType,{'K','Quad','Quadrupole'}))
562            % K - Quadrupole
563            for i = 1:size(NewSP,1)
564                if isfield(THERING{ATIndexList(i)}, 'K')
565                    THERING{ATIndexList(i)}.K = NewSP(i);
566                end
567                THERING{ATIndexList(i)}.PolynomB(2) = NewSP(i);
568            end
569
570        elseif any(strcmpi(AT.ATType,{'K2','Sext','Sextupole'}))
571            % K2 - Sextupole
572            for i = 1:size(NewSP,1)
573                THERING{ATIndexList(i)}.PolynomB(3) = NewSP(i);
574            end
575
576        elseif any(strcmpi(AT.ATType,{'K3','Octupole'}))
577            % K3 - Octupole
578            for i = 1:size(NewSP,1)
579                THERING{ATIndexList(i)}.PolynomB(4) = NewSP(i);
580            end
581
582        elseif any(strcmpi(AT.ATType,{'KS','KS1','SkewQ','SkewQuad'}))
583            % KS1 - Skew Quadrupole
584            for i = 1:size(NewSP,1)
585                THERING{ATIndexList(i)}.PolynomA(2) = NewSP(i);
586            end
587
588        elseif strcmpi(AT.ATType, 'BEND')
589            % BEND
590            % The BEND simulates very differently:
591            % 1. The BEND "K" value does not change
592            % 2. The energy comes from the hw2physics (bend2gev)
593            % 3. All the other magnets have a "K" change
594            % 4. The underlying assumption is that the RF cavity provides the necessary energy
595
596            % Since this takes a relatively long time, only do it once.  Setting each BEND to
597            % different setpoints will not work anyways.
598
599            if isempty(NewSP_HW)
600                fprintf('\n   WARNING: Must set the BEND magnet in the model in hardware units\n');
601                fprintf('   since the BEND magnet in physics units does not usually change.\n');
602                fprintf('   No change made to the BEND family in the model!\n');
603                return
604            end
605
606            % Get the energy of the model
607            GeVPresent = getenergy('Simulator');
608
609            % Get the desired energy of the model
610            GeVDesired = bend2gev(Family, Field, NewSP_HW(i), DeviceList(i,:));
611
612            if abs(GeVPresent - GeVDesired) < 1e-9  % GeV
613                % No change needed
614                return;
615            end
616
617            % Get the present machine config in hardware units
618            SP = getmachineconfig('Hardware', 'Simulator');
619
620            % Set energy in the model
621            setenergymodel(GeVDesired);            % Sets the model energy which is stored in AT
622            setfamilydata(GeVDesired, 'Energy');   % Set design energy in the middle layer
623
624            % Set the new "K" values (physics values)
625            % The amperes does not change, but the "K" values do
626            % because the energy was change between hw2physics/physics2hw calls
627            if isfield(SP,'BEND')
628                SP = rmfield(SP, 'BEND');  % or anything with a BEND ATType
629            end
630            if isfield(SP,'BEND_Setpoint')
631                SP = rmfield(SP, 'BEND_Setpoint');  % or anything with a BEND ATType
632            end
633            setmachineconfig(SP, 'Hardware', 'Simulator');
634           
635        elseif strcmpi(AT.ATType, 'Roll')
636            % Roll or Tilt
637            for i = 1:size(NewSP,1)
638                % Roll the magnet
639                if isfield(THERING{ATIndexList(i)}, 'R1') && isfield(THERING{ATIndexList(i)}, 'R2')
640                    R1 = mksrollmat( NewSP(i));
641                    R2 = mksrollmat(-NewSP(i));
642                    THERING{ATIndexList(i)}.R1 = R1;
643                    THERING{ATIndexList(i)}.R2 = R2;
644                else
645                    error(sprintf('%s(%d,%d) must have a R1 & R2 field in the model to be rolled.', Family, DeviceList(i,:)));
646                end
647            end
648
649        elseif strcmpi(AT.ATType, 'RollX') || strcmpi(AT.ATType, 'RollY')
650            % Roll or Tilt
651            for i = 1:size(NewSP,1)
652                % Roll the corrector magnet
653                if isfield(THERING{ATIndexList(i)}, 'KickAngle')
654                    % The .Roll field is just a middle layer way to store the roll.
655                    % Otherwise, one can not tell the difference between x/y kicks and coupling
656                    % Unroll it, then roll it to the new setpoint
657                    if isfield(THERING{ATIndexList(i)}, 'Roll')
658                        Roll = THERING{ATIndexList(i)}.Roll;
659                    else
660                        Roll = [0 0];
661                    end
662
663                    % Roll it back to actual (measured) coordinates
664                    XKick = [ cos(Roll(2)) sin(Roll(2))] * THERING{ATIndexList(i)}.KickAngle(:) / (cos(Roll(1)-Roll(2)));
665                    YKick = [-sin(Roll(1)) cos(Roll(1))] * THERING{ATIndexList(i)}.KickAngle(:) / (cos(Roll(1)-Roll(2)));
666                   
667                    % Roll it forward to the new model coordinates
668                    if strcmpi(AT.ATType, 'RollX')
669                        Roll(1) = NewSP(i);
670                    else
671                        Roll(2) = NewSP(i);
672                    end
673                   
674                    THERING{ATIndexList(i)}.KickAngle(1) = XKick * cos(Roll(1)) - YKick * sin(Roll(2));
675                    THERING{ATIndexList(i)}.KickAngle(2) = XKick * sin(Roll(1)) + YKick * cos(Roll(2));
676                else
677                    error('%s(%d,%d) must be a KickAngle field in the model to be rolled.', Family, DeviceList(i,:));
678                end
679            end
680
681        elseif strcmpi(AT.ATType, 'Septum')
682
683            %== Septum ==
684
685        elseif strcmpi(AT.ATType, 'null')
686            % JR - do nothing behaviour
687
688        else
689            warning('ATType unknown for Family %s', Family);
690            for i = 1:size(NewSP,1)
691                THERING{ATIndexList(i)}.(Field) = NewSP(i);
692            end
693        end
694    end
695end
696
697
698
699% Look to see if the THERINGCELL needs to be updated
700if ~isempty(ATModelNumber)
701    THERINGCELL{ATModelNumber} = THERING;
702end
703
Note: See TracBrowser for help on using the repository browser.