1 | function [BPMFamilyOutput, BPMDevOutput, DeltaSpos, PhaseAdvance] = quad2bpm(QUADFamily, QUADDev, LocationFlag) |
---|
2 | %QUAD2BPM - Return the nearest BPM to the specified quadrupole |
---|
3 | % [BPMFamily, BPMDeviceList, DeltaSpos, PhaseAdvance] = quad2bpm(QUADFamily, QUADDev, LocationFlag) |
---|
4 | % |
---|
5 | % INPUTS |
---|
6 | % 1. QUADFamily - Quadrupole family (1 family only (row string)) |
---|
7 | % 2. QUADDeviceList - Quadrupole device list |
---|
8 | % 3. LocationFlag - Only search BPM positions that are 'UpStream' or 'DownStream' {Default for transport lines} |
---|
9 | % of the quadrupole. Else no location preference is used {Default for rings}. |
---|
10 | % |
---|
11 | % OUTPUTS |
---|
12 | % 1. BPMFamily |
---|
13 | % 2. BPMDeviceList |
---|
14 | % 3. DeltaSpos - Distance from the Quad to the BPM |
---|
15 | % 4. PhaseAdvance - Phase advance from the quadrupole to the BPM (using the model) [radians] |
---|
16 | % |
---|
17 | % NOTES |
---|
18 | % 1. ThickQuadFlag takes into account quadrupole length since AT give |
---|
19 | % element position at entrance |
---|
20 | % 2. At SOLEIL, for Q10, the BPM used is not the closest one but the |
---|
21 | % second closest one. The code is patched for this BBA purpose |
---|
22 | % 3. Patch for BPM [13 8] and [13 9] of Nanoscopium |
---|
23 | % |
---|
24 | % See Also bpm2quad |
---|
25 | |
---|
26 | % |
---|
27 | % Written by Gregory J. Portmann |
---|
28 | % Modified by Laurent S. Nadolski |
---|
29 | |
---|
30 | ThickQuadFlag = 1; % If thick quad, if 1 s-position is true center, else entrance of element |
---|
31 | |
---|
32 | if nargin < 1 |
---|
33 | QUADFamily = ''; |
---|
34 | end |
---|
35 | |
---|
36 | % default quad family is the first one |
---|
37 | if isempty(QUADFamily) |
---|
38 | QUADFamily = findmemberof('QUAD'); |
---|
39 | QUADFamily = QUADFamily{1}; |
---|
40 | end |
---|
41 | |
---|
42 | if nargin < 2 |
---|
43 | QUADDev = []; |
---|
44 | end |
---|
45 | |
---|
46 | % Default device list is the first one |
---|
47 | if isempty(QUADDev) |
---|
48 | QUADDev = family2dev(QUADFamily); |
---|
49 | QUADDev = QUADDev(1,:); |
---|
50 | end |
---|
51 | |
---|
52 | if nargin < 3 |
---|
53 | LocationFlag = ''; |
---|
54 | end |
---|
55 | |
---|
56 | % Location Flag: can be Downstream for lines and any for rings |
---|
57 | if isempty(LocationFlag) |
---|
58 | if any(strcmpi(getfamilydata('MachineType'), {'Transport','Transportline','Linac'})) |
---|
59 | LocationFlag = 'DownStream'; |
---|
60 | else |
---|
61 | LocationFlag = 'Any'; |
---|
62 | end |
---|
63 | end |
---|
64 | |
---|
65 | |
---|
66 | % Get all the BPM families |
---|
67 | BPMFamilyList = getfamilylist; |
---|
68 | [tmp, i] = ismemberof(BPMFamilyList, 'BPM'); |
---|
69 | % if empty takes first one |
---|
70 | if ~isempty(i) |
---|
71 | BPMFamilyList = BPMFamilyList(i,:); |
---|
72 | else |
---|
73 | BPMFamilyList = [gethbpmfamily,getvbpmfamily]; |
---|
74 | end |
---|
75 | |
---|
76 | |
---|
77 | % Find the BPM next to the Quad |
---|
78 | BPMFamilyOutput = []; |
---|
79 | for k = 1:size(QUADDev,1) |
---|
80 | % get quadrupole s-positions |
---|
81 | % (AT gives position at entrance of element) |
---|
82 | if ThickQuadFlag % then add half of the quad length |
---|
83 | QUADspos = getspos(QUADFamily, QUADDev(k,:)); |
---|
84 | QUADspos = QUADspos + getleff(QUADFamily, QUADDev(k,:))/2; |
---|
85 | else |
---|
86 | QUADspos = getspos(QUADFamily, QUADDev(k,:)); |
---|
87 | end |
---|
88 | |
---|
89 | % if asked, compute phase advance at the middle of the quad |
---|
90 | % The phase is just (phase_entrance+phase_exit)/2 |
---|
91 | if nargout >= 4 |
---|
92 | ATIndex = family2atindex(QUADFamily, QUADDev(k,:)); |
---|
93 | [PhiQx, PhiQy] = modeltwiss('Phase', 'All'); |
---|
94 | i = findrowindex(ATIndex, (1:length(PhiQx))'); |
---|
95 | PhiQx = (PhiQx(i) + PhiQx(i+1))/2; |
---|
96 | end |
---|
97 | |
---|
98 | % search for closest BPM to specified quad |
---|
99 | Del = inf; |
---|
100 | for j = 1:size(BPMFamilyList,1) |
---|
101 | % get BPM s-positions |
---|
102 | Family = deblank(BPMFamilyList(j,:)); |
---|
103 | BPMDevList = family2dev(Family); |
---|
104 | BPMspos = getspos(Family); |
---|
105 | |
---|
106 | if strcmpi(LocationFlag, 'DownStream') |
---|
107 | i = find(abs(BPMspos-QUADspos)==min(abs(BPMspos-QUADspos)) & BPMspos>QUADspos); |
---|
108 | elseif strcmpi(LocationFlag, 'UpStream') |
---|
109 | i = find(abs(BPMspos-QUADspos)==min(abs(BPMspos-QUADspos)) & BPMspos<QUADspos); |
---|
110 | else |
---|
111 | i = find(abs(BPMspos-QUADspos)==min(abs(BPMspos-QUADspos))); |
---|
112 | end |
---|
113 | |
---|
114 | if strcmpi(QUADFamily, 'Q10') |
---|
115 | % take the second closest BPM |
---|
116 | tmpBPMspos = BPMspos; |
---|
117 | tmpBPMspos(i) = Inf; |
---|
118 | i = find(abs(tmpBPMspos-QUADspos)==min(abs(tmpBPMspos-QUADspos))); |
---|
119 | end |
---|
120 | |
---|
121 | BPMDev{j} = BPMDevList(i,:); |
---|
122 | |
---|
123 | if abs(BPMspos(i)-QUADspos) < Del |
---|
124 | BPMFamilyMin = Family; |
---|
125 | BPMDevMin = BPMDev{j}; |
---|
126 | Del = abs(BPMspos(i)-QUADspos); |
---|
127 | DelwithSign = BPMspos(i)-QUADspos; |
---|
128 | end |
---|
129 | end |
---|
130 | |
---|
131 | BPMFamilyOutput = strvcat(BPMFamilyOutput, BPMFamilyMin); |
---|
132 | BPMDevOutput(k,:) = BPMDevMin; |
---|
133 | DeltaSpos(k,1) = DelwithSign; |
---|
134 | |
---|
135 | % If asked |
---|
136 | % Get the phase advance between the BPM and Quad in the model |
---|
137 | if nargout >= 4 |
---|
138 | [PhiX, PhiY] = modeltwiss('Phase', BPMFamilyOutput, BPMDevOutput(k,:)); |
---|
139 | PhaseAdvance = PhiX - PhiQx; |
---|
140 | end |
---|
141 | end |
---|