6 #include "ERFieldMap.h" 8 #include "ERFieldPar.h" 13 #include "TGeoManager.h" 51 fLocalMagFieldNode(NULL),
52 fLocalMagFieldVolName(
"")
56 for (Int_t i=0; i < 2 ; i++) {
58 for (Int_t j=0; j < 2 ; j++) {
60 for (Int_t k=0; k < 2 ; k++) {
99 fLocalMagFieldVolName(
"")
103 for (Int_t i=0; i < 2 ; i++) {
105 for (Int_t j=0; j < 2 ; j++) {
107 for (Int_t k=0; k < 2 ; k++) {
116 fTitle =
"ERFieldMap";
117 TString dir = getenv(
"VMCWORKDIR");
119 if ( fileType[0] ==
'R' ) {
154 fLocalMagFieldVolName(
"")
158 for (Int_t i=0; i < 2 ; i++) {
160 for (Int_t j=0; j < 2 ; j++) {
162 for (Int_t k=0; k < 2 ; k++) {
173 cerr <<
"-W- ERFieldConst::ERFieldMap: empty parameter container!" 177 fieldPar->MapName(fName);
178 fPosX = fieldPar->GetPositionX();
179 fPosY = fieldPar->GetPositionY();
180 fPosZ = fieldPar->GetPositionZ();
181 fScale = fieldPar->GetScale();
182 TString dir = getenv(
"VMCWORKDIR");
183 fFileName = dir +
"/input/" + fName +
".root";
191 if ( fBy )
delete fBy;
192 if ( fBz )
delete fBz;
197 if (fLocalMagFieldVolName.Length() != 0) {
198 if ( ! gGeoManager ) {
199 std::cerr <<
"ERFieldMap: cannot initialise without TGeoManager!"<< std::endl;
201 gGeoManager->CdTop();
202 TGeoNode* cave = gGeoManager->GetCurrentNode();
203 TGeoNode* localMagField = NULL;
204 for (Int_t iNode = 0; iNode < cave->GetNdaughters(); iNode++) {
205 TString name = cave->GetDaughter(iNode)->GetName();
206 if ( name.Contains(fLocalMagFieldVolName, TString::kIgnoreCase) ) {
207 localMagField = cave->GetDaughter(iNode);
216 cerr <<
"-E- ERFieldMap::Init: No proper file name defined! (" 218 Fatal(
"Init",
"No proper file name");
222 Double_t originX = 0;
223 Double_t originY = 0;
224 Double_t originZ = 0;
234 fByOrigin = GetBy(originX, originY, originZ);
235 fBzOrigin = GetBz(originX, originY, originZ);
247 Double_t masterCoord[3];
248 Double_t masterVecB[3];
249 Double_t localCoord[3];
251 localCoord[0] = masterCoord[0] = x;
252 localCoord[1] = masterCoord[1] = y;
253 localCoord[2] = masterCoord[2] = z;
257 if (
IsInside(localCoord[0], localCoord[1], localCoord[2], ix, iy, iz, dx, dy, dz) ) {
259 fHa[0][0][0] =
fBx->At(ix *fNy*fNz + iy *fNz + iz);
260 fHa[1][0][0] =
fBx->At((ix+1)*fNy*fNz + iy *fNz + iz);
261 fHa[0][1][0] =
fBx->At(ix *fNy*fNz + (iy+1)*fNz + iz);
262 fHa[1][1][0] =
fBx->At((ix+1)*fNy*fNz + (iy+1)*fNz + iz);
263 fHa[0][0][1] =
fBx->At(ix *fNy*fNz + iy *fNz + (iz+1));
264 fHa[1][0][1] =
fBx->At((ix+1)*fNy*fNz + iy *fNz + (iz+1));
265 fHa[0][1][1] =
fBx->At(ix *fNy*fNz + (iy+1)*fNz + (iz+1));
266 fHa[1][1][1] =
fBx->At((ix+1)*fNy*fNz + (iy+1)*fNz + (iz+1));
268 Double_t interpolatedCoord[3];
269 interpolatedCoord[0] = masterVecB[0] =
Interpolate(dx, dy, dz);
270 interpolatedCoord[1] = 0;
271 interpolatedCoord[2] = 0;
275 return masterVecB[0];
281 Double_t ERFieldMap::GetBy(Double_t x, Double_t y, Double_t z) {
288 Double_t masterCoord[3];
289 Double_t masterVecB[3];
290 Double_t localCoord[3];
292 localCoord[0] = masterCoord[0] = x;
293 localCoord[1] = masterCoord[1] = y;
294 localCoord[2] = masterCoord[2] = z;
298 if (
IsInside(localCoord[0], localCoord[1], localCoord[2], ix, iy, iz, dx, dy, dz) ) {
300 fHa[0][0][0] = fBy->At(ix *fNy*fNz + iy *fNz + iz);
301 fHa[1][0][0] = fBy->At((ix+1)*fNy*fNz + iy *fNz + iz);
302 fHa[0][1][0] = fBy->At(ix *fNy*fNz + (iy+1)*fNz + iz);
303 fHa[1][1][0] = fBy->At((ix+1)*fNy*fNz + (iy+1)*fNz + iz);
304 fHa[0][0][1] = fBy->At(ix *fNy*fNz + iy *fNz + (iz+1));
305 fHa[1][0][1] = fBy->At((ix+1)*fNy*fNz + iy *fNz + (iz+1));
306 fHa[0][1][1] = fBy->At(ix *fNy*fNz + (iy+1)*fNz + (iz+1));
307 fHa[1][1][1] = fBy->At((ix+1)*fNy*fNz + (iy+1)*fNz + (iz+1));
309 Double_t interpolatedCoord[3];
310 interpolatedCoord[0] = 0;
311 interpolatedCoord[1] = masterVecB[1] =
Interpolate(dx, dy, dz);
312 interpolatedCoord[2] = 0;
316 return masterVecB[1];
322 Double_t ERFieldMap::GetBz(Double_t x, Double_t y, Double_t z) {
329 Double_t masterCoord[3];
330 Double_t masterVecB[3];
331 Double_t localCoord[3];
333 localCoord[0] = masterCoord[0] = x;
334 localCoord[1] = masterCoord[1] = y;
335 localCoord[2] = masterCoord[2] = z;
339 if (
IsInside(localCoord[0], localCoord[1], localCoord[2], ix, iy, iz, dx, dy, dz) ) {
341 fHa[0][0][0] = fBz->At(ix *fNy*fNz + iy *fNz + iz);
342 fHa[1][0][0] = fBz->At((ix+1)*fNy*fNz + iy *fNz + iz);
343 fHa[0][1][0] = fBz->At(ix *fNy*fNz + (iy+1)*fNz + iz);
344 fHa[1][1][0] = fBz->At((ix+1)*fNy*fNz + (iy+1)*fNz + iz);
345 fHa[0][0][1] = fBz->At(ix *fNy*fNz + iy *fNz + (iz+1));
346 fHa[1][0][1] = fBz->At((ix+1)*fNy*fNz + iy *fNz + (iz+1));
347 fHa[0][1][1] = fBz->At(ix *fNy*fNz + (iy+1)*fNz + (iz+1));
348 fHa[1][1][1] = fBz->At((ix+1)*fNy*fNz + (iy+1)*fNz + (iz+1));
350 Double_t interpolatedCoord[3];
351 interpolatedCoord[0] = 0;
352 interpolatedCoord[1] = 0;
353 interpolatedCoord[2] = masterVecB[2] =
Interpolate(dx, dy, dz);
357 return masterVecB[2];
364 Int_t& ix, Int_t& iy, Int_t& iz,
365 Double_t& dx, Double_t& dy, Double_t& dz) {
371 if ( ! ( xl >=
fXmin && xl < fXmax && yl >= fYmin && yl < fYmax &&
372 zl >= fZmin && zl < fZmax ) ) {
379 ix = Int_t( (xl-
fXmin) / fXstep );
380 iy = Int_t( (yl-fYmin) / fYstep );
381 iz = Int_t( (zl-fZmin) / fZstep );
383 dx = (xl-
fXmin) / fXstep - Double_t(ix);
384 dy = (yl-fYmin) / fYstep - Double_t(iy);
385 dz = (zl-fZmin) / fZstep - Double_t(iz);
392 cout <<
"-I- ERFieldMap: Writing field map to ASCII file " 394 std::ofstream mapFile(fileName);
395 if ( ! mapFile.is_open() ) {
396 cerr <<
"-E- ERFieldMap:ReadAsciiFile: Could not open file! " << endl;
400 mapFile.precision(6);
401 mapFile << showpoint;
402 if ( fType == 1 ) mapFile <<
"nosym" << endl;
403 if ( fType == 2 ) mapFile <<
"sym2" << endl;
404 if ( fType == 3 ) mapFile <<
"sym3" << endl;
405 mapFile <<
fXmin <<
" " << fXmax <<
" " <<
fNx << endl;
406 mapFile << fYmin <<
" " << fYmax <<
" " << fNy << endl;
407 mapFile << fZmin <<
" " << fZmax <<
" " << fNz << endl;
409 Double_t factor = 10. *
fScale;
411 Int_t nTot =
fNx * fNy * fNz;
412 cout <<
"-I- ERFieldMap: " <<
fNx*fNy*fNz <<
" entries to write... " 413 << setw(3) << 0 <<
" % ";
416 Int_t iDiv = TMath::Nint(nTot/100.);
417 for(Int_t ix=0; ix<
fNx; ix++) {
418 for(Int_t iy=0; iy<fNy; iy++) {
419 for(Int_t iz=0; iz<fNz; iz++) {
420 index =ix*fNy*fNz + iy*fNz + iz;
421 modul = div(index,iDiv);
422 if ( modul.rem == 0 ) {
423 Double_t perc = TMath::Nint(100.*index/nTot);
424 cout <<
"\b\b\b\b\b\b" << setw(3) << perc <<
" % " << flush;
426 mapFile <<
fBx->At(index)/factor <<
" " << fBy->At(index)/factor
427 <<
" " << fBz->At(index)/factor << endl;
431 cout <<
" " << index+1 <<
" written" << endl;
437 const char* mapName) {
457 TString type =
"Map";
458 if ( fType == 2 ) type =
"Map sym2";
459 if ( fType == 3 ) type =
"Map sym3";
460 cout <<
"======================================================" << endl;
463 cout <<
"---- " << fTitle <<
" : " << fName << endl;
464 cout <<
"----" << endl;
465 cout <<
"---- Field type : " << type << endl;
466 cout <<
"----" << endl;
467 cout <<
"---- Field map grid : " << endl;
468 cout <<
"---- x = " << setw(4) <<
fXmin <<
" to " << setw(4) << fXmax
469 <<
" cm, " <<
fNx <<
" grid points, dx = " << fXstep <<
" cm" << endl;
470 cout <<
"---- y = " << setw(4) << fYmin <<
" to " << setw(4) << fYmax
471 <<
" cm, " << fNy <<
" grid points, dy = " << fYstep <<
" cm" << endl;
472 cout <<
"---- z = " << setw(4) << fZmin <<
" to " << setw(4) << fZmax
473 <<
" cm, " << fNz <<
" grid points, dz = " << fZstep <<
" cm" << endl;
475 cout <<
"---- Field centre position: ( " << setw(6) <<
fPosX <<
", " 476 << setw(6) << fPosY <<
", " << setw(6) << fPosZ <<
") cm" << endl;
477 cout <<
"---- Field scaling factor: " <<
fScale << endl;
478 cout <<
"----" << endl;
479 cout <<
"---- Field at origin is ( " << setw(6) <<
fBxOrigin <<
", " << setw(6)
481 cout <<
"======================================================" << endl;
486 fPosX = fPosY = fPosZ = 0.;
487 fXmin = fYmin = fZmin = 0.;
488 fXmax = fYmax = fZmax = 0.;
489 fXstep = fYstep = fZstep = 0.;
493 if ( fBy ) {
delete fBy; fBy = NULL; }
494 if ( fBz ) {
delete fBz; fBz = NULL; }
499 Double_t bx=0., by=0., bz=0.;
500 Double_t localVecB[3];
501 Double_t masterVecB[3];
502 Double_t localCoord[3];
503 Double_t masterCoord[3];
505 LOG(INFO) <<
"ERFieldMap: Reading field map from ASCII file " 506 << fileName << FairLogger::endl;
507 std::ifstream mapFile(fileName);
508 if ( ! mapFile.is_open() ) {
509 LOG(ERROR) <<
"ERFieldMap:ReadAsciiFile: Could not open file!" << FairLogger::endl;
510 LOG(FATAL) <<
"ERFieldMap:ReadAsciiFile: Could not open file!" << FairLogger::endl;
516 if ( type ==
"nosym" ) iType = 1;
517 if ( type ==
"sym2" ) iType = 2;
518 if ( type ==
"sym3" ) iType = 3;
519 if ( fType != iType ) {
520 cout <<
"-E- ERFieldMap::ReadAsciiFile: Incompatible map types!" 522 cout <<
" Field map is of type " << fType
523 <<
" but map on file is of type " << iType << endl;
524 Fatal(
"ReadAsciiFile",
"Incompatible map types");
528 mapFile >> fYmin >> fYmax >> fNy;
529 mapFile >> fZmin >> fZmax >> fNz;
531 fXstep = ( fXmax -
fXmin ) / Double_t( fNx - 1 );
532 fYstep = ( fYmax - fYmin ) / Double_t( fNy - 1 );
533 fZstep = ( fZmax - fZmin ) / Double_t( fNz - 1 );
536 fBx =
new TArrayF(fNx * fNy * fNz);
537 fBy =
new TArrayF(fNx * fNy * fNz);
538 fBz =
new TArrayF(fNx * fNy * fNz);
540 Double_t factor =
fScale * 10.;
542 Int_t nTot = fNx * fNy * fNz;
543 cout <<
"-I- ERFieldMap: " << nTot <<
" entries to read... " 544 << setw(3) << 0 <<
" % ";
547 Int_t iDiv = TMath::Nint(nTot/100.);
550 for (Int_t ix=0; ix<
fNx; ix++) {
551 for (Int_t iy = 0; iy<fNy; iy++) {
552 for (Int_t iz = 0; iz<fNz; iz++) {
553 if (! mapFile.good()) cerr <<
"-E- ERFieldMap::ReadAsciiFile: " 554 <<
"I/O Error at " << ix <<
" " 555 << iy <<
" " << iz << endl;
556 index = ix*fNy*fNz + iy*fNz + iz;
564 mapFile >> bx >> by >> bz;
566 fBx->AddAt(factor*bx, index);
567 fBy->AddAt(factor*by, index);
568 fBz->AddAt(factor*bz, index);
569 if ( mapFile.eof() ) {
570 cerr << endl <<
"-E- ERFieldMap::ReadAsciiFile: EOF" 571 <<
" reached at " << ix <<
" " << iy <<
" " << iz << endl;
578 cout <<
" " << index+1 <<
" read" << endl;
584 const char* mapName) {
616 fHb[0][0] =
fHa[0][0][0] + (
fHa[1][0][0]-
fHa[0][0][0] ) * dx;
617 fHb[1][0] =
fHa[0][1][0] + (
fHa[1][1][0]-
fHa[0][1][0] ) * dx;
618 fHb[0][1] =
fHa[0][0][1] + (
fHa[1][0][1]-
fHa[0][0][1] ) * dx;
619 fHb[1][1] =
fHa[0][1][1] + (
fHa[1][1][1]-
fHa[0][1][1] ) * dx;
621 fHc[0] = fHb[0][0] + ( fHb[1][0] - fHb[0][0] ) * dy;
622 fHc[1] = fHb[0][1] + ( fHb[1][1] - fHb[0][1] ) * dy;
624 return fHc[0] + ( fHc[1] - fHc[0] ) * dz;
virtual Bool_t IsInside(Double_t x, Double_t y, Double_t z, Int_t &ix, Int_t &iy, Int_t &iz, Double_t &dx, Double_t &dy, Double_t &dz)
virtual void SetPosition(Double_t x, Double_t y, Double_t z)
void ReadAsciiFile(const char *fileName)
TGeoNode * fLocalMagFieldNode
z-component of the field at the origin
Double_t fHb[2][2]
Field at corners of a grid cell.
Double_t fBzOrigin
y-component of the field at the origin
Double_t fHc[2]
Interpolated field (2-dim)
Double_t fBxOrigin
Interpolated field (1-dim)
void WriteRootFile(const char *fileName, const char *mapName)
void ReadRootFile(const char *fileName, const char *mapName)
void WriteAsciiFile(const char *fileName)
Double_t Interpolate(Double_t dx, Double_t dy, Double_t dz)
Double_t fByOrigin
x-component of the field at the origin
virtual void Print(Option_t *="") const