18#include "TGeoManager.h"
19#include "TGeoChecker.h"
20#include "TGeoPhysicalNode.h"
21#include "TGeoUniformMagField.h"
22#include "TGeoMatrix.h"
24#include "TGeoVolume.h"
25#include "TVirtualMC.h"
38 TG4VUserPostDetConstruction(),
78 if (inputFile.size() < 1) {
79 std::cerr<<
"Skipping ShipFieldMaker::readInputFile(): file name is empty"<<std::endl;
83 std::string fullFileName = getenv(
"VMCWORKDIR");
84 fullFileName +=
"/"; fullFileName += inputFile.c_str();
86 std::cout<<
"ShipFieldMaker::makeFields inputFile = "<<fullFileName<<std::endl;
88 std::ifstream getData(fullFileName);
89 std::string whiteSpace(
" ");
92 while (getData.good()) {
94 if (getData.peek() ==
'\n') {
101 if (getData.eof()) {
break;}
103 }
else if (getData.peek() ==
'#') {
106 getData.ignore(1000,
'\n');
107 getData.putback(
'\n');
110 if (getData.eof()) {
break;}
115 std::string line(
"");
116 std::getline(getData, line);
119 if (getData.eof()) {
break;}
122 std::vector<std::string> lineVect = this->
splitString(line, whiteSpace);
124 size_t nWords = lineVect.size();
129 TString keyWord(lineVect[0].c_str());
132 if (!keyWord.CompareTo(
"uniform")) {
137 }
else if (!keyWord.CompareTo(
"constant")) {
142 }
else if (!keyWord.CompareTo(
"bell")) {
147 }
else if (!keyWord.CompareTo(
"fieldmap")) {
152 }
else if (!keyWord.CompareTo(
"symfieldmap")) {
157 }
else if (!keyWord.CompareTo(
"copymap")) {
162 }
else if (!keyWord.CompareTo(
"composite")) {
167 }
else if (!keyWord.CompareTo(
"global")) {
172 }
else if (!keyWord.CompareTo(
"region")) {
177 }
else if (!keyWord.CompareTo(
"local")) {
197 size_t nWords = inputLine.size();
204 const TString name(inputLine[1].c_str());
206 Double_t Bx = std::atof(inputLine[2].c_str());
207 Double_t By = std::atof(inputLine[3].c_str());
208 Double_t Bz = std::atof(inputLine[4].c_str());
209 const TVector3 BVector(Bx, By, Bz);
215 std::cout<<
"Expecting 5 words for the definition of the uniform field: "
216 <<
"Uniform Name Bx By Bz"<<std::endl;
228 if (
verbose_) {std::cout<<
"Creating uniform field for "<<name.Data()<<std::endl;}
230 Double_t Bx = BVector.X()*
Tesla_;
231 Double_t By = BVector.Y()*
Tesla_;
232 Double_t Bz = BVector.Z()*
Tesla_;
234 TGeoUniformMagField* uField =
new TGeoUniformMagField(Bx, By, Bz);
240 std::cout<<
"We already have a uniform field with the name "
241 <<name.Data()<<std::endl;
250 size_t nWords = inputLine.size();
257 TString name(inputLine[1].c_str());
259 Double_t xMin = std::atof(inputLine[2].c_str());
260 Double_t xMax = std::atof(inputLine[3].c_str());
262 Double_t yMin = std::atof(inputLine[4].c_str());
263 Double_t yMax = std::atof(inputLine[5].c_str());
265 Double_t zMin = std::atof(inputLine[6].c_str());
266 Double_t zMax = std::atof(inputLine[7].c_str());
269 Double_t Bx = std::atof(inputLine[8].c_str());
270 Double_t By = std::atof(inputLine[9].c_str());
271 Double_t Bz = std::atof(inputLine[10].c_str());
273 const TVector2 xRange(xMin, xMax);
274 const TVector2 yRange(yMin, yMax);
275 const TVector2 zRange(zMin, zMax);
276 const TVector3 BVector(Bx, By, Bz);
282 std::cout<<
"Expecting 11 words for the definition of the constant field: "
283 <<
"Constant Name xMin xMax yMin yMax zMin zMax Bx By Bz"<<std::endl;
290 const TVector2& zRange,
const TVector3& BVector)
296 Double_t xMin = xRange.X();
297 Double_t xMax = xRange.Y();
298 Double_t yMin = yRange.X();
299 Double_t yMax = yRange.Y();
300 Double_t zMin = zRange.X();
301 Double_t zMax = zRange.Y();
303 Double_t Bx = BVector.X()*
Tesla_;
304 Double_t By = BVector.Y()*
Tesla_;
305 Double_t Bz = BVector.Z()*
Tesla_;
308 zMin, zMax, Bx, By, Bz);
314 std::cout<<
"We already have a constant field with the name "
315 <<name.Data()<<std::endl;
323 size_t nWords = inputLine.size();
328 if (nWords == 6 || nWords == 9) {
330 TString name(inputLine[1].c_str());
332 Double_t BPeak = std::atof(inputLine[2].c_str());
333 Double_t zMiddle = std::atof(inputLine[3].c_str());
335 Int_t orient = std::atoi(inputLine[4].c_str());
336 Double_t tubeR = std::atof(inputLine[5].c_str());
338 Double_t xy(0.0), z(0.0), L(0.0);
342 xy = std::atof(inputLine[6].c_str());
343 z = std::atof(inputLine[7].c_str());
344 L = std::atof(inputLine[8].c_str());
347 this->
defineBell(name, BPeak, zMiddle, orient, tubeR, xy, z, L);
351 std::cout<<
"Expecting 6 or 9 words for the definition of the Bell field: "
352 <<
"Bell Name BPeak zMiddle orientationInt tubeRadius [targetXY targetZ0 targetL]"<<std::endl;
359 Int_t orient, Double_t tubeR, Double_t xy, Double_t z, Double_t L)
376 std::cout<<
"We already have a Bell field with the name "
377 <<name.Data()<<std::endl;
386 size_t nWords = inputLine.size();
391 if (nWords == 3 || nWords == 6 || nWords == 9) {
393 const TString name(inputLine[1].c_str());
394 const TString mapFileName(inputLine[2].c_str());
396 Double_t x0(0.0), y0(0.0), z0(0.0);
397 Double_t phi(0.0), theta(0.0), psi(0.0);
400 x0 = std::atof(inputLine[3].c_str());
401 y0 = std::atof(inputLine[4].c_str());
402 z0 = std::atof(inputLine[5].c_str());
406 phi = std::atof(inputLine[6].c_str());
407 theta = std::atof(inputLine[7].c_str());
408 psi = std::atof(inputLine[8].c_str());
411 const TVector3 localCentre(x0, y0, z0);
412 const TVector3 localAngles(phi, theta, psi);
414 this->
defineFieldMap(name, mapFileName, localCentre, localAngles, useSymmetry);
418 std::cout<<
"Expecting 3, 6 or 9 words for the definition of the field map: "
419 <<
"(Sym)FieldMap Name mapFileName [x0 y0 z0] [[phi theta psi]]"<<std::endl;
425 const TVector3& localCentre,
const TVector3& localAngles,
432 std::string fullFileName = getenv(
"VMCWORKDIR");
433 fullFileName +=
"/"; fullFileName += mapFileName.Data();
437 std::cout<<
"Creating symmetric field map called "<<name.Data()<<
" using "<<fullFileName<<std::endl;
439 std::cout<<
"Creating field map called "<<name.Data()<<
" using "<<fullFileName<<std::endl;
445 Float_t x0 = localCentre.X();
446 Float_t y0 = localCentre.Y();
447 Float_t z0 = localCentre.Z();
449 Float_t phi = localAngles.X();
450 Float_t theta = localAngles.Y();
451 Float_t psi = localAngles.Z();
456 phi, theta, psi, scale, useSymmetry);
462 std::cout<<
"We already have a field map with the name "
463 <<name.Data()<<std::endl;
475 size_t nWords = inputLine.size();
480 if (nWords == 6 || nWords == 9) {
482 const TString name(inputLine[1].c_str());
485 const TString mapNameToCopy(inputLine[2].c_str());
487 Double_t x0 = std::atof(inputLine[3].c_str());
488 Double_t y0 = std::atof(inputLine[4].c_str());
489 Double_t z0 = std::atof(inputLine[5].c_str());
491 Double_t phi(0.0), theta(0.0), psi(0.0), scale(1.0);
494 phi = std::atof(inputLine[6].c_str());
495 theta = std::atof(inputLine[7].c_str());
496 psi = std::atof(inputLine[8].c_str());
499 const TVector3 translation(x0, y0, z0);
500 const TVector3 eulerAngles(phi, theta, psi);
506 std::cout<<
"Expecting 6 or 9 words for the copy of a field map: "
507 <<
"CopyMap Name MapNameToCopy x0 y0 z0 [phi theta psi]"<<std::endl;
514 const TVector3& translation,
const TVector3& eulerAngles)
526 std::cout<<
"Creating map field copy "<<name.Data()
527 <<
" based on "<<mapNameToCopy.Data()<<std::endl;
532 Float_t x0 = translation.X();
533 Float_t y0 = translation.Y();
534 Float_t z0 = translation.Z();
536 Float_t phi = eulerAngles.X();
537 Float_t theta = eulerAngles.Y();
538 Float_t psi = eulerAngles.Z();
543 x0, y0, z0, phi, theta, psi, scale);
550 std::cout<<
"We already have a copied field map with the name "
551 <<name.Data()<<std::endl;
560 size_t nWords = inputLine.size();
567 TString name(inputLine[1].c_str());
569 std::vector<TString> fieldNames;
570 for (
size_t i = 2; i < nWords; i++) {
572 TString aName(inputLine[i].c_str());
573 fieldNames.push_back(aName);
581 std::cout<<
"Expecting at least 3 words for the composite definition: "
582 <<
"Composite Name Field1 Field2 ... FieldN"<<std::endl;
589 const TString& field2Name,
const TString& field3Name,
590 const TString& field4Name)
593 std::vector<TString> fieldNames;
594 fieldNames.push_back(field1Name);
595 fieldNames.push_back(field2Name);
597 if (field3Name.Length() > 0) {
598 fieldNames.push_back(field3Name);
600 if (field4Name.Length() > 0) {
601 fieldNames.push_back(field4Name);
615 std::vector<TVirtualMagField*> vectFields;
617 std::vector<TString>::iterator iter;
618 for (iter = fieldNames.begin(); iter != fieldNames.end(); ++iter) {
620 TString aName = *iter;
621 TVirtualMagField* aField = this->
getField(aName);
623 if (
verbose_) {std::cout<<
"Adding field "<<aName<<std::endl;}
624 vectFields.push_back(aField);
634 std::cout<<
"We already have a composite field with the name "
635 <<name.Data()<<std::endl;
645 size_t nWords = inputLine.size();
652 TString name(
"Global");
654 std::vector<TString> fieldNames;
655 for (
size_t i = 1; i < nWords; i++) {
657 TString aName(inputLine[i].c_str());
658 fieldNames.push_back(aName);
666 std::cout<<
"Expecting at least two words for the global field definition: "
667 <<
"Global Field1 ... FieldN"<<std::endl;
674 const TString& field3Name,
const TString& field4Name)
677 std::vector<TString> fieldNames;
678 fieldNames.push_back(field1Name);
680 if (field2Name.Length() > 0) {
681 fieldNames.push_back(field2Name);
683 if (field3Name.Length() > 0) {
684 fieldNames.push_back(field3Name);
686 if (field4Name.Length() > 0) {
687 fieldNames.push_back(field4Name);
699 std::cout<<
"Deleting already existing Global field"<<std::endl;
704 if (
verbose_) {std::cout<<
"Setting the Global field"<<std::endl;}
706 std::vector<TVirtualMagField*> vectFields;
708 std::vector<TString>::iterator iter;
709 for (iter = fieldNames.begin(); iter != fieldNames.end(); ++iter) {
711 TString aName = *iter;
712 TVirtualMagField* aField = this->
getField(aName);
715 if (
verbose_) {std::cout<<
"Adding field "<<aName<<
" to Global"<<std::endl;}
716 vectFields.push_back(aField);
718 std::cout<<
"Could not find the field "<<aName<<std::endl;
723 TString name(
"Global");
730 std::cout<<
"The virtual MC pointer gMC is null! The global field can't be used by Geant4 but will work for track fitting and track extrapolation"<<std::endl;
739 size_t nWords = inputLine.size();
744 if (nWords == 3 || nWords == 4) {
746 TString volName(inputLine[1].c_str());
747 TString fieldName(inputLine[2].c_str());
750 if (nWords == 4) {scale = std::atof(inputLine[3].c_str());}
756 std::cout<<
"Expecting 3 or 4 words for the region (local + global) field definition: "
757 <<
"Region VolName LocalFieldName [LocalFieldMapScale]"<<std::endl;
767 std::cout<<
"ShipFieldMaker::defineRegionField for volume "
768 <<volName.Data()<<
" and field "<<fieldName.Data()
769 <<
" with scale = "<<scale<<std::endl;
772 fieldInfo theInfo(volName, fieldName, scale);
781 std::vector<fieldInfo>::iterator regionIter;
786 const TString volName = theInfo.
volName_;
788 Double_t scale = theInfo.
scale_;
791 TGeoVolume* theVol(0);
792 if (gGeoManager) {theVol = gGeoManager->FindVolumeFast(volName.Data());}
797 TVirtualMagField* localField = this->
getField(fieldName);
807 fieldName = localField->GetName();
812 TString lgName(fieldName); lgName +=
"Global";
813 TVirtualMagField* lgField = this->
getField(lgName);
820 std::cout<<
"Creating the combined field "<<lgName.Data()<<
", with local field "
821 <<fieldName.Data()<<
" with the global field for volume "
822 <<volName.Data()<<std::endl;
827 theVol->SetField(combField);
832 std::cout<<
"Setting the field "<<lgName.Data()
833 <<
" for volume "<<volName.Data()<<std::endl;
835 theVol->SetField(lgField);
842 std::cout<<
"There is no global field defined. Just setting the local field"<<std::endl;
844 theVol->SetField(localField);
850 std::cout<<
"Could not find the local field "<<fieldName.Data()<<std::endl;
857 std::cout<<
"Could not find the volume "<<volName<<std::endl;
869 size_t nWords = inputLine.size();
874 if (nWords == 3 || nWords == 4) {
876 TString volName(inputLine[1].c_str());
877 TString fieldName(inputLine[2].c_str());
880 if (nWords == 4) {scale = std::atof(inputLine[3].c_str());}
886 std::cout<<
"Expecting 3 or 4 words for the local field definition: "
887 <<
"Local VolName LocalFieldName [FieldMapScale]"<<std::endl;
897 std::cout<<
"ShipFieldMaker::defineLocalField for volume "
898 <<volName.Data()<<
" and field "<<fieldName.Data()
899 <<
" with scale = "<<scale<<std::endl;
902 fieldInfo theInfo(volName, fieldName,scale);
911 std::vector<fieldInfo>::iterator localIter;
916 const TString volName = theInfo.
volName_;
918 Double_t scale = theInfo.
scale_;
920 TGeoVolume* theVol(0);
921 if (gGeoManager) {theVol = gGeoManager->FindVolumeFast(volName.Data());}
925 TVirtualMagField* localField = this->
getField(fieldName);
930 theVol->SetField(localField);
933 std::cout<<
"Setting local field "<<localField->GetName()
934 <<
" for volume "<<volName<<std::endl;
939 std::cout<<
"Could not find the field "<<fieldName.Data()<<std::endl;
944 std::cout<<
"Could not find the volume "<<volName.Data()<<std::endl;
964 TString fieldName(mapField->GetName());
965 TString localName(fieldName); localName += volName;
968 std::cout<<
"Checking local field map "<<fieldName
969 <<
" co-ord transformation for volume "<<volName<<std::endl;
975 if (!localMap && volName.Length() > 0) {
978 TString volName1(volName); volName1 +=
"_1";
988 TGeoTranslation origTrans(
"origTrans", origX0, origY0, origZ0);
990 Double_t origPhi = mapField->
GetPhi();
991 Double_t origTheta = mapField->
GetTheta();
992 Double_t origPsi = mapField->
GetPsi();
993 TGeoRotation origRot(
"origRot", origPhi, origTheta, origPsi);
995 TGeoCombiTrans origComb(origTrans, origRot);
997 std::cout<<
"The original field map transformation:"<<std::endl;
1001 TGeoTranslation newTrans(
"newTrans", theInfo.
x0_, theInfo.
y0_, theInfo.
z0_);
1002 TGeoRotation newRot(
"newRot", theInfo.
phi_, theInfo.
theta_, theInfo.
psi_);
1004 TGeoCombiTrans newComb(newTrans, newRot);
1007 std::cout<<
"The volume transformation:"<<std::endl;
1012 newComb = newComb*origComb;
1015 std::cout<<
"The combined transformation:"<<std::endl;
1020 const Double_t* newTransArray = newComb.GetTranslation();
1021 theInfo.
x0_ = newTransArray[0];
1022 theInfo.
y0_ = newTransArray[1];
1023 theInfo.
z0_ = newTransArray[2];
1025 const TGeoRotation* fullRot = newComb.GetRotation();
1033 std::cout<<
"Creating field map copy for "<<localName
1034 <<
" based on "<<mapField->GetName()
1035 <<
": x0 = "<<theInfo.
x0_<<
", y0 = "<<theInfo.
y0_
1036 <<
", z0 = "<<theInfo.
z0_<<
", phi = "<<theInfo.
phi_
1037 <<
", theta = "<<theInfo.
theta_
1038 <<
", psi = "<<theInfo.
psi_<<
", scale = "<<scale
1039 <<
" and symmetry = "<<mapField->
HasSymmetry()<<std::endl;
1051 localField = localMap;
1063 theInfo.
x0_ = 0.0; theInfo.
y0_ = 0.0; theInfo.
z0_ = 0.0;
1066 TGeoMatrix* theMatrix(0);
1068 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
1070 std::cout<<
"Can't find the top volume in ShipFieldMaker::getTransformation"<<std::endl;
1074 if (
verbose_) {std::cout<<
"Finding transformation for "<<volName<<std::endl;}
1079 this->
findNode(topVolume, volName);
1087 const Double_t* theTrans = theMatrix->GetTranslation();
1088 theInfo.
x0_ = theTrans[0];
1089 theInfo.
y0_ = theTrans[1];
1090 theInfo.
z0_ = theTrans[2];
1094 if (theMatrix->IsCombi()) {
1096 TGeoCombiTrans* theCombi =
dynamic_cast<TGeoCombiTrans*
>(theMatrix);
1098 TGeoRotation* combRotn = theCombi->GetRotation();
1104 }
else if (theMatrix->IsRotation()) {
1106 TGeoRotation* theRotn =
dynamic_cast<TGeoRotation*
>(theMatrix);
1124 TObjArray* volNodes = aVolume->GetNodes();
1129 int nNodes = volNodes->GetEntries();
1130 for (
int i = 0; i < nNodes; i++) {
1132 TGeoNode* node =
dynamic_cast<TGeoNode*
>(volNodes->At(i));
1136 const TString nodeName(node->GetName());
1137 if (!nodeName.CompareTo(volName, TString::kExact)) {
1144 }
else if (node->GetNodes()) {
1147 this->
findNode(node->GetVolume(), volName);
1164 TVirtualMagField* theField(0);
1165 TGeoVolume* theVol(0);
1166 if (gGeoManager) {theVol = gGeoManager->FindVolumeFast(volName.Data());}
1170 theField =
dynamic_cast<TVirtualMagField*
>(theVol->GetField());
1180 Bool_t result(kFALSE);
1183 SFMap::const_iterator iter;
1186 TString key = iter->first;
1187 TVirtualMagField* theField = iter->second;
1190 if (!key.CompareTo(name, TString::kExact) && theField) {
1204 TVirtualMagField* theField(0);
1207 SFMap::const_iterator iter;
1210 TString key = iter->first;
1211 TVirtualMagField* BField = iter->second;
1214 if (!key.CompareTo(name, TString::kExact)) {
1226 const std::string& plotFile)
const
1228 this->
plotField(0, xAxis, yAxis, plotFile);
1232 const std::string& plotFile)
const
1234 this->
plotField(1, zAxis, xAxis, plotFile);
1238 const std::string& plotFile)
const
1240 this->
plotField(2, zAxis, yAxis, plotFile);
1244 const std::string& plotFile)
const
1247 std::cout<<
"ShipFieldMaker plotField "<<plotFile<<
": type = "<<type<<std::endl;
1249 Double_t xMin = xAxis(0);
1250 Double_t xMax = xAxis(1);
1251 Double_t dx = xAxis(2);
1253 if (dx > 0.0) {Nx =
static_cast<Int_t
>(((xMax - xMin)/dx) + 0.5);}
1255 Double_t yMin = yAxis(0);
1256 Double_t yMax = yAxis(1);
1257 Double_t dy = yAxis(2);
1259 if (dy > 0.0) {Ny =
static_cast<Int_t
>(((yMax - yMin)/dy) + 0.5);}
1262 const int nhistograms = 4;
1263 const int ncoordinates = 3;
1265 TH2D theHist[nhistograms];
1266 std::string titles[nhistograms] = {
"Bx (T)",
"By (T)",
"Bz (T)",
"B (T)"};
1267 for (
int icomponent = 0; icomponent< nhistograms; icomponent++){
1268 theHist[icomponent] = TH2D(Form(
"theHist[%i]",icomponent), titles[icomponent].data(), Nx, xMin, xMax, Ny, yMin, yMax);
1269 theHist[icomponent].SetDirectory(0);
1272 theHist[icomponent].SetXTitle(
"x (cm)");
1273 theHist[icomponent].SetYTitle(
"y (cm)");
1275 else if (type == 1) {
1277 theHist[icomponent].SetXTitle(
"z (cm)");
1278 theHist[icomponent].SetYTitle(
"x (cm)");
1280 else if (type == 2) {
1282 theHist[icomponent].SetXTitle(
"z (cm)");
1283 theHist[icomponent].SetYTitle(
"y (cm)");
1287 TObjArray* theVolumes = gGeoManager->GetListOfVolumes();
1289 if (theVolumes) {nVol = theVolumes->GetSize();}
1292 for (Int_t ix = 0; ix < Nx; ix++) {
1294 Double_t x = dx*ix + xMin;
1297 for (Int_t iy = 0; iy < Ny; iy++) {
1299 Double_t y = dy*iy + yMin;
1302 Double_t B[ncoordinates] = {0.0, 0.0, 0.0};
1305 Double_t position[ncoordinates] = {0.0, 0.0, 0.0};
1308 position[0] = x, position[1] = y;
1309 }
else if (type == 1) {
1311 position[0] = y, position[2] = x;
1312 }
else if (type == 2) {
1314 position[1] = y; position[2] = x;
1318 Bool_t inside(kFALSE);
1321 TGeoNode* theNode = gGeoManager->FindNode(position[0], position[1], position[2]);
1326 TGeoVolume* theVol = theNode->GetVolume();
1331 TVirtualMagField* theField =
dynamic_cast<TVirtualMagField*
>(theVol->GetField());
1336 theField->Field(position, B);
1351 for (
int icomponent = 0; icomponent<ncoordinates; icomponent++){
1352 theHist[icomponent].Fill(x,y, B[icomponent]/
Tesla_);
1354 Double_t BMag = sqrt(B[0]*B[0] + B[1]*B[1] + B[2]*B[2])/
Tesla_;
1355 theHist[3].Fill(x, y, BMag);
1361 Bool_t wasBatch = gROOT->IsBatch();
1363 gROOT->SetBatch(kTRUE);
1364 TCanvas theCanvas(
"theCanvas",
"", 900, 700);
1365 gROOT->SetStyle(
"Plain");
1366 gStyle->SetOptStat(0);
1368 gStyle->SetPalette(kBird);
1369 theCanvas.UseCurrentStyle();
1371 theCanvas.Divide(2,2);
1372 for (
int icomponent = 0; icomponent < nhistograms; icomponent++){
1373 theCanvas.cd(icomponent+1);
1374 theHist[icomponent].Draw(
"colz");
1376 theCanvas.Print(plotFile.c_str());
1379 if (wasBatch == kFALSE) {gROOT->SetBatch(kFALSE);}
1384 std::ofstream myfile;
1385 myfile.open (fileName);
1386 int xSteps = ceil(xRange/step) + 1;
1387 int ySteps = ceil(yRange/step) + 1;
1388 int zSteps = ceil(zRange*2./step) + 1;
1389 Double_t position[3] = {0.0, 0.0, 0.0};
1390 myfile<<xSteps<<
" "<<ySteps<<
" "<<zSteps<<
" "<<step<<
" "<<xRange<<
" "<<yRange<<
" "<<zRange<<std::endl;
1391 for (
int i =0 ; i < xSteps; i++){
1392 for (
int k=0; k<ySteps;k++){
1393 for (
int m=0;
m<zSteps;
m++){
1394 Double_t B[3] = {0.0, 0.0, 0.0};
1395 Double_t x = step*i;
1396 Double_t y = step * k;
1397 Double_t z =
m * step - zRange + zShift;
1401 Bool_t inside(kFALSE);
1402 TGeoNode* theNode = gGeoManager->FindNode(position[0], position[1], position[2]);
1404 TGeoVolume* theVol = theNode->GetVolume();
1406 TVirtualMagField* theField =
dynamic_cast<TVirtualMagField*
>(theVol->GetField());
1408 theField->Field(position, B);
1416 myfile<<x<<
" "<<y<<
" "<<z<<
" "<<B[0]/
Tesla_<<
" "<<B[1]/
Tesla_<<
" "<<B[2]/
Tesla_<<std::endl;
1424 std::string& splitter)
const {
1429 if (!theString.empty() && !splitter.empty()) {
1431 for (std::string::size_type offset = 0;;) {
1433 std::string::size_type found = theString.find(splitter, offset);
1435 if (found != std::string::npos) {
1436 std::string tmpString = theString.substr(offset, found-offset);
1437 if (tmpString.size() > 0) {result.push_back(tmpString);}
1438 offset = found + splitter.size();
1440 std::string tmpString = theString.substr(offset, theString.size()-offset);
1441 if (tmpString.size() > 0) {result.push_back(tmpString);}
Class that defines a (3d) magnetic field map (distances in cm, fields in tesla)
Bool_t HasSymmetry() const
Get the boolean flag to specify if we have quadrant symmetry.
Float_t GetYOffset() const
Get the y offset co-ordinate of the map for global positioning.
Float_t GetTheta() const
Get the second Euler rotation angle about the new x axis for global positioning.
Float_t GetPsi() const
Get the third Euler rotation angle about the new z axis for global positioning.
Float_t GetPhi() const
Get the first Euler rotation angle about the z axis for global positioning.
Float_t GetXOffset() const
Get the x offset co-ordinate of the map for global positioning.
Float_t GetZOffset() const
Get the z offset co-ordinate of the map for global positioning.
void IncludeTarget(Double_t xy, Double_t z, Double_t l)
Class that defines a magnetic field composed from many fields.
virtual void Field(const Double_t *position, Double_t *B)
The total magnetic field from all of the composite sources (linear superposition)
void defineFieldMap(const TString &name, const TString &mapFileName, const TVector3 &localCentre=TVector3(0.0, 0.0, 0.0), const TVector3 &localAngles=TVector3(0.0, 0.0, 0.0), Bool_t useSymmetry=kFALSE)
std::vector< fieldInfo > localInfo_
Vector of fieldInfo for local fields.
Bool_t gotField(const TString &name) const
Check if we have a field stored with the given name name.
void findNode(TGeoVolume *aVolume, const TString &volName)
Update the current geometry node pointer that matches the required volume name.
void defineComposite(const TString &name, const TString &field1Name, const TString &field2Name, const TString &field3Name="", const TString &field4Name="")
Define a composite field from up to four fields.
void plotField(Int_t type, const TVector3 &xAxis, const TVector3 &yAxis, const std::string &plotFile) const
Plot the magnetic field in "x-y" plane.
Bool_t gotNode_
Boolean to specify if we have found the volume node we need.
SFMap theFields_
The map storing all created magnetic fields.
TVirtualMagField * getField(const TString &name) const
Get the field stored with the given name name.
void plotZYField(const TVector3 &zAxis, const TVector3 &yAxis, const std::string &plotFile) const
Plot the magnetic field in z-y plane.
ShipFieldMaker(Bool_t verbose=kFALSE)
Constructor.
ShipCompField * globalField_
The global magnetic field.
std::vector< fieldInfo > regionInfo_
Vector of fieldInfo for regional fields.
std::vector< std::string > stringVect
Typedef of a vector of strings.
void getTransformation(const TString &volName, transformInfo &theInfo)
Get the transformation matrix for the volume position and orientation.
void readInputFile(const std::string &inputFile)
Read an input file to define fields and associated volumes.
TGeoNode * theNode_
The current volume node: used for finding volume transformations.
void plotXYField(const TVector3 &xAxis, const TVector3 &yAxis, const std::string &plotFile) const
Plot the magnetic field in x-y plane.
Double_t Tesla_
Double converting Tesla to kiloGauss (for VMC/FairRoot B field units)
TVirtualMagField * getVolumeField(const TString &volName) const
Get the magnetic field for the given volume.
void defineGlobalField(const TString &field1Name, const TString &field2Name="", const TString &field3Name="", const TString &field4Name="")
Define a composite field from up to four fields.
void defineLocalField(const TString &volName, const TString &fieldName, Double_t scale=1.0)
Define a localised field and volume pairing.
Bool_t verbose_
Verbose boolean.
void setAllRegionFields()
void defineUniform(const TString &name, const TVector3 &BVector)
Define a uniform field.
virtual void Construct()
Set-up all local and regional fields and assign them to volumes.
virtual ~ShipFieldMaker()
Destructor.
void defineBell(const TString &name, Double_t BPeak, Double_t zMiddle, Int_t orient=1, Double_t tubeR=500.0, Double_t xy=0.0, Double_t z=0.0, Double_t L=0.0)
Define a Bell field.
void defineFieldMapCopy(const TString &name, const TString &mapNameToCopy, const TVector3 &translation, const TVector3 &eulerAngles=TVector3(0.0, 0.0, 0.0))
Define a copy of a field map with a coordinate translation and optional rotation.
void defineConstant(const TString &name, const TVector2 &xRange, const TVector2 &yRange, const TVector2 &zRange, const TVector3 &BVector)
Define a constant field.
stringVect splitString(std::string &theString, std::string &splitter) const
Split a string.
void checkLocalFieldMap(TVirtualMagField *&localField, const TString &volName, Double_t scale)
Check if we have a local field map and store the volume global transformation.
void plotZXField(const TVector3 &zAxis, const TVector3 &xAxis, const std::string &plotFile) const
Plot the magnetic field in z-x plane.
void defineRegionField(const TString &volName, const TString &fieldName, Double_t scale=1.0)
Define a regional (local + global) field and volume pairing.
void generateFieldMap(TString fileName, const float step=2.5, const float xRange=179, const float yRange=317, const float zRange=1515.5, const float zShift=-4996)
Structure to hold volume name, field name and field scaling factor.
TString fieldName_
The name of the field.
Double_t scale_
The field scaling factor.
TString volName_
The name of the volume.