ATLAS Offline Software
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 
5 #include "FPTracker/magnetSet.h"
7 #include "FPTracker/ConfigData.h"
8 #include "FPTracker/STLHelpers.h"
10 
11 #include <istream>
12 #include <fstream>
13 #include <stdexcept>
14 #include <cmath>
15 #include <cassert>
16 #include <algorithm>
17 namespace 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 
156  Magnet::Type mmagtype = Magnet::notAMagnet;
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 
FPTracker::findIPCentre
double findIPCentre(int magver, Side side, int ip)
Definition: magnetSet.cxx:20
FPTracker::Magnet::vbDipole
@ vbDipole
Definition: FPTracker/FPTracker/Magnet.h:64
ConfigData.h
FPTracker::magnetSet
Magnet::Container_t magnetSet(const ConfigData &, const Side &side, int magversion, std::shared_ptr< std::ifstream > magfile)
Definition: magnetSet.cxx:56
FPTracker::Magnet::hfQuadrupole
@ hfQuadrupole
Definition: FPTracker/FPTracker/Magnet.h:64
STLHelpers.h
FPTracker::Magnet::hbDipole
@ hbDipole
Definition: FPTracker/FPTracker/Magnet.h:64
Monitored::X
@ X
Definition: HistogramFillerUtils.h:24
magnetSet.h
TRT::Hit::side
@ side
Definition: HitInfo.h:83
FPTracker::beam1
@ beam1
Definition: FPTrackerConstants.h:12
FPTracker::ConfigData::absZMagMax
float absZMagMax
Definition: FPTracker/FPTracker/ConfigData.h:23
FPTracker::beam2
@ beam2
Definition: FPTrackerConstants.h:12
magnetFactory.h
FPTracker::beamlineXPosition
TransversePoint beamlineXPosition(double z)
Definition: beamlineXPosition.cxx:11
FPTracker::Magnet::Container_t
std::vector< Ptr_t > Container_t
Definition: FPTracker/FPTracker/Magnet.h:62
Side
Definition: WaferTree.h:36
FPTracker::Magnet::notAMagnet
@ notAMagnet
Definition: FPTracker/FPTracker/Magnet.h:64
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
Monitored::Y
@ Y
Definition: HistogramFillerUtils.h:24
FPTracker::ConfigData::pbeam0
double pbeam0
Definition: FPTracker/FPTracker/ConfigData.h:18
FPTracker::ConfigData::brho
double brho
Definition: FPTracker/FPTracker/ConfigData.h:19
FPTracker::Magnet::vfQuadrupole
@ vfQuadrupole
Definition: FPTracker/FPTracker/Magnet.h:64
FPTracker::magnetFactory
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)
Definition: magnetFactory.cxx:87
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
FPTracker::Magnet::Ptr_t
std::shared_ptr< Magnet > Ptr_t
Definition: FPTracker/FPTracker/Magnet.h:61
beamlineXPosition.h
FPTracker::ConfigData
Definition: FPTracker/FPTracker/ConfigData.h:9
FPTracker
Definition: FPTracker/FPTracker/Beamline.h:12
FPTracker::ConfigData::apermb
double apermb
Definition: FPTracker/FPTracker/ConfigData.h:15
FPTracker::ConfigData::IP
int IP
Definition: FPTracker/FPTracker/ConfigData.h:12
FPTracker::Magnet::Type
Type
Definition: FPTracker/FPTracker/Magnet.h:64