ATLAS Offline Software
Loading...
Searching...
No Matches
magnetSet.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
10
11#include <istream>
12#include <fstream>
13#include <stdexcept>
14#include <cmath>
15#include <cassert>
16#include <algorithm>
17namespace FPTracker
18{
19
20 double findIPCentre(int magver, Side side, int ip)
21 {
22 if ( magver == 1 )
23 {
24 if ( (side == beam2) && (ip == 1) ) { return 26658.88320;}
25 if ( (side == beam2) && (ip == 5) ) { return 13329.593967;}
26 if ( (side == beam1) && (ip == 1) ) { return 0.;}
27 if ( (side == beam1) && (ip == 5) ) { return 13329.289233;}
28 assert(false);
29 }
30
31
32
33 if ( magver == 2 )
34 {
35 if ( (side == beam2) && (ip == 1) ) { return 13329.28923;}
36 if ( (side == beam2) && (ip == 5) ) { return 13329.59397;}
37 if ( (side == beam1) && (ip == 1) ) { return 13329.59397;}
38 if ( (side == beam1) && (ip == 5) ) { return 13329.28923;}
39 assert(false);
40 }
41
42 if ( magver == 3 ) //ALFA, from D Pelikan
43 {
44 if ( (side == beam2) && (ip == 1) ) { return 0.;}
45 if ( (side == beam2) && (ip == 5) ) { return 13329.593967;}
46 if ( (side == beam1) && (ip == 1) ) { return 0.;}
47 if ( (side == beam1) && (ip == 5) ) { return 13329.289233;}
48 assert(false);
49 }
50 // check that the argument values are in have expected values
51 assert(false);
52
53 return 0;
54 }
55
56 Magnet::Container_t magnetSet(const ConfigData& cData, const Side& side, int magver, std::shared_ptr< std::ifstream> magfile)
57 {
58 // Coordinate system: take z = forwards, x= to left , y = up.
59 // For quadrupoles, input the quantity K1L. type = 1,2 if K1L is +,-ve.
60 // Input type = 3 here to let the program decide.
61 // HKICK and VKICK are read and treated as bending magnets.
62
63
64
65 //-------- Arrange to read the magnet data from CERN files.
66 // twiss_b1.txt and twiss_b2.txt for beam 1 and beam 2
67 // beam 2 is on side=0 here and beam 1 is on side=1
68 // Read through the files to pick up the requested magnets.
69
70
71 const int& IP = cData.IP;
72 const double& apermb = cData.apermb;
73 const double& brho = cData.brho;
74 const float& absZMagMax = cData.absZMagMax;
75
76 Magnet::Container_t magnets;
77
78 double centreIP = findIPCentre(magver, side, IP);
79
80 std::ifstream& myMags = *magfile;
81
82
83 //std::cout<<"Open magnets file for beam "<<ifile<<std::endl;
84 //--- Skip introductory material, indicated by the 1st character of a record.
85 while (myMags.peek() =='@' || myMags.peek() =='*' || myMags.peek() =='$')
86 {
87 myMags.ignore(1000,'\n');
88 }
89
90 // side 1 == direction to +ve s of IP == beam 1.
91 // NB "dist" is -Delta(s) but magcen, i.e. z, is then -dist.
92
93 while(true)
94 {
95
96 double endpos=0, maglength=0, K0L=0, K1L=0, K2L=0, K3L=0, HKICK=0, VKICK=0;
97 float BETX=0,ALFX=0,MUX=0,DX=0,DPX=0,X=0,PX=0,BETY=0,ALFY=0,MUY=0,DY=0,DPY=0,Y=0,PY=0,A1=0,A2=0,A3=0,A4=0;
98
99 std::string magname,magsort, basicmag ;
100
101 std::string aperture;
102
103 if( magver==1 )
104 {
105 myMags>>magname>>magsort>>endpos>>maglength>>K0L>>K1L>>K2L>>K3L>>HKICK>>VKICK
106 >>BETX>>ALFX>>MUX>>DX>>DPX>>X>>PX>>BETY>>ALFY>>MUY>>DY>>DPY>>Y>>PY
107 >>aperture>>A1>>A2>>A3>>A4;
108 }
109 else if( magver==2 or magver==3 )
110 {
111 myMags>>magname>>magsort>>basicmag>>endpos>>maglength>>HKICK>>VKICK>>K0L
112 >>K1L>>K2L>>K3L>>X>>Y>>PX>>PY>>BETX>>BETY>>ALFX>>ALFY
113 >>MUX>>MUY>>DX>>DY>>DPX>>DPY>>aperture>>A1>>A2>>A3>>A4;
114 }
115 else
116 {
117 assert(false);
118 }
119
120 if(magver==1)
121 { // Some more fudges to give more precision
122 if(std::fabs(K0L)==0.000188) K0L=K0L*188.175/188.0 ;
123 if(std::fabs(K0L)==0.001129) K0L=K0L*1129.049/1129. ;
124 if(std::fabs(K1L)==0.055577) K0L=K0L*55576.561/55577. ;
125 if(std::fabs(K1L)==0.047986) K0L=K0L*47986.041/47986. ;
126 if(std::fabs(VKICK)==0.00020) VKICK=VKICK*20.171/20. ;
127 if(std::fabs(VKICK)==0.00019) VKICK=VKICK*19.17/19. ;
128 }
129
130 double dist = centreIP - endpos + 0.5*maglength ;
131
132 float adist=std::fabs(dist) ;
133
134 // decide how to progress down the magnet files
135 // the file formats are not constant. first
136 // consider the magver=1 or 2 (these are two formats used by AFP.
137 if ( magver == 1 or magver == 2 )
138 {
139 if (side == beam1)
140 {
141 if( dist > 0. ) {continue;}
142 if( adist > absZMagMax ) {break;}
143 }
144 else
145 {
146 if( adist > absZMagMax ) {continue;}
147 if ( dist <= 0. ) {break;}
148 }
149 }
150 else if( magver == 3 ) //ALFA. from D. Pelikan
151 {
152 if( dist > 0. ) {continue;}
153 if( adist > absZMagMax ) {break;}
154 }
155
157 double magstrength = 0;
158 if (K0L != 0.)
159 {
160 mmagtype = Magnet::hbDipole; //type = 0
161 magstrength = K0L;
162 if(side == beam2)
163 {
164 magstrength = -magstrength;
165 }
166
167 }
168 else if(K1L != 0.)
169 {
170 magstrength = K1L;
171 mmagtype = magstrength >= 0 ? Magnet::hfQuadrupole:Magnet::vfQuadrupole; // type = 3 ->1,2
172 assert(maglength > 0.);
173 magstrength = std::fabs(brho*magstrength/maglength);
174 }
175 else if(HKICK != 0.)
176 {
177 mmagtype = Magnet::hbDipole; // type = 0
178 magstrength = -HKICK;
179 }
180 else if(VKICK != 0.)
181 {
182 mmagtype = Magnet::vbDipole; // type = 4
183 magstrength = VKICK;
184 }
185
186 if(mmagtype == Magnet::notAMagnet) {continue;} // --(not a magnet)
187
188
189 double mmagcen = -dist;
190
191
192 // more differences between AFP and ALFA files (from D. Pelikan)
193 if (magver == 3)
194 {
195 if (side == beam2 ){ mmagcen = dist; }
196
197 }
198
199
200 int mmagapertype = 0;
201 // CLassify apertures.
202 if(aperture == "\"NONE\"")
203 {
204 mmagapertype = 0;
205 }
206 else if(aperture == "\"CIRCLE\"" && A1 == 0.)
207 {
208 mmagapertype =0;
209 }
210 else if(aperture == "\"CIRCLE\"" && A1 > 0.)
211 {
212 mmagapertype =1;
213 }
214 else if(aperture == "\"RECTELLIPSE\"")
215 {
216 mmagapertype =2;
217 }
218 else if(aperture == "\"OCTAGON\"")
219 {
220 mmagapertype =3;
221 }
222 else
223 {
224 throw std::runtime_error(" Unknown magnet aperture type "+aperture+"\n");
225 }
226
227
228 if(apermb > 0)
229 { // -------alter the MB apertures
230 int pos = magname.find("MB.");
231 if(pos==1)
232 {
233 A3=apermb; A4=apermb;
234 }
235 }
236
237 // note the sign convention for xdis. This shift of the magnet
238 // x location accounts for the splitting of the beams somewhere
239 // around 155. m. The x coordinate is wrt to beamline position,
240 // and not the magnet center.
241 double mmagnet_x = beamlineXPosition(mmagcen)[0];
242 double mmagnet_y = beamlineXPosition(mmagcen)[1];
243
244 Magnet::Ptr_t mptr = magnetFactory(mmagnet_x,
245 mmagnet_y,
246 mmagcen,
247 magstrength,
248 maglength,
249 mmagapertype,
250 A1,
251 A2,
252 A3,
253 A4,
254 X,
255 cData.pbeam0,
256 side,
257 mmagtype);
258 magnets.push_back(std::move(mptr));
259 }
260 std::sort(magnets.begin(), magnets.end(), absZGreater< Magnet::ConstPtr_t >);
261 return magnets;
262 }
263}
264
static const int K0L
Definition AtlasPID.h:112
std::shared_ptr< Magnet > Ptr_t
std::vector< Ptr_t > Container_t
double findIPCentre(int magver, Side side, int ip)
Definition magnetSet.cxx:20
bool absZGreater(const PtrType rhs, const PtrType lhs)
Magnet::Container_t magnetSet(const ConfigData &, const Side &side, int magversion, std::shared_ptr< std::ifstream > magfile)
Definition magnetSet.cxx:56
TransversePoint beamlineXPosition(double z)
Magnet::Ptr_t magnetFactory(double x, double y, double center, double strength, double length, int apertype, double A1, double A2, double A3, double A4, double X, double pbeam0, Side side, Magnet::Type type)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.