173 #include "StarMagField.h"
174 #include "StarCallf77.h"
180 #define agufld F77_NAME(agufld,AGUFLD)
181 #define mfldgeo F77_NAME(mfldgeo,MFLDGEO)
191 StarMagField* StarMagField::Instance() {
return fgInstance;}
195 Float_t type_of_call agufld(Float_t *x, Float_t *bf) {
196 bf[0] = bf[1] = bf[2] = 0;
197 if (StarMagField::Instance())
198 StarMagField::Instance()->BField(x,bf);
200 printf(
"agufld:: request for non initialized mag.field, return 0\n");
201 assert(StarMagField::Instance());
206 void type_of_call mfldgeo(Float_t &factor) {
207 if (StarMagField::Instance()) {
208 printf(
"StarMagField mfldgeo: The field has been already instantiated.\n");
210 printf(
"StarMagField instantiate starsim field=%g\n",factor);
211 (
new StarMagField(StarMagField::kMapped,factor/5.))->SetLock();
213 Float_t x[3]={0},b[3];
215 printf(
"StarMagField:mfldgeo(%g) Bz=%g\n",factor,b[2]);
222 Float_t date; Int_t kz; Float_t rmaxx, zmaxx, rrm, zz1, zz2;
223 Float_t RmaxInn, ZmaxInn;
226 static const BFLD_t BFLD = {
244 Float_t Zi, Ri[20], Bzi[20], Bri[20];
247 static const Int_t nZext = 23;
248 static const BDAT_t BDAT[nZext] = {
251 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0,
252 200.0, 225.0, 250.0, 275.0, 300.0, 375.0, 400.0 } ,
253 {4704.6,4768.0,4946.6,5148.3,5128.6,4927.3,4844.9,4830.1,
254 4823.3,4858.0,5110.9,3402.4, -18.1, -13.6, -25.0 } ,
255 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
256 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } },
261 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0,
262 200.0, 225.0, 250.0, 275.0, 300.0, 375.0, 400.0 } ,
263 {4704.6,4768.0,4946.6,5148.3,5128.6,4927.3,4844.9,4830.1,
264 4823.3,4858.0,5110.9,3402.4, -18.1, -13.6, -25.0 } ,
265 { 0.0, 131.3, 188.4, 74.1,-148.6,-164.8, -53.2, 23.8,
266 97.4, 213.7, 329.3, 75.3, 18.2, -44.3, -36.5 } },
269 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0,
270 200.0, 225.0, 250.0, 275.0, 300.0, 375.0, 400.0 } ,
271 {4568.8,4649.8,4898.6,5241.5,5234.5,4883.9,4806.5,4802.4,
272 4781.7,4771.8,5057.8,3504.2,-144.8, -15.0, -28.0 } ,
273 { 0.0, 188.6, 297.5, 151.9,-241.2,-242.5, -60.1, 19.5,
274 92.3, 244.3, 541.5, 396.8, 83.6, -49.9, -40.6 } },
277 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0,
278 200.0, 225.0, 250.0, 275.0, 300.0, 375.0, 400.0 } ,
279 {4383.8,4478.4,4801.1,5378.7,5431.1,4771.4,4765.5,4778.2,
280 4741.4,4651.9,4852.9,3684.4, 6.9, -16.9, -31.6 } ,
281 { 0.0, 260.2, 456.5, 312.9,-414.5,-349.8, -51.7, 14.4,
282 74.7, 234.0, 858.0, 726.3, 355.0, -56.5, -45.0 } },
285 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0,
286 200.0, 225.0, 250.0, 275.0, 300.0, 375.0, 400.0 } ,
287 {4142.1,4240.8,4614.8,5546.4,5829.1,4450.0,4737.6,4761.4,
288 4711.3,4534.1,4231.0,4067.5,-880.0, -19.3, -36.2 } ,
289 { 0.0, 341.1, 669.5, 661.0,-766.7,-480.9, -24.5, 8.8,
290 43.5, 149.9,1333.6, 999.3, 53.6, -64.2, -49.8 } },
293 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0,
294 200.0, 225.0, 250.0, 275.0, 300.0, 375.0, 400.0 } ,
295 {3842.7,3930.2,4292.5,5589.1,6643.0,3236.8,4733.0,4755.1,
296 4699.4,4485.0,1931.8,4782.0, 50.2, -22.8, -42.0 } ,
297 { 0.0, 421.2, 915.6,1382.6,-1482.8,-1019.7, 1.2, 2.0,
298 1.9, -2.3,2069.4, 791.7, 240.6, -73.6, -54.9 } },
301 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 375.0, 400.0 } ,
302 {3491.2,3552.1,3807.3,4923.7,7889.6,1983.9, -28.0, -49.4 } ,
303 { 0.0, 485.7,1133.5,2502.8, -38.8,-174.8, -85.1, -60.0 } },
306 { 0.0, 25.0, 50.0, 75.0, 250.0, 375.0, 400.0 } ,
307 {3105.3,3127.0,3200.4,3268.9, -3.5, -36.6, -59.0 } ,
308 { 0.0, 521.1,1246.1,3029.5,9199.2, -99.4, -64.5 } },
311 { 0.0, 25.0, 50.0, 75.0, 375.0, 400.0 } ,
312 {2706.4,2686.8,2574.5,1826.7, -51.8, -71.0 } ,
313 { 0.0, 520.6,1218.1,2485.3,-116.9, -67.3 } },
316 { 0.0, 25.0, 50.0, 75.0, 375.0, 400.0 } ,
317 {2317.7,2264.6,2026.3,1142.6, -80.8, -85.1 } ,
318 { 0.0, 487.6,1082.3,1787.2,-133.8, -67.0 } },
321 { 0.0, 25.0, 50.0, 75.0, 100.0, 250.0, 375.0, 400.0 } ,
322 {1958.5,1885.6,1595.6, 829.2,-563.7,4895.8,-127.6, -99.8 } ,
323 { 0.0, 432.4, 901.7,1265.8, 788.0,9507.4,-134.0, -62.2 } },
326 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0, 200.0,
327 225.0, 250.0, 275.0, 300.0, 325.0, 350.0, 375.0, 400.0 } ,
328 {1637.8,1562.2,1276.7, 678.9, 15.7, 251.6, 384.9, 503.7, 683.3,
329 1087.1,1868.1,-1320.5,-593.9,-391.5,-345.9,-168.2,-112.9 } ,
330 { 0.0, 367.3, 720.6, 900.1, 421.6, 60.4, 37.1, 44.5, 79.7,
331 229.6,2339.4, 654.6, 114.6, 35.9, -30.0,-101.8, -52.4 } },
334 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0, 200.0,
335 225.0, 250.0, 275.0, 300.0, 325.0, 350.0, 375.0, 400.0 } ,
336 {1373.5,1296.6,1045.5, 603.2, 221.4, 278.6, 382.7, 488.2, 638.7,
337 892.4, 708.6,-709.9,-515.0,-364.7,-293.1,-181.5,-122.1 } ,
338 { 0.0, 302.3, 563.3, 650.3, 369.7, 120.0, 79.6, 96.2, 169.1,
339 430.1,1454.7, 860.7, 228.6, 77.5, -10.8, -60.2, -39.4 } },
342 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0, 200.0,
343 225.0, 250.0, 275.0, 300.0, 325.0, 350.0, 375.0, 400.0 } ,
344 {1151.2,1083.6, 877.2, 557.6, 308.9, 305.2, 377.6, 463.3, 573.3,
345 684.5, 377.5,-376.2,-415.2,-326.0,-258.2,-179.8,-126.9 } ,
346 { 0.0, 243.7, 437.7, 486.1, 319.9, 155.1, 115.2, 139.4, 232.4,
347 494.6,1019.1, 751.4, 289.6, 112.2, 19.4, -26.7, -25.0 } },
350 { 0.0, 25.0, 50.0, 75.0, 100.0, 125.0, 150.0, 175.0, 200.0,
351 225.0, 250.0, 275.0, 300.0, 325.0, 350.0, 375.0, 400.0 } ,
352 {971.6, 914.8, 751.6, 520.8, 348.0, 323.7, 369.1, 432.0, 500.9,
353 520.4, 251.2,-214.3,-320.8,-282.3,-230.2,-171.7,-127.7 } ,
354 { 0.0, 194.5, 341.1, 375.8, 277.5, 171.7, 142.1, 172.1, 269.4,
355 486.6, 769.0, 624.1, 308.0, 137.2, 44.9, -1.4, -11.2 } },
358 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
359 {481.5, 423.2, 325.1, 283.8, 242.6, 88.2, -85.2,-123.1,-103.9 } ,
360 { 0.0, 119.3, 157.5, 174.6, 248.4, 314.8, 220.8, 95.4, 32.3 } },
363 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
364 {291.3, 273.2, 234.4, 192.6, 136.7, 53.6, -25.6, -64.6, -72.5 } ,
365 { 0.0, 60.7, 103.2, 135.9, 168.1, 177.4, 140.6, 84.7, 41.9 } },
368 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
369 {190.4, 181.9, 159.6, 127.7, 86.0, 37.1, -7.3, -35.9, -48.9 } ,
370 { 0.0, 37.8, 69.7, 94.3, 110.3, 110.8, 92.6, 64.2, 37.3 } },
373 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
374 {126.9, 121.7, 107.1, 84.9, 56.8, 26.4, -1.2, -21.2, -32.9 } ,
375 { 0.0, 25.0, 46.9, 63.4, 72.6, 72.2, 62.3, 46.3, 29.2 } },
378 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
379 { 84.8, 81.4, 71.7, 56.8, 38.3, 18.7, 0.8, -13.1, -22.2 } ,
380 { 0.0, 16.7, 31.4, 42.4, 48.2, 48.1, 42.4, 32.8, 21.6 } },
383 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
384 { 56.7, 54.4, 47.9, 38.0, 25.9, 13.1, 1.3, -8.3, -15.0 } ,
385 { 0.0, 11.2, 21.1, 28.4, 32.4, 32.5, 29.1, 23.0, 15.5 } },
388 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
389 { 37.7, 36.2, 31.9, 25.4, 17.5, 9.1, 1.2, -5.4, -10.1 } ,
390 { 0.0, 7.6, 14.3, 19.3, 22.0, 22.2, 20.1, 16.1, 11.0 } },
393 { 0.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0 } ,
394 { 24.8, 23.8, 21.0, 16.8, 11.6, 6.1, 0.9, -3.5, -6.7 } ,
395 { 0.0, 5.2, 9.8, 13.3, 15.2, 15.4, 14.1, 11.4, 7.9 } },
399 void StarMagField::SetStarMagFieldRotation(TGeoRotation &rot) {
400 fStarMagFieldRotation = rot;
401 fStarMagFieldRotation.SetName(
"StarMagFieldRotation");
402 fStarMagFieldRotation.Print();
405 void StarMagField::SetStarMagFieldRotation(Double_t *r) {
408 SetStarMagFieldRotation(rot);
412 bool StarMagField::mConstBz =
false;
415 StarMagField::StarMagField ( EBField map, Float_t factor,
416 Bool_t lock, Float_t rescale,
417 Float_t BDipole, Float_t RmaxDip,
418 Float_t ZminDip, Float_t ZmaxDip) :
420 #if ROOT_VERSION_CODE >= 335360
421 TVirtualMagField(
"StarMagField"),
427 fFactor(factor), fRescale(rescale),
428 fBDipole(BDipole), fRmaxDip(RmaxDip),
429 fZminDip(ZminDip), fZmaxDip(ZmaxDip),
433 printf(
"Cannot initialise twice StarMagField class\n");
437 if (fMap == kUndefined) {
438 printf(
"StarMagField is instantiated with predefined factor %f and map %i\n",fFactor, fMap);
440 if (fLock) printf(
"StarMagField is locked, no modification from DB will be accepted\n");
443 float myX[3]={0},myB[3];
445 printf (
"StarMagField(0,0,0) = %g",myB[2]);
448 fStarMagFieldRotation = TGeoRotation(
"StarMagFieldRotation");
453 void StarMagField::BField(
const Double_t x[], Double_t B[] ) {
454 Float_t xx[3] = {(Float_t) x[0], (Float_t) x[1], (Float_t) x[2]};
457 B[0] = bb[0]; B[1] = bb[1]; B[2] = bb[2];
460 void StarMagField::BField(
const Float_t x[], Float_t B[] )
465 Float_t r, z, Br_value, Bz_value ;
466 Float_t phi, Bphi_value,phi1;
468 Br_value = Bz_value = 0;
469 B[0] = B[1] = B[2] = 0;
471 r = sqrt( x[0]*x[0] + x[1]*x[1] ) ;
472 phi = atan2( x[1], x[0] ) ;
473 if ( phi < 0 ) phi += 2*TMath::Pi() ;
479 B[0] = B[1] = B[2] = 0.;
480 if ( abs(z) < 380.0 && r < 300.0 ) B[2] = +5.0;
486 Float_t za = fabs(z);
487 if (za > fZminDip && za < fZmaxDip && r < fRmaxDip) {
488 B[1] = TMath::Sign(fBDipole, z);
489 B[2] = fabs(B[1]/1000.);
492 if (z >= ZList[0] && z <= ZList[nZ-1] && r <= Radius[nR-1]) {
494 Double_t BL[3] = {0, 0, Bz_value};
496 BL[0] = Br_value * (x[0]/r) ;
497 BL[1] = Br_value * (x[1]/r) ;
501 fStarMagFieldRotation.LocalToMaster(BL,BG);
502 for (Int_t i = 0; i < 3; i++) B[i] = BG[i];
504 for (Int_t i = 0; i < 3; i++) B[i] = BL[i];
512 if (za <=342.20 && r>=303.29 && r <= 364.25) {
514 phi1=phi*TMath::RadToDeg();
515 if(phi1>12) phi1=phi1-int(phi1/12)*12;
518 B[0] = Br_value * (x[0]/r) - Bphi_value * (x[1]/r) ;
519 B[1] = Br_value * (x[1]/r) + Bphi_value * (x[0]/r) ;
537 Interpolate2ExtDBfield( r, z, Br_value, Bz_value ) ;
538 if (za <= BFLD.zmaxx && r <= BFLD.rmaxx) {
539 static const Float_t zero = 0;
540 static const Float_t one = 1;
541 Float_t wz = (za - ZList[nZ-1] )/(BFLD.zmaxx - ZList[nZ-1]);
542 Float_t wr = (r - Radius[nR-1])/(BFLD.rmaxx - Radius[nR-1]);
543 Float_t w = TMath::Min(TMath::Max(zero,TMath::Max(wz,wr)),one);
544 Float_t rm = TMath::Min(r,Radius[nR-1]);
545 Float_t zm = TMath::Sign(TMath::Min(za,ZList[nZ-1]),z);
548 Br_value = (1-w)*BrI + w*Br_value;
549 Bz_value = (1-w)*BzI + w*Bz_value;
553 B[0] = Br_value * (x[0]/r) ;
554 B[1] = Br_value * (x[1]/r) ;
564 Float_t r, z, phi, Br_value, Bz_value, Bphi_value ;
566 Br_value = Bz_value = 0;
567 B[0] = B[1] = B[2] = 0;
572 r = sqrt( x[0]*x[0] + x[1]*x[1] ) ;
576 phi = TMath::ATan2( x[1], x[0] ) ;
577 if ( phi < 0 ) phi += 2*TMath::Pi() ;
580 phi1=phi*TMath::RadToDeg();
587 B[0] = Br_value * (x[0]/r) - Bphi_value * (x[1]/r) ;
588 B[1] = Br_value * (x[1]/r) + Bphi_value * (x[0]/r) ;
599 Double_t BL[3] = {B[0], B[1], B[2]};
602 fStarMagFieldRotation.LocalToMaster(BL,BG);
603 for (Int_t i = 0; i < 3; i++) B[i] = BG[i];
605 for (Int_t i = 0; i < 3; i++) B[i] = BL[i];
611 Float_t xx[3] = {(Float_t) x[0], (Float_t) x[1], (Float_t) x[2]};
614 B[0] = bb[0]; B[1] = bb[1]; B[2] = bb[2];
624 Br_value = Bz_value = 0;
633 void StarMagField::BrBz3DField(
const Float_t r,
const Float_t z,
const Float_t phi,
634 Float_t &Br_value, Float_t &Bz_value, Float_t &Bphi_value )
639 Br_value = Bz_value = 0;
646 if ( phiprime < 0 ) phiprime += 2*TMath::Pi() ;
648 phiprime=phiprime*TMath::RadToDeg();
669 void StarMagField::ReadField( )
672 FILE *magfile, *b3Dfile ;
673 std::string comment, filename, filename3D ;
674 std::string MapLocation ;
675 std::string BaseLocation = getenv(
"STAR") ;
676 BaseLocation +=
"/StarDb/StMagF/" ;
678 if (gEnv->GetValue(
"NewTpcAlignment",0) != 0) {
679 TString rootf(
"StarFieldZ.root");
680 TString path(
".:./StarDb/StMagF:$STAR/StarDb/StMagF");
681 Char_t *file = gSystem->Which(path,rootf,kReadPermission);
683 Error(
"StarMagField::ReadField",
"File %s has not been found in path %s",rootf.Data(),path.Data());
685 Warning(
"StarMagField::ReadField",
"File %s has been found",rootf.Data());
686 TFile *pFile =
new TFile(file);
687 TH2F *Br0 = (TH2F *) pFile->Get(
"Br0");
688 TH2F *Bz0 = (TH2F *) pFile->Get(
"Bz0");
690 TH2F *Br5cm = (TH2F *) pFile->Get(
"Br5cm");
691 TH2F *Bz5cm = (TH2F *) pFile->Get(
"Bz5cm");
692 assert(Br5cm && Bz5cm);
693 TH2F *Br10cm = (TH2F *) pFile->Get(
"Br10cm");
694 TH2F *Bz10cm = (TH2F *) pFile->Get(
"Bz10cm");
695 assert(Br10cm && Bz10cm);
696 fBzdZCorrection =
new TH2F(*Bz5cm); fBzdZCorrection->SetDirectory(0);
697 fBzdZCorrection->Scale(0.5);
698 fBzdZCorrection->Add(Bz10cm,0.5);
699 fBzdZCorrection->Add(Bz0,-1.0);
700 fBrdZCorrection =
new TH2F(*Br5cm); fBrdZCorrection->SetDirectory(0);
701 fBrdZCorrection->Scale(0.5);
702 fBrdZCorrection->Add(Br10cm,0.5);
703 fBrdZCorrection->Add(Br0,-1.0);
704 Warning(
"StarMagField::ReadField",
"Use effective PMT box dZ = 7.5 cm");
711 if ( fMap == kMapped )
713 if ( fabs(fFactor) > 0.8 )
717 filename =
"bfield_full_positive_2D.dat" ;
718 filename3D =
"bfield_full_positive_3D.dat" ;
719 comment =
"Measured Full Field" ;
724 filename =
"bfield_full_negative_2D.dat" ;
725 filename3D =
"bfield_full_negative_3D.dat" ;
726 comment =
"Measured Full Field Reversed" ;
732 filename =
"bfield_half_positive_2D.dat" ;
733 filename3D =
"bfield_half_positive_3D.dat" ;
734 comment =
"Measured Half Field" ;
738 else if ( fMap == kConstant )
740 filename =
"const_full_positive_2D.dat" ;
741 comment =
"Constant Full Field" ;
746 fprintf(stderr,
"StarMagField::ReadField No map available - you must choose a mapped field or a constant field\n");
750 printf(
"StarMagField::ReadField Reading Magnetic Field %s, Scale factor = %f \n",comment.c_str(),fFactor);
751 printf(
"StarMagField::ReadField Filename is %s, Adjusted Scale factor = %f \n",filename.c_str(),fFactor*fRescale);
753 MapLocation = BaseLocation + filename ;
754 magfile = fopen(MapLocation.c_str(),
"r") ;
755 printf(
"StarMagField::ReadField Reading 2D Magnetic Field file: %s \n",filename.c_str());
761 fgets ( cname,
sizeof(cname) , magfile ) ;
762 fgets ( cname,
sizeof(cname) , magfile ) ;
763 fgets ( cname,
sizeof(cname) , magfile ) ;
764 fgets ( cname,
sizeof(cname) , magfile ) ;
765 fgets ( cname,
sizeof(cname) , magfile ) ;
767 for ( Int_t j=0 ; j < nZ ; j++ )
769 for ( Int_t k=0 ; k < nR ; k++ )
771 fgets ( cname,
sizeof(cname) , magfile ) ;
772 sscanf ( cname,
" %f %f %f %f ", &Radius[k], &ZList[j], &Br[j][k], &Bz[j][k] ) ;
773 #if defined(__ROOT__)
774 if (fBzdZCorrection && fBrdZCorrection) {
775 Br[j][k] += fFactor*fBrdZCorrection->Interpolate(ZList[j],Radius[k]);
776 Bz[j][k] += fFactor*fBzdZCorrection->Interpolate(ZList[j],Radius[k]);
786 fprintf(stderr,
"StarMagField::ReadField File %s not found !\n",MapLocation.c_str());
792 MapLocation = BaseLocation + filename3D ;
793 b3Dfile = fopen(MapLocation.c_str(),
"r") ;
794 printf(
"StarMagField::ReadField Reading 3D Magnetic Field file: %s \n",filename3D.c_str());
800 fgets ( cname,
sizeof(cname) , b3Dfile ) ;
801 fgets ( cname,
sizeof(cname) , b3Dfile ) ;
802 fgets ( cname,
sizeof(cname) , b3Dfile ) ;
803 fgets ( cname,
sizeof(cname) , b3Dfile ) ;
804 fgets ( cname,
sizeof(cname) , b3Dfile ) ;
805 fgets ( cname,
sizeof(cname) , b3Dfile ) ;
807 for ( Int_t i=0 ; i < nPhi ; i++ )
809 for ( Int_t j=0 ; j < nZ ; j++ )
811 for ( Int_t k=0 ; k < nR ; k++ )
813 fgets ( cname,
sizeof(cname) , b3Dfile ) ;
814 sscanf ( cname,
" %f %f %f %f %f %f ",
815 &R3D[k], &Z3D[j], &Phi3D[i], &Br3D[i][j][k], &Bz3D[i][j][k], &Bphi3D[i][j][k] ) ;
816 Phi3D[i] *= TMath::Pi() / 180. ;
817 #if defined(__ROOT__)
818 if (fBzdZCorrection && fBrdZCorrection) {
819 Br3D[i][j][k] += fFactor*fBrdZCorrection->Interpolate(Z3D[j],R3D[k]);
820 Bz3D[i][j][k] += fFactor*fBzdZCorrection->Interpolate(Z3D[j],R3D[k]);
828 else if ( fMap == kConstant )
831 for ( Int_t i=0 ; i < nPhi ; i++ )
833 for ( Int_t j=0 ; j < nZ ; j++ )
835 for ( Int_t k=0 ; k < nR ; k++ )
837 Br3D[i][j][k] = Br[j][k] ;
838 Bz3D[i][j][k] = Bz[j][k] ;
839 Bphi3D[i][j][k] = 0 ;
848 fprintf(stderr,
"StarMagField::ReadField File %s not found !\n",MapLocation.c_str());
861 MapLocation = BaseLocation +
"steel_magfieldmap.dat";
862 magfile = fopen(MapLocation.c_str(),
"r") ;
864 printf(
"StarMagField::ReadField Reading 3D Magnetic Field file: %s \n",filename.c_str());
867 fgets ( cname,
sizeof(cname) , magfile ) ;
868 if (cname[0] ==
'#')
continue;
871 for ( Int_t i=0 ; i < nPhiSteel ; i++ )
874 for ( Int_t k=0 ; k < nRSteel ; k++ )
876 for ( Int_t j=0 ; j < nZSteel ; j++ )
880 fgets ( cname,
sizeof(cname) , magfile ) ;
881 sscanf ( cname,
" %f %f %f %f %f %f ",
882 &R3DSteel[k], &Z3DSteel[j], &Phi3DSteel[i], &Bx3DSteel[i][j][k], &Bz3DSteel[i][j][k], &By3DSteel[i][j][k] ) ;
885 Br3DSteel[i][j][k]=cos(Phi3DSteel[i]*TMath::DegToRad())*Bx3DSteel[i][j][k]+sin(Phi3DSteel[i]*TMath::DegToRad())*By3DSteel[i][j][k];
887 Bphi3DSteel[i][j][k]=0-sin(Phi3DSteel[i]*TMath::DegToRad())*Bx3DSteel[i][j][k]+cos(Phi3DSteel[i]*TMath::DegToRad())*By3DSteel[i][j][k];
919 fscale = 0.001*fFactor*fRescale ;
922 const Int_t ORDER = 1 ;
923 static Int_t jlow=0, klow=0 ;
924 Float_t save_Br[ORDER+1] ;
925 Float_t save_Bz[ORDER+1] ;
927 Search ( nZ, ZList, z, jlow ) ;
928 Search ( nR, Radius, r, klow ) ;
929 if ( jlow < 0 ) jlow = 0 ;
930 if ( klow < 0 ) klow = 0 ;
931 if ( jlow + ORDER >= nZ - 1 ) jlow = nZ - 1 - ORDER ;
932 if ( klow + ORDER >= nR - 1 ) klow = nR - 1 - ORDER ;
934 for ( Int_t j = jlow ; j < jlow + ORDER + 1 ; j++ )
936 save_Br[j-jlow] =
Interpolate( &Radius[klow], &Br[j][klow], ORDER, r ) ;
937 save_Bz[j-jlow] =
Interpolate( &Radius[klow], &Bz[j][klow], ORDER, r ) ;
939 Br_value = fscale *
Interpolate( &ZList[jlow], save_Br, ORDER, z ) ;
940 Bz_value = fscale *
Interpolate( &ZList[jlow], save_Bz, ORDER, z ) ;
944 void StarMagField::Interpolate2ExtDBfield(
const Float_t r,
const Float_t z, Float_t &Br_value, Float_t &Bz_value ) {
945 static Float_t ZExtList[nZext];
946 static Bool_t first = kTRUE;
948 for (Int_t j = 0; j < nZext; j++) ZExtList[j] = BDAT[j].Zi;
951 Float_t za = fabs(z);
952 if (za > BFLD.zz2 || r > BFLD.rrm)
return;
953 if (za < ZList[nZ-1] && r < Radius[nR-1])
return;
956 if (za <=342.20 && r>=303.29 && r <= 363.29)
return;
960 Float_t fscale = 0.001*fFactor;
962 const Int_t ORDER = 1 ;
963 static Int_t jlow=0, klow=0 ;
964 Float_t save_Br[ORDER+1] ;
965 Float_t save_Bz[ORDER+1] ;
966 Search ( nZext, ZExtList, za, jlow ) ;
967 if ( jlow < 0 ) jlow = 0 ;
968 if ( jlow + ORDER >= nZext - 1 ) jlow = nZext - 1 - ORDER ;
970 for ( Int_t j = jlow ; j < jlow + ORDER + 1 ; j++ ) {
972 Search ( N, (Float_t *) (&BDAT[j].Ri[0]), r, klow ) ;
973 if ( klow < 0 ) klow = 0 ;
974 if ( klow + ORDER >= BDAT[j].N - 1 ) klow = BDAT[j].N - 1 - ORDER ;
975 save_Br[j-jlow] =
Interpolate( &BDAT[j].Ri[klow], &BDAT[j].Bri[klow], ORDER, r ) ;
976 save_Bz[j-jlow] =
Interpolate( &BDAT[j].Ri[klow], &BDAT[j].Bzi[klow], ORDER, r ) ;
978 Br_value = fscale *
Interpolate( &ZExtList[jlow], save_Br, ORDER, za ) ;
979 Bz_value = fscale *
Interpolate( &ZExtList[jlow], save_Bz, ORDER, za ) ;
980 if (z < 0) Br_value = - Br_value;
986 Float_t &Br_value, Float_t &Bz_value, Float_t &Bphi_value )
991 fscale = 0.001*fFactor*fRescale ;
993 const Int_t ORDER = 1 ;
994 static Int_t ilow=0, jlow=0, klow=0 ;
995 Float_t save_Br[ORDER+1], saved_Br[ORDER+1] ;
996 Float_t save_Bz[ORDER+1], saved_Bz[ORDER+1] ;
997 Float_t save_Bphi[ORDER+1], saved_Bphi[ORDER+1] ;
1004 Search( nPhi, Phi3D, phi, ilow ) ;
1005 Search( nZ, Z3D, z, jlow ) ;
1006 Search( nR, R3D, r, klow ) ;
1007 if ( ilow < 0 ) ilow = 0 ;
1008 if ( jlow < 0 ) jlow = 0 ;
1009 if ( klow < 0 ) klow = 0 ;
1011 if ( ilow + ORDER >= nPhi - 1 ) ilow = nPhi - 1 - ORDER ;
1012 if ( jlow + ORDER >= nZ - 1 ) jlow = nZ - 1 - ORDER ;
1013 if ( klow + ORDER >= nR - 1 ) klow = nR - 1 - ORDER ;
1015 for ( Int_t i = ilow ; i < ilow + ORDER + 1 ; i++ )
1017 for ( Int_t j = jlow ; j < jlow + ORDER + 1 ; j++ )
1019 save_Br[j-jlow] =
Interpolate( &R3D[klow], &Br3D[i][j][klow], ORDER, r ) ;
1020 save_Bz[j-jlow] =
Interpolate( &R3D[klow], &Bz3D[i][j][klow], ORDER, r ) ;
1021 save_Bphi[j-jlow] =
Interpolate( &R3D[klow], &Bphi3D[i][j][klow], ORDER, r ) ;
1023 saved_Br[i-ilow] =
Interpolate( &Z3D[jlow], save_Br, ORDER, z ) ;
1024 saved_Bz[i-ilow] =
Interpolate( &Z3D[jlow], save_Bz, ORDER, z ) ;
1025 saved_Bphi[i-ilow] =
Interpolate( &Z3D[jlow], save_Bphi, ORDER, z ) ;
1027 Br_value = fscale *
Interpolate( &Phi3D[ilow], saved_Br, ORDER, phi ) ;
1028 Bz_value = fscale *
Interpolate( &Phi3D[ilow], saved_Bz, ORDER, phi ) ;
1029 Bphi_value = fscale *
Interpolate( &Phi3D[ilow], saved_Bphi, ORDER, phi ) ;
1046 Float_t &Br_value, Float_t &Bz_value, Float_t &Bphi_value )
1054 fscale = 0.001*fFactor;
1056 const Int_t ORDER = 1 ;
1057 static Int_t ilow=0, jlow=0, klow=0 ;
1058 Float_t save_Br[ORDER+1], saved_Br[ORDER+1] ;
1059 Float_t save_Bz[ORDER+1], saved_Bz[ORDER+1] ;
1060 Float_t save_Bphi[ORDER+1], saved_Bphi[ORDER+1] ;
1063 Search( nPhiSteel, Phi3DSteel, phi, ilow ) ;
1064 Search( nZSteel, Z3DSteel, z, jlow ) ;
1065 Search( nRSteel, R3DSteel, r, klow ) ;
1066 if ( ilow < 0 ) ilow = 0 ;
1067 if ( jlow < 0 ) jlow = 0 ;
1068 if ( klow < 0 ) klow = 0 ;
1070 if ( ilow + ORDER >= nPhiSteel - 1 ) ilow = nPhiSteel - 1 - ORDER ;
1071 if ( jlow + ORDER >= nZSteel - 1 ) jlow = nZSteel - 1 - ORDER ;
1072 if ( klow + ORDER >= nRSteel - 1 ) klow = nRSteel - 1 - ORDER ;
1074 for ( Int_t i = ilow ; i < ilow + ORDER + 1 ; i++ )
1076 for ( Int_t j = jlow ; j < jlow + ORDER + 1 ; j++ )
1078 save_Br[j-jlow] =
Interpolate( &R3DSteel[klow], &Br3DSteel[i][j][klow], ORDER, r ) ;
1079 save_Bz[j-jlow] =
Interpolate( &R3DSteel[klow], &Bz3DSteel[i][j][klow], ORDER, r ) ;
1080 save_Bphi[j-jlow] =
Interpolate( &R3DSteel[klow], &Bphi3DSteel[i][j][klow], ORDER, r ) ;
1082 saved_Br[i-ilow] =
Interpolate( &Z3DSteel[jlow], save_Br, ORDER, z ) ;
1083 saved_Bz[i-ilow] =
Interpolate( &Z3DSteel[jlow], save_Bz, ORDER, z ) ;
1084 saved_Bphi[i-ilow] =
Interpolate( &Z3DSteel[jlow], save_Bphi, ORDER, z ) ;
1086 Br_value = fscale *
Interpolate( &Phi3DSteel[ilow], saved_Br, ORDER, phi ) ;
1087 Bz_value = fscale *
Interpolate( &Phi3DSteel[ilow], saved_Bz, ORDER, phi ) ;
1088 Bphi_value = fscale *
Interpolate( &Phi3DSteel[ilow], saved_Bphi, ORDER, phi ) ;
1102 void StarMagField::Interpolate2DEdistortion(
const Float_t r,
const Float_t z,
1103 const Float_t Er[neZ][neR], Float_t &Er_value )
1107 const Int_t ORDER = 1 ;
1108 static Int_t jlow=0, klow=0 ;
1109 Float_t save_Er[ORDER+1] ;
1111 Search( neZ, eZList, z, jlow ) ;
1112 Search( neR, eRadius, r, klow ) ;
1113 if ( jlow < 0 ) jlow = 0 ;
1114 if ( klow < 0 ) klow = 0 ;
1115 if ( jlow + ORDER >= neZ - 1 ) jlow = neZ - 1 - ORDER ;
1116 if ( klow + ORDER >= neR - 1 ) klow = neR - 1 - ORDER ;
1118 for ( Int_t j = jlow ; j < jlow + ORDER + 1 ; j++ )
1120 save_Er[j-jlow] =
Interpolate( &eRadius[klow], &Er[j][klow], ORDER, r ) ;
1122 Er_value =
Interpolate( &eZList[jlow], save_Er, ORDER, z ) ;
1128 void StarMagField::Interpolate3DEdistortion(
const Float_t r,
const Float_t phi,
const Float_t z,
1129 const Float_t Er[neZ][nePhi][neR],
const Float_t Ephi[neZ][nePhi][neR],
1130 Float_t &Er_value, Float_t &Ephi_value )
1134 const Int_t ORDER = 1 ;
1135 static Int_t ilow=0, jlow=0, klow=0 ;
1136 Float_t save_Er[ORDER+1], saved_Er[ORDER+1] ;
1137 Float_t save_Ephi[ORDER+1], saved_Ephi[ORDER+1] ;
1139 Search( neZ, eZList, z, ilow ) ;
1140 Search( nePhi, ePhiList, phi, jlow ) ;
1141 Search( neR, eRadius, r, klow ) ;
1142 if ( ilow < 0 ) ilow = 0 ;
1143 if ( jlow < 0 ) jlow = 0 ;
1144 if ( klow < 0 ) klow = 0 ;
1146 if ( ilow + ORDER >= neZ - 1 ) ilow = neZ - 1 - ORDER ;
1147 if ( jlow + ORDER >= nePhi - 1 ) jlow = nePhi - 1 - ORDER ;
1148 if ( klow + ORDER >= neR - 1 ) klow = neR - 1 - ORDER ;
1150 for ( Int_t i = ilow ; i < ilow + ORDER + 1 ; i++ )
1152 for ( Int_t j = jlow ; j < jlow + ORDER + 1 ; j++ )
1154 save_Er[j-jlow] =
Interpolate( &eRadius[klow], &Er[i][j][klow], ORDER, r ) ;
1155 save_Ephi[j-jlow] =
Interpolate( &eRadius[klow], &Ephi[i][j][klow], ORDER, r ) ;
1157 saved_Er[i-ilow] =
Interpolate( &ePhiList[jlow], save_Er, ORDER, phi ) ;
1158 saved_Ephi[i-ilow] =
Interpolate( &ePhiList[jlow], save_Ephi, ORDER, phi ) ;
1160 Er_value =
Interpolate( &eZList[ilow], saved_Er, ORDER, z ) ;
1161 Ephi_value =
Interpolate( &eZList[ilow], saved_Ephi, ORDER, z ) ;
1171 const Int_t ORDER,
const Float_t x )
1181 y = (x-Xarray[1]) * (x-Xarray[2]) * Yarray[0] / ( (Xarray[0]-Xarray[1]) * (Xarray[0]-Xarray[2]) ) ;
1182 y += (x-Xarray[2]) * (x-Xarray[0]) * Yarray[1] / ( (Xarray[1]-Xarray[2]) * (Xarray[1]-Xarray[0]) ) ;
1183 y += (x-Xarray[0]) * (x-Xarray[1]) * Yarray[2] / ( (Xarray[2]-Xarray[0]) * (Xarray[2]-Xarray[1]) ) ;
1190 y = Yarray[0] + ( Yarray[1]-Yarray[0] ) * ( x-Xarray[0] ) / ( Xarray[1] - Xarray[0] ) ;
1205 assert(! TMath::IsNaN(x));
1206 Long_t middle, high ;
1207 Int_t ascend = 0, increment = 1 ;
1209 if ( Xarray[N-1] >= Xarray[0] ) ascend = 1 ;
1211 if ( low < 0 || low > N-1 ) { low = -1 ; high = N ; }
1215 if ( (Int_t)( x >= Xarray[low] ) == ascend )
1217 if ( low == N-1 ) return ;
1219 while ( (Int_t)( x >= Xarray[high] ) == ascend )
1223 high = low + increment ;
1224 if ( high > N-1 ) { high = N ; break ; }
1229 if ( low == 0 ) { low = -1 ; return ; }
1231 while ( (Int_t)( x < Xarray[low] ) == ascend )
1235 if ( increment >= high ) { low = -1 ; break ; }
1236 else low = high - increment ;
1241 while ( (high-low) != 1 )
1243 middle = ( high + low ) / 2 ;
1244 if ( (Int_t)( x >= Xarray[middle] ) == ascend )
1250 if ( x == Xarray[N-1] ) low = N-2 ;
1251 if ( x == Xarray[0] ) low = 0 ;
1256 void StarMagField::Set ## A (Float_t m) { \
1257 if (!fLock) f ## A = m; \
1258 else printf("StarMagField::Set"#A"() "#A" is locked at %f; Set to %f is ignored\n", f ## A ,m); \
1268 void StarMagField::SetLock () {
1271 printf(
"StarMagField::SetLock lock StarMagField parameters\n");
1276 #define PrintPar(A) printf("StarMagField:: "#A"\t%f\n",f ## A)
1277 void StarMagField::Print (Option_t*)
const {
1278 if (fLock) printf(
"StarMagField parameters are locked\n");
1279 printf(
"StarMagField:: Map\t%i\n",fMap );
virtual void Interpolate3DBSteelfield(const Float_t r, const Float_t z, const Float_t phi, Float_t &Br_value, Float_t &Bz_value, Float_t &Bphi_value)
Interpolate the B field map - 3D interpolation.
virtual void Interpolate2DBfield(const Float_t r, const Float_t z, Float_t &Br_value, Float_t &Bz_value)
Interpolate the B field map - 2D interpolation.
virtual void B3DField(const Float_t x[], Float_t B[])
Bfield in Cartesian coordinates - 3D field.
static void Search(Int_t N, const Float_t Xarray[], Float_t x, Int_t &low)
Search an ordered table by starting at the most recently used point.
virtual Float_t Interpolate(const Float_t Xarray[], const Float_t Yarray[], const Int_t ORDER, const Float_t x)
Interpolate a 3x2 table (quadratic) or a 2x2 table (linear)
virtual void Interpolate3DBfield(const Float_t r, const Float_t z, const Float_t phi, Float_t &Br_value, Float_t &Bz_value, Float_t &Bphi_value)
Interpolate the B field map - 3D interpolation.
virtual void BrBzField(const Float_t r, const Float_t z, Float_t &Br_value, Float_t &Bz_value)
B field in Radial coordinates - 2D field (ie Phi symmetric)