Skip to content

Commit e8036c1

Browse files
authored
Matlab frequency control (#560)
* Handle frequency change of dp optics in 6d * trajectory response * naming * Added a test for off-momentum in 6D lattices * Add tests off-momentum with dct and df * Help improved
1 parent 40be867 commit e8036c1

File tree

10 files changed

+227
-118
lines changed

10 files changed

+227
-118
lines changed

atmat/atphysics/LinearOptics/atlinopt6.m

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@
8080
%
8181
% See also atlinopt2 atlinopt4 tunechrom
8282

83-
[ringdata,elemdata]=wrapper6d(ring,@xlinopt6,varargin{:});
83+
[ringdata,elemdata]=frequency_control(@xlinopt6,ring,varargin{:});
8484

85-
function [ringdata,elemdata] = xlinopt6(ring, is6d, varargin)
85+
function [ringdata,elemdata] = xlinopt6(ring, varargin)
8686
clight = PhysConstant.speed_of_light_in_vacuum.value; % m/s
8787
[get_chrom, varargs]=getflag(varargin, 'get_chrom');
8888
[get_w, varargs]=getflag(varargs, 'get_w');
@@ -91,6 +91,7 @@
9191
[DPStep,~]=getoption(varargs,'DPStep');
9292
[cavargs,varargs]=getoption(varargs,{'cavpts'});
9393
[refpts,varargs]=getargs(varargs,1,'check',@(arg) isnumeric(arg) || islogical(arg));
94+
is_6d=getoption(varargs,'is_6d',[]); % Always set by frequency_control, keep in varargs
9495

9596
if isempty(twiss_in) % Circular machine
9697
[orbs,orbitin]=findorbit(ring,refpts,dpargs{:},varargs{:});
@@ -120,15 +121,15 @@
120121
)';
121122
ringdata=struct('tune',tunes,'damping_time',damping_times);
122123

123-
if is6d % 6D processing
124+
if is_6d % 6D processing
124125
[alpha,beta,disp]=cellfun(@output6,ri,'UniformOutput',false);
125126
if get_w || get_chrom
126127
frf=get_rf_frequency(ring);
127128
DFStep=-DPStep*mcf(atradoff(ring))*frf;
128129
rgup=atsetcavity(ring,'Frequency',frf+0.5*DFStep,cavargs{:});
129130
rgdn=atsetcavity(ring,'Frequency',frf-0.5*DFStep,cavargs{:});
130-
[~,o1P]=findorbit(rgup,'guess',orbitin,varargs{:});
131-
[~,o1M]=findorbit(rgdn,'guess',orbitin,varargs{:});
131+
[~,o1P]=findorbit6(rgup,'guess',orbitin,varargs{:});
132+
[~,o1M]=findorbit6(rgdn,'guess',orbitin,varargs{:});
132133
if get_w
133134
[ringdata.chromaticity,w]=chrom_w(rgup,rgdn,o1P,o1M,refpts);
134135
[elemdata.W]=deal(w{:});
@@ -180,7 +181,7 @@
180181

181182
function [vals,ms,phis,rmats,as]=build_1turn_map(ring,refpts,orbit,varargin)
182183
% Build the initial distribution at entrance of the transfer line
183-
if is6d
184+
if is_6d
184185
[mt,ms]=findm66(ring,refpts,'orbit',orbit,varargs{:});
185186
else
186187
[mt,ms]=findm44(ring,NaN,refpts,'orbit',orbit,varargs{:});

atmat/atphysics/LinearOptics/findm44.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
varargs=getdparg(varargs);
7979
[dp,varargs]=getoption(varargs,'dp',0.0);
8080
[dpargs,varargs]=getoption(varargs,{'dct','df'});
81+
[~,varargs]=getoption(varargs,'is_6d',[]); % Consume the is_6d option
8182
[refpts,orbitin,varargs]=getargs(varargs,[],orbitin,'check',@(x) ~(ischar(x) || isstring(x))); %#ok<ASGLU>
8283

8384
if islogical(refpts)
Lines changed: 56 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function [M66, varargout] = findm66(LATTICE, varargin)
1+
function varargout = findm66(LATTICE, varargin)
22
%FINDM66 numerically finds the 6x6 transfer matrix of an accelerator lattice
33
% by differentiation of LINEPASS near the closed orbit
44
% FINDM66 uses FINDORBIT6 to search for the closed orbit in 6-d
@@ -7,6 +7,18 @@
77
% M66 = FINDM66(RING) finds the full one-turn 6-by-6
88
% matrix at the entrance of the first element
99
%
10+
%[...]=FINDM66(RING,...,'dp',DP) Specify the momentum deviation when
11+
% radiation is OFF (default: 0)
12+
%
13+
%[...]=FINDM66(RING,...,'dct',DCT) Specify the path lengthening when
14+
% radiation is OFF (default: 0)
15+
%
16+
%[...]=FINDM66(RING,...,'df',DF) Specify the RF frequency deviation
17+
% radiation is OFF (default: 0)
18+
%
19+
%[...]=FINDM66(RING,...,'orbit',ORBIT) Specify the orbit at the entrance
20+
% of the ring, if known.
21+
%
1022
% [M66,T] = FINDM66(RING,REFPTS) in addition to M finds
1123
% 6-by-6 transfer matrixes between entrances of
1224
% the first element and each element indexed by REFPTS.
@@ -37,52 +49,54 @@
3749
if ~iscell(LATTICE)
3850
error('First argument must be a cell array');
3951
end
40-
NE = length(LATTICE);
41-
[XYStep,varargs]=getoption(varargin,'XYStep'); % Step size for numerical differentiation %1.e-8
42-
[DPStep,varargs]=getoption(varargs,'DPStep'); % Step size for numerical differentiation %1.e-6
43-
[orbitin,varargs]=getoption(varargs,'orbit',[]);
44-
[refpts,orbitin,varargs]=getargs(varargs,[],orbitin,'check',@(x) ~(ischar(x) || isstring(x))); %#ok<ASGLU>
52+
[varargout{1:nargout}] = frequency_control(@xfindm66,LATTICE,varargin{:});
4553

46-
if islogical(refpts)
47-
refpts(end+1:NE+1)=false;
48-
elseif isnumeric(refpts)
49-
refpts=setelems(false(1,NE+1),refpts);
50-
else
51-
error('REFPTS must be numeric or logical');
52-
end
54+
function [M66, varargout] = xfindm66(LATTICE, varargin)
55+
NE = length(LATTICE);
56+
[XYStep,varargs]=getoption(varargin,'XYStep'); % Step size for numerical differentiation %1.e-8
57+
[DPStep,varargs]=getoption(varargs,'DPStep'); % Step size for numerical differentiation %1.e-6
58+
[orbitin,varargs]=getoption(varargs,'orbit',[]);
59+
[dpargs,varargs]=getoption(varargs,{'dp','dct','df'});
60+
[is_6d,varargs]=getoption(varargs,'is_6d',[]); % Always set by frequency_control
61+
[refpts,orbitin,varargs]=getargs(varargs,[],orbitin,'check',@(x) ~(ischar(x) || isstring(x))); %#ok<ASGLU>
5362

54-
if isempty(orbitin)
55-
if check_radiation(LATTICE)
56-
orbitin = findorbit6(LATTICE,'XYStep',XYStep,'DPStep',DPStep);
57-
else
58-
[~, orbitin] = findorbit4(LATTICE,0.0,'XYStep',XYStep);
59-
end
60-
end
63+
if islogical(refpts)
64+
refpts(end+1:NE+1)=false;
65+
elseif isnumeric(refpts)
66+
refpts=setelems(false(1,NE+1),refpts);
67+
else
68+
error('REFPTS must be numeric or logical');
69+
end
6170

62-
refs=setelems(refpts,NE+1);
63-
reqs=refpts(refs);
71+
if isempty(orbitin)
72+
[~, orbitin] = findorbit(LATTICE,'XYStep',XYStep,'DPStep',DPStep,'is_6d',is_6d,dpargs{:});
73+
end
6474

65-
% Build a diagonal matrix of initial conditions
66-
%scaling=2*XYStep*[1 0.1 1 0.1 1 1];
67-
scaling=XYStep*[1 1 1 1 0 0] + DPStep*[0 0 0 0 1 1];
68-
D6 = 0.5*diag(scaling);
69-
% Add to the orbit_in. First 12 columns for derivative
70-
% 13-th column is for closed orbit
71-
RIN = orbitin + [D6 -D6 zeros(6,1)];
72-
ROUT = linepass(LATTICE,RIN,refs);
73-
TMAT3 = reshape(ROUT,6,13,[]);
74-
M66 = (TMAT3(:,1:6,end)-TMAT3(:,7:12,end))./scaling;
75+
refs=setelems(refpts,NE+1);
76+
reqs=refpts(refs);
7577

76-
if nargout >= 2 % Calculate matrices at all REFPTS.
77-
varargout{1} = (TMAT3(:,1:6,reqs)-TMAT3(:,7:12,reqs))./scaling;
78-
% Return closed orbit if requested
79-
if nargout >= 3
80-
varargout{2}=squeeze(TMAT3(:,13,reqs));
81-
end
82-
end
78+
% Build a diagonal matrix of initial conditions
79+
%scaling=2*XYStep*[1 0.1 1 0.1 1 1];
80+
scaling=XYStep*[1 1 1 1 0 0] + DPStep*[0 0 0 0 1 1];
81+
D6 = 0.5*diag(scaling);
82+
% Add to the orbit_in. First 12 columns for derivative
83+
% 13-th column is for closed orbit
84+
RIN = orbitin + [D6 -D6 zeros(6,1)];
85+
ROUT = linepass(LATTICE,RIN,refs);
86+
TMAT3 = reshape(ROUT,6,13,[]);
87+
M66 = (TMAT3(:,1:6,end)-TMAT3(:,7:12,end))./scaling;
8388

84-
function mask=setelems(mask,idx)
85-
mask(idx)=true;
86-
end
89+
if nargout >= 2 % Calculate matrices at all REFPTS.
90+
varargout{1} = (TMAT3(:,1:6,reqs)-TMAT3(:,7:12,reqs))./scaling;
91+
% Return closed orbit if requested
92+
if nargout >= 3
93+
varargout{2}=squeeze(TMAT3(:,13,reqs));
94+
end
95+
end
96+
97+
function mask=setelems(mask,idx)
98+
mask(idx)=true;
99+
end
87100

101+
end
88102
end

atmat/atphysics/Orbit/findorbit.m

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,39 +30,41 @@
3030
%
3131
% See also FINDORBIT4, FINDSYNCORBIT, FINDORBIT6.
3232

33-
[orbitin,varargs]=getoption(varargin,'orbit',[]);
34-
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
35-
[dp,varargs]=getoption(varargs,'dp',NaN);
36-
[dct,varargs]=getoption(varargs,'dct',NaN);
37-
[df,varargs]=getoption(varargs,'df',NaN);
38-
if isempty(orbitin)
39-
if check_6d(ring) % Radiation ON: 6D orbit
40-
if isfinite(dp) || isfinite(dct) || isfinite(df)
41-
warning('AT:linopt','In 6D, "dp", "dct" and "df" are ignored');
33+
[orbs,orbitin]=frequency_control(@xfindorbit,ring,varargin{:});
34+
35+
function [orbs,orb0]=xfindorbit(ring,varargin)
36+
[orb0,varargs]=getoption(varargin,'orbit',[]);
37+
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
38+
[dp,varargs]=getoption(varargs,'dp',NaN);
39+
[dct,varargs]=getoption(varargs,'dct',NaN);
40+
[df,varargs]=getoption(varargs,'df',NaN);
41+
[is_6d,varargs]=getoption(varargs,'is_6d',[]); % Always set by frequency_control
42+
if isempty(orb0)
43+
if is_6d % Radiation ON: 6D orbit
44+
orb0=xorbit_6(ring,varargs{:});
45+
elseif isfinite(df)
46+
[cell_l,cell_frev,cell_h]=atGetRingProperties(ring,'cell_length',...
47+
'cell_harmnumber','cell_revolution_frequency');
48+
dct=-cell_l*df/(cell_frev*cell_h+df);
49+
orb0=xorbit_ct(ring,dct,varargs{:});
50+
elseif isfinite(dct)
51+
orb0=xorbit_ct(ring,dct,varargs{:});
52+
else
53+
orb0=xorbit_dp(ring,dp,varargs{:});
54+
end
55+
args={'KeepLattice'};
56+
else
57+
args={};
4258
end
43-
orbitin=xorbit_6(ring,varargs{:});
44-
elseif isfinite(df)
45-
[cell_l,cell_frev,cell_h]=atGetRingProperties(ring,'cell_length',...
46-
'cell_harmnumber','cell_revolution_frequency');
47-
dct=-cell_l*df/(cell_frev*cell_h+df);
48-
orbitin=xorbit_ct(ring,dct,varargs{:});
49-
elseif isfinite(dct)
50-
orbitin=xorbit_ct(ring,dct,varargs{:});
51-
else
52-
orbitin=xorbit_dp(ring,dp,varargs{:});
53-
end
54-
args={'KeepLattice'};
55-
else
56-
args={};
57-
end
5859

59-
if islogical(refpts)
60-
refpts=find(refpts);
61-
end
62-
if isempty(refpts)
63-
% return only the fixed point at the entrance of RING{1}
64-
orbs=orbitin;
65-
else
66-
orbs=linepass(ring,orbitin,refpts,args{:});
67-
end
60+
if islogical(refpts)
61+
refpts=find(refpts);
62+
end
63+
if isempty(refpts)
64+
% return only the fixed point at the entrance of RING{1}
65+
orbs=orb0;
66+
else
67+
orbs=linepass(ring,orb0,refpts,args{:});
68+
end
69+
end
6870
end

atmat/atphysics/Orbit/findorbit4.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
[dct,varargs]=getoption(varargs,'dct',NaN);
6262
[df,varargs]=getoption(varargs,'df',NaN);
6363
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
64+
[~,varargs]=getoption(varargs,'is_6d',[]); % Consume the is_6d option
6465
if isempty(orbitin)
6566
if isfinite(df)
6667
[cell_l,cell_frev,cell_h]=atGetRingProperties(ring,'cell_length',...

atmat/atphysics/Orbit/findorbit6.m

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@
3838
% from the range 1 to length(RING)+1.
3939
% See further explanation of REFPTS in the 'help' for FINDSPOS
4040
%
41+
% FINDORBIT6(...,'dp',DP)
42+
% Specify the off-momentum. The RF frequency will be adjusted to get the
43+
% desired value
44+
%
45+
% FINDORBIT6(...,'dct',DCT)
46+
% Specify the path lengthening. The RF frequency will be adjusted to get
47+
% the desired value
48+
%
49+
% FINDORBIT6(...,'df',DF)
50+
% Specify the RF frequency deviation
51+
%
4152
% FINDORBIT6(RING,REFPTS,GUESS)
4253
% FINDORBIT6(...,'guess',GUESS) The search for the fixed point
4354
% starts from initial condition GUESS. Otherwise the search starts from
@@ -56,22 +67,27 @@
5667
if ~iscell(ring)
5768
error('First argument must be a cell array');
5869
end
59-
[orbitin,varargs]=getoption(varargin,'orbit',[]);
60-
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
61-
if isempty(orbitin)
62-
orbitin=xorbit_6(ring,varargs{:});
63-
args={'KeepLattice'};
64-
else
65-
args={};
66-
end
70+
[orb6,orbitin] = frequency_control(@xfindorbit6,ring,varargin{:});
6771

68-
if islogical(refpts)
69-
refpts=find(refpts);
70-
end
71-
if isempty(refpts)
72-
% return only the fixed point at the entrance of RING{1}
73-
orb6=orbitin;
74-
else
75-
orb6 = linepass(ring,orbitin,refpts,args{:});
76-
end
72+
function[orb6,orbitin] = xfindorbit6(ring,varargin)
73+
[orbitin,varargs]=getoption(varargin,'orbit',[]);
74+
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
75+
[~,varargs]=getoption(varargs,'is_6d',[]); %% Consume the is_6d option
76+
if isempty(orbitin)
77+
orbitin=xorbit_6(ring,varargs{:});
78+
args={'KeepLattice'};
79+
else
80+
args={};
81+
end
82+
83+
if islogical(refpts)
84+
refpts=find(refpts);
85+
end
86+
if isempty(refpts)
87+
% return only the fixed point at the entrance of RING{1}
88+
orb6=orbitin;
89+
else
90+
orb6 = linepass(ring,orbitin,refpts,args{:});
91+
end
92+
end
7793
end

atmat/atphysics/Orbit/findsyncorbit.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
[dp,varargs]=getoption(varargs,'dp',NaN);
6161
[df,varargs]=getoption(varargs,'df',NaN);
6262
[refpts,varargs]=getargs(varargs,[],'check',@(arg) isnumeric(arg) || islogical(arg));
63+
[~,varargs]=getoption(varargs,'is_6d',[]); % Consume the is_6d option
6364
if isempty(orbitin)
6465
if isfinite(df)
6566
[cell_l,cell_frev,cell_h]=atGetRingProperties(ring,'cell_length',...

atmat/atphysics/TuneAndChromaticity/tunechrom.m

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@
4040
if cpl1 || ~cpl2
4141
warning('AT:ObsoleteParameter','The "coupled" flag is ignored: coupling is always assumed');
4242
end
43-
[varargout{1:nargout}]=wrapper6d(ring,@xtunechrom,allargs{:});
43+
[varargout{1:nargout}]=frequency_control(@xtunechrom,ring,allargs{:});
4444

45-
function [tune, chrom] = xtunechrom(ring,is6d,varargin)
45+
function [tune, chrom] = xtunechrom(ring,varargin)
4646
[oldchrom,varargs]=getflag(varargin,'chrom');
4747
[chrom,varargs]=getflag(varargs,'get_chrom');
4848
[dpargs,varargs]=getoption(varargs,{'orbit','dp','dct','df'});
4949
[cavargs,varargs]=getoption(varargs,{'cavpts'});
5050
[DPStep,~]=getoption(varargs,'DPStep');
51-
if is6d
51+
is_6d=getoption(varargs,'is_6d',[]); % Always set by frequency_control, keep in varargs
52+
if is_6d
5253
tunefunc=@tune6;
5354
else
5455
tunefunc=@tune4;
@@ -59,13 +60,13 @@
5960
tune=tunefunc(ring,'orbit',orbitin,varargs{:});
6061

6162
if chrom || oldchrom || nargout == 2
62-
if is6d
63+
if is_6d
6364
frf=get_rf_frequency(ring);
6465
DFStep=-DPStep*mcf(atradoff(ring))*frf;
6566
rgup=atsetcavity(ring,'Frequency',frf+0.5*DFStep,cavargs{:});
6667
rgdn=atsetcavity(ring,'Frequency',frf-0.5*DFStep,cavargs{:});
67-
[~,o1P]=findorbit(rgup,'guess',orbitin,varargs{:});
68-
[~,o1M]=findorbit(rgdn,'guess',orbitin,varargs{:});
68+
[~,o1P]=findorbit6(rgup,'guess',orbitin,varargs{:});
69+
[~,o1M]=findorbit6(rgdn,'guess',orbitin,varargs{:});
6970
deltap=o1P(5)-o1M(5);
7071
else
7172
dp=orbitin(5);

0 commit comments

Comments
 (0)