source: MML/trunk/at/atphysics/twissring.m @ 4

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

Initial import--MML version from SOLEIL@2013

File size: 5.9 KB
Line 
1function [TD, varargout] = twissring(RING,DP,varargin)
2%TWISSRING calculates linear optics functions for an UNCOUPLED ring
3%
4% [TwissData, tune]  = TWISSRING(LATTICE,DP) calculates twiss parameters
5%    and closed orbit coordinates at the RING entrance assuming
6%    constant energy deviation DP.
7%
8% [TwissData, tune]  = TWISSRING(LATTICE,DP,REFPTS) calculates Twiss parameters
9%    and closed orbit coordinates at specified reference points REFPTS.
10%
11%    Note: REFPTS is an array of increasing indexes that 
12%    select elements from range 1 to length(LATTICE)+1.
13%    See further explanation of REFPTS in the 'help' for FINDSPOS
14%
15% [TwissData, tune, chrom]  = TWISSRING(...,'chrom', DDP) also calculates
16%    linear dispersion and chromaticity. Dispersion is returned as one
17%    of the fields in TwissData.
18%    !!! Last argument DDP is a momentum deviation on top
19%    of DP (the second argument) used to calculate and normalize
20%    dispersion and chromaticity. If not supplied
21%    the default value of 1e-8 is used.
22%
23%    Note: To resolve the integer part of the tune
24%    and the uncertainty of acos(trace(M)/2) it is necessary to
25%    supply sufficient number of REFPTS properly spaced in betatron phase.
26%
27% TwisData is a 1-by-REFPTS (1-by-1) structure array with fields
28%       (Some are the same as in the output of LINOPT)
29%       ElemIndex   - integer (element number) in the RING
30%       SPos        - longitudinal position [m]
31%       ClosedOrbit - closed orbit column vector with
32%                     components x, px, y, py (momentums, NOT angles)                                           
33%       Dispersion  - dispersion orbit position 4-by-1 vector with
34%                     components [eta_x, eta_prime_x, eta_y, eta_prime_y]'
35%                     calculated with respect to the closed orbit with
36%                     momentum deviation DP
37%       M44         - 4x4 transfer matrix M from the beginning of RING
38%                     to the entrance of the element for specified DP [2]
39%       beta        - [betax, betay] horizontal and vertical Twiss parameter beta
40%       alpha       - [alphax, alphay] horizontal and vertical Twiss parameter alpha
41%       mu          - [mux, muy] horizontal and vertical betatron phase
42%                     !!! NOT 2*PI normalized
43%
44% Use MATLAB function CAT to get the data from fields of TwissData into MATLAB arrays.
45%     Example:
46%     >> TD = twissring(THERING,0,1:length(THERING));
47%     >> BETA = cat(1,TD.beta);
48%     >> S = cat(1,TD.SPos);
49%     >> plot(S,BETA(:,1))
50
51% See also TWISSLINE, LINOPT, TUNECHROM.
52
53NE=length(RING);
54DDP_default = 1e-8;
55% Process input arguments
56switch nargin
57case 2
58    REFPTS=NE+1;
59    CHROMFLAG=0;
60case 3
61    if isnumeric(varargin{1})
62        REFPTS = varargin{1};
63        CHROMFLAG = 0;
64    elseif ischar(varargin{1}) & strncmp(lower(varargin{1}),'chrom',5)
65        CHROMFLAG = 1;
66        REFPTS = NE+1;
67        DDP = DDP_default;
68    else
69        error('Third argument must be a numeric array or string');
70    end
71case 4
72    if isnumeric(varargin{1})
73        REFPTS = varargin{1};
74        if ischar(varargin{2}) & strncmp(lower(varargin{2}),'chrom',5)
75            CHROMFLAG = 1;
76            DDP = DDP_default;
77        else
78            error('Fourth argument - wrong type');
79        end
80    elseif ischar(varargin{1}) & strncmp(lower(varargin{1}),'chrom',5)
81        CHROMFLAG = 1;
82        REFPTS = NE+1;
83        if isnumeric(varargin{2})
84            DDP = varargin{2};
85        else
86            error('Fourth argument - wrong type');
87        end
88    end
89case 5
90    if isnumeric(varargin{1})
91        REFPTS = varargin{1};
92    else
93        error('Third argument - wrong type');
94    end
95    if ischar(varargin{2}) & strncmp(lower(varargin{2}),'chrom',5)
96         CHROMFLAG = 1;
97    else
98         error('Fourth argument - wrong type');
99    end
100    if isnumeric(varargin{3})
101        DDP = varargin{3};
102    else
103        error('Fifth argument - wrong type');
104    end
105otherwise
106    error('Wrong number of arguments');
107end
108
109% Include the endpoint if it is not already in REFPTS
110if REFPTS(end)==NE+1
111    [M44, MS, orb] = findm44(RING,DP,REFPTS);
112else
113    [M44, MS, orb] = findm44(RING,DP,[REFPTS,NE+1]);
114end
115
116
117
118
119cos_mu_x = (M44(1,1)+M44(2,2))/2;
120cos_mu_y = (M44(3,3)+M44(4,4))/2;
121
122sin_mu_x = sign(M44(1,2))*sqrt(-M44(1,2)*M44(2,1)-(M44(1,1)-M44(2,2))^2/4);
123sin_mu_y = sign(M44(3,4))*sqrt(-M44(3,4)*M44(4,3)-(M44(3,3)-M44(4,4))^2/4);
124
125
126ax = (M44(1,1)-M44(2,2))/2/sin_mu_x;
127ay = (M44(3,3)-M44(4,4))/2/sin_mu_y;
128
129bx = M44(1,2)/sin_mu_x;
130by = M44(3,4)/sin_mu_y;
131
132BX = squeeze((MS(1,1,:)*bx-MS(1,2,:)*ax).^2 + MS(1,2,:).^2)/bx;
133BY = squeeze((MS(3,3,:)*by-MS(3,4,:)*ay).^2 + MS(3,4,:).^2)/by;
134
135
136AX = -squeeze((MS(1,1,:)*bx-MS(1,2,:)*ax).*(MS(2,1,:)*bx-MS(2,2,:)*ax) + MS(1,2,:).*MS(2,2,:))/bx;
137AY = -squeeze((MS(3,3,:)*by-MS(3,4,:)*ay).*(MS(4,3,:)*by-MS(4,4,:)*ay) + MS(3,4,:).*MS(4,4,:))/by;
138
139MX = atan(squeeze( MS(1,2,:)./(MS(1,1,:)*bx-MS(1,2,:)*ax)));
140MY = atan(squeeze(MS(3,4,:)./(MS(3,3,:)*by-MS(3,4,:)*ay)));
141
142MX = BetatronPhaseUnwrap(MX);
143MY = BetatronPhaseUnwrap(MY);
144
145tune = [MX(end),MY(end)]/2/pi;
146
147NR = length(REFPTS);
148% Build TD only for points originally referenced in REFPTS
149TD = struct('ElemIndex',num2cell(REFPTS),...
150    'SPos',num2cell(findspos(RING,REFPTS)),...
151    'ClosedOrbit',num2cell(orb(:,1:NR),1),...
152    'M44', squeeze(num2cell(MS(:,:,1:NR),[1 2]))',...
153    'beta', num2cell([BX(1:NR),BY(1:NR)],2)',...
154    'alpha', num2cell([AX(1:NR),AY(1:NR)],2)',...
155    'mu', num2cell([MX(1:NR),MY(1:NR)],2)');
156
157
158if CHROMFLAG
159    [TD_DDP tune_DDP] = twissring(RING,DP+DDP,REFPTS);
160    DORBIT = reshape(cat(1,TD_DDP.ClosedOrbit),4,[]);
161    DISPERSION = num2cell((DORBIT-orb(:,1:NR))/DDP,1);
162    [TD.Dispersion] = deal( DISPERSION{:});
163end
164   
165if nargout>1
166    varargout{1}=tune;
167end
168if nargout==3 & CHROMFLAG
169    varargout{2} = (tune_DDP-tune)/DDP;
170end
171
172function UP = BetatronPhaseUnwrap(P)
173% unwrap negative jumps in betatron
174    DP = diff(P);
175    JUMPS = [0; diff(P)] < 0;
176    UP = P+cumsum(JUMPS)*pi;
177
178
Note: See TracBrowser for help on using the repository browser.