EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EicBeamLineElementGrad.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EicBeamLineElementGrad.cxx
1 // RMP (rpetti@bnl.gov), 2016/03/02
2 //
3 // EIC IR Beam line element magnetic field gradient handler;
4 //
5 
6 //
7 // CHECK: XY-orientation (well, and Z-sign as well); A[][] -> transpose or not?;
8 //
9 
10 #include <stdlib.h>
11 #include <assert.h>
12 #include <math.h>
13 #include <iostream>
14 #include <fstream>
15 #ifdef __APPLE__
16 #include <unistd.h>
17 #include <libgen.h>
18 #endif
19 
20 #include <TGeoBBox.h>
21 #include <TGeoCone.h>
22 #include <TGeoVolume.h>
23 #include <TMath.h>
24 #include <TVector3.h>
25 
26 #include <EicLibrary.h>
27 #include <EicBeamLineElementGrad.h>
28 
29 // =======================================================================================
30 
31 //
32 // FIXME: check against the latest EicHtcTask codes and modify accordingly;
33 //
34 
36 {
37  //std::cout << "In EicBeamLineElementGrad::Initialize()" << std::endl;
38 
39 
40  mAngle = mAngle*1.e-3*TMath::RadToDeg();
41  TGeoRotation *rw = new TGeoRotation();
42  rw->RotateY(mAngle);
43  // Convert [m] -> [cm];
44  mTransformation = new TGeoCombiTrans(100.0 * mCenterX, 100.0 * mCenterY, 100.0 * mCenterZ, rw);
45 
46 
47  //return EicMagneticFieldGrad::Initialize();
49 } // EicBeamLineElementGrad::Initialize()
50 
51 const char *EicBeamLineElementGrad::BasenameWrapper(const char *fname) const {
52  // basename() can screw up this buffer, fine;
53  char buffer[1024];
54  snprintf(buffer, 1024-1, "%s", fname);
55 
56  return basename(buffer);
57 } // EicBeamLineElementGrad::BasenameWrapper()
58 
59 void EicBeamLineElementGrad::SetFieldScale(const double fieldScaler)
60 {
61  mScale = fieldScaler;
62 }
63 
64 
65 // ---------------------------------------------------------------------------------------
66 
67 int EicBeamLineElementGrad::GetFieldValue(const double xx[], double B[]) const
68 {
69  // FIXME: do thia lambda stuff better later (Fermi shape, bore-dependent, etc);
70  double xl[3], lambda = 10.0;
71 
72  // NB: it looks like this->Contains() call will also have to perform mTransformation->MasterToLocal()
73  // before doing anything else; so no gain to call it first; THINK: the only thing I can do to speed
74  // processing up is to call mShape->Contains() after mTransformation->MasterToLocal() here; hmm?;
75  mTransformation->MasterToLocal(xx, xl);
76 
77  {
78  TVector3 xlv(xl[0], xl[1], xl[2]), BLV;
79 
80  // Make sure we are in the region of the aperture where the field exists;
81  // if not, make the field 0.
82  double zl = xl[2], r = sqrt(xl[0]*xl[0] + xl[1]*xl[1]), dzMax = 100*mLength/2. + lambda;//)*100.0;
83  // FIXME: consider conical bore case, please;
84  double rMax = mBoreZout*100.0;
85 
86  //if(xl[2] < (mLength/2.)*100. && xl[2] > (-mLength/2.)*100. && r < mBoreZout*100.) {
87  if(fabs(zl) < dzMax && r < rMax) {
88  double cff = 1.0;
89  // Mimic triangular fall off in the [-lambda .. lambda] range around mLength/2;
90  if (fabs(zl) > 100.*mLength/2. - lambda) cff = (fabs(dzMax) - fabs(zl))/(2*lambda);
91  //printf("%f\n", cff);
92 
93  if(mGradient == 0.) { // indicates a dipole
94  BLV.SetX(0.);
95  BLV.SetY(cff * mB * 10.0 * mScale); // 10.0: convert from T to kG
96  BLV.SetZ(0.);
97  } else {
98  BLV.SetX(cff * xl[1]*mGradient*10./100.*mScale); // multiply by 10 for T->kG conversion
99  BLV.SetY(cff * xl[0]*mGradient*10./100.*mScale); // divide by 100 to convert cm -> m
100  BLV.SetZ(0.);
101  } //if
102  } else {
103  for(unsigned iq=0; iq<3; iq++)
104  B[iq] = 0.0;
105 
106  return -1;
107  } //if
108 
109  {
110  double BL[3] = {BLV[0], BLV[1], BLV[2]};
111  mTransformation->LocalToMasterVect(BL, B);
112  }
113  }
114 
115  return 0;
116 } // EicBeamLineElementGrad::GetFieldValue()
117 
118 // ---------------------------------------------------------------------------------------
119 
120 #include <EicMediaHub.h>
121 
122 // Make it configurable parameter later; for now just add 100mm to both width and height;
123 #define _EXTRA_BORE_WIDTH_ (100.0)
124 
125 #define _IRON_ ("iron")
126 #define _VACUUM_ ("thin-air")//("vacuum")
127 //#define _VACUUM_ ("vacuum")
128 
129 #include <TGeoManager.h>
130 #include <TGeoCompositeShape.h>
131 
133 {
134  // FIXME: obviously need an Instance() member there;
135  EicMediaHub *mediaHub = new EicMediaHub();
136 
137  mediaHub->Init();
138 
139  // Ok, basically I need to create something matching yoke volume and put it in a proper
140  // place in the geometry tree;
141  char yokeIronName[128], yokeVacuumName[128];
142 
143  //snprintf(yokeIronName, 128-1, "%s-Yoke", GetDetectorName().Data());
144  //snprintf(yokeVacuumName, 128-1, "%s-Vacuum", GetDetectorName().Data());
145  snprintf(yokeIronName, 128-1, "%sYoke", GetDetectorName().Data());
146  snprintf(yokeVacuumName, 128-1, "%sVacuum", GetDetectorName().Data());
147 
148  //double origin[3] = {0.0, 0.0, 100.0 * mLength/2};
149  double origin[3] = {0.0, 0.0, 0.0};
150  TGeoShape *yoke;
151  double xyHalfSize = mDiaOut ? 100.0 * mDiaOut/2 : 100.0 * mBoreZout + 0.1 * _EXTRA_BORE_WIDTH_;
152  if (mB)
153  yoke = new TGeoBBox(yokeIronName,
154  xyHalfSize, xyHalfSize,
155  //100.0 * mBoreZout + 0.1 * _EXTRA_BORE_WIDTH_,
156  //100.0 * mBoreZout + 0.1 * _EXTRA_BORE_WIDTH_,
157  100.0 * mLength/2);//, origin);
158  else
159  yoke = new TGeoTube(yokeIronName,
160  0.0,
161  xyHalfSize,
162  //100.0 * mBoreZout + 0.1 * _EXTRA_BORE_WIDTH_,
163  100.0 * mLength/2);
164 
165 #if 1//_LATER_
166  assert(mBoreZin);
167  if (mBoreZin) {
168  TGeoShape *vacuum;
169  if (mBoreZin == mBoreZout)
170  // Use simplier cylindrical shape in this case;
171  vacuum = new TGeoTube(yokeVacuumName,
172  0.0,
173  100.0 * mBoreZin,
174  100.0 * mLength/2 + 0.1);
175  else
176  // Otherwise define a conical bore;
177  vacuum = new TGeoCone(yokeVacuumName,
178  100.0 * mLength/2 + 0.1,
179  0.0,
180  100.0 * mBoreZin,
181  0.0,
182  100.0 * mBoreZout);
183  char cmd[1024], yokeCompName[128];
184  snprintf(cmd, 1024-1, "%s-%s", yokeIronName, yokeVacuumName);
185  snprintf(yokeCompName, 128-1, "%sComp", GetDetectorName().Data());
186 
187  TGeoCompositeShape *comp = new TGeoCompositeShape(yokeCompName/*GetDetectorName().Data()*/, cmd);
188  mYoke = new TGeoVolume(yokeCompName/*GetDetectorName().Data()*/, comp, mediaHub->GetMedium(_IRON_));
189 
190  mYoke->SetFillColor(GetYokeColor());
191  // FIXME: this has no effect -> check!;
192  mYoke->SetLineColor(GetYokeColor());
193  mYoke->RegisterYourself();
194  } //if
195 #else
196  mYoke = new TGeoVolume(yokeIronName, yoke, mediaHub->GetMedium(_IRON_));
197  mYoke->SetFillColor(GetYokeColor());
198  // FIXME: this has no effect -> check!;
199  mYoke->SetLineColor(GetYokeColor());
200  mYoke->RegisterYourself();
201 
202  if (mBoreZin) {
203  TGeoShape *vacuum;
204  if (mBoreZin == mBoreZout)
205  // Use simplier cylindrical shape in this case;
206  vacuum = new TGeoTube(yokeVacuumName,
207  0.0,
208  100.0 * mBoreZin,
209  100.0 * mLength/2);
210  else
211  // Otherwise define a conical bore;
212  vacuum = new TGeoCone(yokeVacuumName,
213  100.0 * mLength/2,
214  0.0,
215  100.0 * mBoreZin,
216  0.0,
217  100.0 * mBoreZout);
218 
219  TGeoVolume *vvacuum = new TGeoVolume(yokeVacuumName, vacuum, mediaHub->GetMedium(_VACUUM_));
220 
221  vvacuum->RegisterYourself();
222 
223  mYoke->AddNode(vvacuum, 0, new TGeoTranslation(origin[0], origin[1], origin[2]));
224  } //if
225 #endif
226 
227  gGeoManager->GetTopVolume()->AddNode(mYoke, 0, mTransformation);
228 
229  return 0;
230 
231 } // EicBeamLineElementGrad::ConstructGeometry()
232 
233 // =======================================================================================
234