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

Last change on this file since 28 was 28, checked in by zhangj, 10 years ago

Add features to set/get the TL Dipoles by the bending angle, while the ring dipoles are still connected to the beam energy in AT. (Maybe this features in TL dipoles need to change back in the future...)

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