RINGPASS tracks particles through each element of the cell array RING calling the element-specific tracking function specified in the RING{i}.PassMethod field. ROUT=RINGPASS(RING,RIN,NTURNS) tracks particle(s) with initial condition(s) RIN for NTURNS turns RING AT lattice RIN 6xN matrix: input coordinates of N particles NTURNS Number of turns to perform (default: 1) ROUT 6x(N*NTURNS) matrix: output coordinates of N particles at the exit of each turn [ROUT, LOST]=RINGPASS(...) Return additionally an information on lost particles LOST 1xN logical vector, indicating lost particles If only one output is given, loss information is saved in global variable LOSSFLAG [ROUT, LOST, NTURNS]=RINGPASS(...) Return additionally the number of turns performed by each particle NTURNS 1xN vector, number of turns performed [ROUT, LOSS, NTURNS, LOSSINFO]=RINGPASS(...,'nhist',NHIST,...) Return additional information on lost particles NHIST number elements before the loss to be traced (default: 1) LOSSINFO 1x1 structure with the following fields: lost 1xN logical vector, indicating lost particles turn 1xN vector, turn number where the particle is lost element 1xN vector, element number where the particle is lost coordinates_at_loss 6xN array, coordinates at the exit of the element where the particle is lost (sixth coordinate is inf if particle is lost in a physical aperture) coordinates 6xNxNHIST array, coordinates at the entrance of the LHIST elements before the loss ROUT=RINGPASS(...,'KeepLattice') Tracking with the 'KeepLattice' flag is more efficient because it reuses persistent data structures stored in memory in previous calls to RINGPASS. !!! In order to use this option, RINGPASS must first be called without the 'KeepLattice' flag. It then assumes that the elements in RING DO NOT CHANGE between calls. Otherwise, RINGPASS must be called again without 'KeepLattice'. ROUT=RINGPASS(...,'reuse') is kept for compatibilty with previous versions. It has no effect. ROUT=RINGPASS(...,'Silent') does not output the particle coordinates at each turn but only at the end of the tracking ROUT=RINGPASS(...,PREFUNC) ROUT=RINGPASS(...,PREFUNC,POSTFUNC) ROUT=RINGPASS(...,function_handle.empty,POSTFUNC) PREFUNC and POSTFUNC are function handles, PREFUNC is called immediately before tracking each element, POSTFUNC is called immediately after each element. Functions are called as: ROUT=FUNC(ELEMENT, RIN, NTURN, NELEMENT) and are allowed to modify the particle coordinates See also: LINEPASS
0001 function [Rout, varargout] = ringpass(ring, Rin, nturns, varargin) 0002 %RINGPASS tracks particles through each element of the cell array RING 0003 % calling the element-specific tracking function specified in the 0004 % RING{i}.PassMethod field. 0005 % 0006 % ROUT=RINGPASS(RING,RIN,NTURNS) tracks particle(s) with initial 0007 % condition(s) RIN for NTURNS turns 0008 % 0009 % RING AT lattice 0010 % RIN 6xN matrix: input coordinates of N particles 0011 % NTURNS Number of turns to perform (default: 1) 0012 % 0013 % ROUT 6x(N*NTURNS) matrix: output coordinates of N particles at 0014 % the exit of each turn 0015 % 0016 % [ROUT, LOST]=RINGPASS(...) 0017 % Return additionally an information on lost particles 0018 % LOST 1xN logical vector, indicating lost particles 0019 % If only one output is given, loss information is saved in 0020 % global variable LOSSFLAG 0021 % 0022 % [ROUT, LOST, NTURNS]=RINGPASS(...) 0023 % Return additionally the number of turns performed by each particle 0024 % NTURNS 1xN vector, number of turns performed 0025 % 0026 % [ROUT, LOSS, NTURNS, LOSSINFO]=RINGPASS(...,'nhist',NHIST,...) 0027 % Return additional information on lost particles 0028 % NHIST number elements before the loss to be traced (default: 1) 0029 % LOSSINFO 1x1 structure with the following fields: 0030 % lost 1xN logical vector, indicating lost particles 0031 % turn 1xN vector, turn number where the particle is lost 0032 % element 1xN vector, element number where the particle is lost 0033 % coordinates_at_loss 6xN array, coordinates at the exit of 0034 % the element where the particle is lost 0035 % (sixth coordinate is inf if particle is lost in a physical aperture) 0036 % coordinates 6xNxNHIST array, coordinates at the entrance of the 0037 % LHIST elements before the loss 0038 % 0039 % ROUT=RINGPASS(...,'KeepLattice') Tracking with the 'KeepLattice' flag is 0040 % more efficient because it reuses persistent data structures stored in 0041 % memory in previous calls to RINGPASS. 0042 % 0043 % !!! In order to use this option, RINGPASS must first be called 0044 % without the 'KeepLattice' flag. It then assumes that the elements in RING 0045 % DO NOT CHANGE between calls. Otherwise, RINGPASS must be called again 0046 % without 'KeepLattice'. 0047 % 0048 % ROUT=RINGPASS(...,'reuse') is kept for compatibilty with previous 0049 % versions. It has no effect. 0050 % 0051 % ROUT=RINGPASS(...,'Silent') does not output the particle coordinates at 0052 % each turn but only at the end of the tracking 0053 % 0054 % ROUT=RINGPASS(...,PREFUNC) 0055 % ROUT=RINGPASS(...,PREFUNC,POSTFUNC) 0056 % ROUT=RINGPASS(...,function_handle.empty,POSTFUNC) 0057 % PREFUNC and POSTFUNC are function handles, PREFUNC is called 0058 % immediately before tracking each element, POSTFUNC is called 0059 % immediately after each element. Functions are called as: 0060 % 0061 % ROUT=FUNC(ELEMENT, RIN, NTURN, NELEMENT) 0062 % 0063 % and are allowed to modify the particle coordinates 0064 % 0065 % See also: LINEPASS 0066 0067 % Check input arguments 0068 if size(Rin,1)~=6 0069 error('Matrix of initial conditions, the second argument, must have 6 rows'); 0070 end 0071 0072 if nargin < 3 0073 nturns = 1; 0074 end 0075 [keeplattice,args]=getflag(varargin, 'KeepLattice'); 0076 [dummy,args]=getflag(args,'reuse'); %#ok<ASGLU> % Kept for compatibility and ignored 0077 [silent,args]=getflag(args, 'silent'); 0078 funcargs=cellfun(@(arg) isa(arg,'function_handle'), args); 0079 nhist=getoption(struct(args{~funcargs}), 'nhist',1); 0080 0081 newlattice = double(~keeplattice); 0082 0083 if silent 0084 refpts=[]; 0085 else 0086 refpts=length(ring)+1; 0087 end 0088 0089 [prefunc,postfunc]=parseargs({function_handle.empty,function_handle.empty},... 0090 args(funcargs)); 0091 0092 try 0093 [Rout,lossinfo] = atpass(ring,Rin,newlattice,nturns,refpts,prefunc,postfunc,nhist); 0094 0095 if nargout>1 0096 if nargout>3, varargout{3}=lossinfo; end 0097 if nargout>2, varargout{2} = lossinfo.turn; end 0098 varargout{1} = lossinfo.lost; 0099 else % if no output arguments - create LOSSFLAG, for backward compatibility with AT 1.2 0100 evalin('base','clear LOSSFLAG'); 0101 evalin('base','global LOSSFLAG'); 0102 assignin('base','LOSSFLAG',lossinfo.lost); 0103 end 0104 catch err 0105 if strcmp(err.identifier,'MATLAB:unassignedOutputs') 0106 error('Atpass:obsolete',['ringpass is now expecting 2 output arguments from atpass.\n',... 0107 'You may need to call "atmexall" to install the new version']); 0108 else 0109 rethrow(err) 0110 end 0111 end 0112 end