25#include "FairLogger.h"
30#include "TGeoChecker.h"
31#include "TGeoManager.h"
32#include "TGeoMatrix.h"
34#include "TGeoPhysicalNode.h"
35#include "TGeoUniformMagField.h"
36#include "TGeoVolume.h"
41#include "TVirtualMC.h"
44 : TG4VUserPostDetConstruction(),
45 globalField_(nullptr),
72 if (inputFile.size() < 1) {
73 std::cerr <<
"Skipping ShipFieldMaker::readInputFile(): file name is empty"
78 const char* vmcworkdir = getenv(
"VMCWORKDIR");
80 LOG(fatal) <<
"VMCWORKDIR environment variable not set";
83 std::string fullFileName = vmcworkdir;
85 fullFileName += inputFile.c_str();
87 std::cout <<
"ShipFieldMaker::makeFields inputFile = " << fullFileName
90 std::ifstream getData(fullFileName);
91 std::string whiteSpace(
" ");
94 while (getData.good()) {
95 if (getData.peek() ==
'\n') {
105 }
else if (getData.peek() ==
'#') {
107 getData.ignore(1000,
'\n');
108 getData.putback(
'\n');
117 std::string line(
"");
118 std::getline(getData, line);
126 std::vector<std::string> lineVect = this->
splitString(line, whiteSpace);
128 size_t nWords = lineVect.size();
132 TString keyWord(lineVect[0].c_str());
135 if (!keyWord.CompareTo(
"uniform")) {
139 }
else if (!keyWord.CompareTo(
"constant")) {
143 }
else if (!keyWord.CompareTo(
"bell")) {
147 }
else if (!keyWord.CompareTo(
"fieldmap")) {
151 }
else if (!keyWord.CompareTo(
"symfieldmap")) {
155 }
else if (!keyWord.CompareTo(
"copymap")) {
159 }
else if (!keyWord.CompareTo(
"composite")) {
163 }
else if (!keyWord.CompareTo(
"global")) {
167 }
else if (!keyWord.CompareTo(
"region")) {
171 }
else if (!keyWord.CompareTo(
"local")) {
183 size_t nWords = inputLine.size();
189 const TString name(inputLine[1].c_str());
191 Double_t Bx = std::atof(inputLine[2].c_str());
192 Double_t By = std::atof(inputLine[3].c_str());
193 Double_t Bz = std::atof(inputLine[4].c_str());
194 const TVector3 BVector(Bx, By, Bz);
199 std::cout <<
"Expecting 5 words for the definition of the uniform field: "
200 <<
"Uniform Name Bx By Bz" << std::endl;
205 const TVector3& BVector) {
209 std::cout <<
"Creating uniform field for " << name.Data() << std::endl;
212 Double_t Bx = BVector.X() *
Tesla_;
213 Double_t By = BVector.Y() *
Tesla_;
214 Double_t Bz = BVector.Z() *
Tesla_;
216 TGeoUniformMagField* uField =
new TGeoUniformMagField(Bx, By, Bz);
221 std::cout <<
"We already have a uniform field with the name "
222 << name.Data() << std::endl;
228 size_t nWords = inputLine.size();
234 TString name(inputLine[1].c_str());
236 Double_t xMin = std::atof(inputLine[2].c_str());
237 Double_t xMax = std::atof(inputLine[3].c_str());
239 Double_t yMin = std::atof(inputLine[4].c_str());
240 Double_t yMax = std::atof(inputLine[5].c_str());
242 Double_t zMin = std::atof(inputLine[6].c_str());
243 Double_t zMax = std::atof(inputLine[7].c_str());
246 Double_t Bx = std::atof(inputLine[8].c_str());
247 Double_t By = std::atof(inputLine[9].c_str());
248 Double_t Bz = std::atof(inputLine[10].c_str());
250 const TVector2 xRange(xMin, xMax);
251 const TVector2 yRange(yMin, yMax);
252 const TVector2 zRange(zMin, zMax);
253 const TVector3 BVector(Bx, By, Bz);
258 std::cout <<
"Expecting 11 words for the definition of the constant field: "
259 <<
"Constant Name xMin xMax yMin yMax zMin zMax Bx By Bz"
265 const TVector2& yRange,
266 const TVector2& zRange,
267 const TVector3& BVector) {
270 Double_t xMin = xRange.X();
271 Double_t xMax = xRange.Y();
272 Double_t yMin = yRange.X();
273 Double_t yMax = yRange.Y();
274 Double_t zMin = zRange.X();
275 Double_t zMax = zRange.Y();
277 Double_t Bx = BVector.X() *
Tesla_;
278 Double_t By = BVector.Y() *
Tesla_;
279 Double_t Bz = BVector.Z() *
Tesla_;
282 yMax, zMin, zMax, Bx, By, Bz);
287 std::cout <<
"We already have a constant field with the name "
288 << name.Data() << std::endl;
294 size_t nWords = inputLine.size();
299 if (nWords == 6 || nWords == 9) {
300 TString name(inputLine[1].c_str());
302 Double_t BPeak = std::atof(inputLine[2].c_str());
303 Double_t zMiddle = std::atof(inputLine[3].c_str());
305 Int_t orient = std::atoi(inputLine[4].c_str());
306 Double_t tubeR = std::atof(inputLine[5].c_str());
308 Double_t xy(0.0), z(0.0), L(0.0);
312 xy = std::atof(inputLine[6].c_str());
313 z = std::atof(inputLine[7].c_str());
314 L = std::atof(inputLine[8].c_str());
317 this->
defineBell(name, BPeak, zMiddle, orient, tubeR, xy, z, L);
320 std::cout <<
"Expecting 6 or 9 words for the definition of the Bell field: "
321 <<
"Bell Name BPeak zMiddle orientationInt tubeRadius [targetXY "
328 Double_t zMiddle, Int_t orient, Double_t tubeR,
329 Double_t xy, Double_t z, Double_t L) {
343 std::cout <<
"We already have a Bell field with the name " << name.Data()
350 Bool_t useSymmetry) {
351 size_t nWords = inputLine.size();
356 if (nWords == 3 || nWords == 6 || nWords == 9) {
357 const TString name(inputLine[1].c_str());
358 const TString mapFileName(inputLine[2].c_str());
360 Double_t x0(0.0), y0(0.0), z0(0.0);
361 Double_t phi(0.0), theta(0.0), psi(0.0);
364 x0 = std::atof(inputLine[3].c_str());
365 y0 = std::atof(inputLine[4].c_str());
366 z0 = std::atof(inputLine[5].c_str());
370 phi = std::atof(inputLine[6].c_str());
371 theta = std::atof(inputLine[7].c_str());
372 psi = std::atof(inputLine[8].c_str());
375 const TVector3 localCentre(x0, y0, z0);
376 const TVector3 localAngles(phi, theta, psi);
383 <<
"Expecting 3, 6 or 9 words for the definition of the field map: "
384 <<
"(Sym)FieldMap Name mapFileName [x0 y0 z0] [[phi theta psi]]"
390 const TString& mapFileName,
391 const TVector3& localCentre,
392 const TVector3& localAngles,
393 Bool_t useSymmetry) {
397 const char* vmcworkdir = getenv(
"VMCWORKDIR");
399 LOG(fatal) <<
"VMCWORKDIR environment variable not set";
402 std::string fullFileName = vmcworkdir;
404 fullFileName += mapFileName.Data();
408 std::cout <<
"Creating symmetric field map called " << name.Data()
409 <<
" using " << fullFileName << std::endl;
411 std::cout <<
"Creating field map called " << name.Data() <<
" using "
412 << fullFileName << std::endl;
418 Float_t x0 = localCentre.X();
419 Float_t y0 = localCentre.Y();
420 Float_t z0 = localCentre.Z();
422 Float_t phi = localAngles.X();
423 Float_t theta = localAngles.Y();
424 Float_t psi = localAngles.Z();
429 new ShipBFieldMap(name.Data(), fullFileName, x0, y0, z0, phi, theta,
430 psi, scale, useSymmetry);
435 std::cout <<
"We already have a field map with the name " << name.Data()
444 size_t nWords = inputLine.size();
449 if (nWords == 6 || nWords == 9) {
450 const TString name(inputLine[1].c_str());
453 const TString mapNameToCopy(inputLine[2].c_str());
455 Double_t x0 = std::atof(inputLine[3].c_str());
456 Double_t y0 = std::atof(inputLine[4].c_str());
457 Double_t z0 = std::atof(inputLine[5].c_str());
459 Double_t phi(0.0), theta(0.0), psi(0.0);
462 phi = std::atof(inputLine[6].c_str());
463 theta = std::atof(inputLine[7].c_str());
464 psi = std::atof(inputLine[8].c_str());
467 const TVector3 translation(x0, y0, z0);
468 const TVector3 eulerAngles(phi, theta, psi);
473 std::cout <<
"Expecting 6 or 9 words for the copy of a field map: "
474 <<
"CopyMap Name MapNameToCopy x0 y0 z0 [phi theta psi]"
480 const TString& mapNameToCopy,
481 const TVector3& translation,
482 const TVector3& eulerAngles) {
490 std::cout <<
"Creating map field copy " << name.Data() <<
" based on "
491 << mapNameToCopy.Data() << std::endl;
496 Float_t x0 = translation.X();
497 Float_t y0 = translation.Y();
498 Float_t z0 = translation.Z();
500 Float_t phi = eulerAngles.X();
501 Float_t theta = eulerAngles.Y();
502 Float_t psi = eulerAngles.Z();
507 name.Data(), *fieldToCopy, x0, y0, z0, phi, theta, psi, scale);
512 std::cout <<
"We already have a copied field map with the name "
513 << name.Data() << std::endl;
518 size_t nWords = inputLine.size();
524 TString name(inputLine[1].c_str());
526 std::vector<TString> fieldNames;
527 for (
size_t i = 2; i < nWords; i++) {
528 TString aName(inputLine[i].c_str());
529 fieldNames.push_back(aName);
535 std::cout <<
"Expecting at least 3 words for the composite definition: "
536 <<
"Composite Name Field1 Field2 ... FieldN" << std::endl;
541 const TString& field1Name,
542 const TString& field2Name,
543 const TString& field3Name,
544 const TString& field4Name) {
545 std::vector<TString> fieldNames;
546 fieldNames.push_back(field1Name);
547 fieldNames.push_back(field2Name);
549 if (field3Name.Length() > 0) {
550 fieldNames.push_back(field3Name);
552 if (field4Name.Length() > 0) {
553 fieldNames.push_back(field4Name);
560 std::vector<TString> fieldNames) {
564 std::vector<TVirtualMagField*> vectFields;
566 std::vector<TString>::iterator iter;
567 for (iter = fieldNames.begin(); iter != fieldNames.end(); ++iter) {
568 TString aName = *iter;
569 TVirtualMagField* aField = this->
getField(aName);
572 std::cout <<
"Adding field " << aName << std::endl;
574 vectFields.push_back(aField);
582 std::cout <<
"We already have a composite field with the name "
583 << name.Data() << std::endl;
590 size_t nWords = inputLine.size();
596 TString name(
"Global");
598 std::vector<TString> fieldNames;
599 for (
size_t i = 1; i < nWords; i++) {
600 TString aName(inputLine[i].c_str());
601 fieldNames.push_back(aName);
608 <<
"Expecting at least two words for the global field definition: "
609 <<
"Global Field1 ... FieldN" << std::endl;
614 const TString& field2Name,
615 const TString& field3Name,
616 const TString& field4Name) {
617 std::vector<TString> fieldNames;
618 fieldNames.push_back(field1Name);
620 if (field2Name.Length() > 0) {
621 fieldNames.push_back(field2Name);
623 if (field3Name.Length() > 0) {
624 fieldNames.push_back(field3Name);
626 if (field4Name.Length() > 0) {
627 fieldNames.push_back(field4Name);
636 std::cout <<
"Deleting already existing Global field" << std::endl;
642 std::cout <<
"Setting the Global field" << std::endl;
645 std::vector<TVirtualMagField*> vectFields;
647 std::vector<TString>::iterator iter;
648 for (iter = fieldNames.begin(); iter != fieldNames.end(); ++iter) {
649 TString aName = *iter;
650 TVirtualMagField* aField = this->
getField(aName);
654 std::cout <<
"Adding field " << aName <<
" to Global" << std::endl;
656 vectFields.push_back(aField);
658 std::cout <<
"Could not find the field " << aName << std::endl;
662 TString name(
"Global");
670 <<
"The virtual MC pointer gMC is null! The global field can't be used "
671 "by Geant4 but will work for track fitting and track extrapolation"
678 size_t nWords = inputLine.size();
683 if (nWords == 3 || nWords == 4) {
684 TString volName(inputLine[1].c_str());
685 TString fieldName(inputLine[2].c_str());
689 scale = std::atof(inputLine[3].c_str());
695 std::cout <<
"Expecting 3 or 4 words for the region (local + global) field "
697 <<
"Region VolName LocalFieldName [LocalFieldMapScale]"
703 const TString& fieldName,
706 std::cout <<
"ShipFieldMaker::defineRegionField for volume "
707 << volName.Data() <<
" and field " << fieldName.Data()
708 <<
" with scale = " << scale << std::endl;
711 fieldInfo theInfo(volName, fieldName, scale);
718 std::vector<fieldInfo>::iterator regionIter;
723 const TString volName = theInfo.
volName_;
725 Double_t scale = theInfo.
scale_;
728 TGeoVolume* theVol(0);
730 theVol = gGeoManager->FindVolumeFast(volName.Data());
735 TVirtualMagField* localField = this->
getField(fieldName);
744 fieldName = localField->GetName();
749 TString lgName(fieldName);
751 TVirtualMagField* lgField = this->
getField(lgName);
758 std::cout <<
"Creating the combined field " << lgName.Data()
759 <<
", with local field " << fieldName.Data()
760 <<
" with the global field for volume "
761 << volName.Data() << std::endl;
767 theVol->SetField(combField);
771 std::cout <<
"Setting the field " << lgName.Data()
772 <<
" for volume " << volName.Data() << std::endl;
774 theVol->SetField(lgField);
779 std::cout <<
"There is no global field defined. Just setting the "
783 theVol->SetField(localField);
787 std::cout <<
"Could not find the local field " << fieldName.Data()
792 std::cout <<
"Could not find the volume " << volName << std::endl;
800 size_t nWords = inputLine.size();
805 if (nWords == 3 || nWords == 4) {
806 TString volName(inputLine[1].c_str());
807 TString fieldName(inputLine[2].c_str());
811 scale = std::atof(inputLine[3].c_str());
817 std::cout <<
"Expecting 3 or 4 words for the local field definition: "
818 <<
"Local VolName LocalFieldName [FieldMapScale]" << std::endl;
823 const TString& fieldName,
826 std::cout <<
"ShipFieldMaker::defineLocalField for volume "
827 << volName.Data() <<
" and field " << fieldName.Data()
828 <<
" with scale = " << scale << std::endl;
831 fieldInfo theInfo(volName, fieldName, scale);
838 std::vector<fieldInfo>::iterator localIter;
843 const TString volName = theInfo.
volName_;
845 Double_t scale = theInfo.
scale_;
847 TGeoVolume* theVol(0);
849 theVol = gGeoManager->FindVolumeFast(volName.Data());
853 TVirtualMagField* localField = this->
getField(fieldName);
857 theVol->SetField(localField);
860 std::cout <<
"Setting local field " << localField->GetName()
861 <<
" for volume " << volName << std::endl;
865 std::cout <<
"Could not find the field " << fieldName.Data()
870 std::cout <<
"Could not find the volume " << volName.Data() << std::endl;
877 const TString& volName,
889 TString fieldName(mapField->GetName());
890 TString localName(fieldName);
891 localName += volName;
894 std::cout <<
"Checking local field map " << fieldName
895 <<
" co-ord transformation for volume " << volName << std::endl;
902 if (!localMap && volName.Length() > 0) {
904 TString volName1(volName);
915 TGeoTranslation origTrans(
"origTrans", origX0, origY0, origZ0);
917 Double_t origPhi = mapField->
GetPhi();
918 Double_t origTheta = mapField->
GetTheta();
919 Double_t origPsi = mapField->
GetPsi();
920 TGeoRotation origRot(
"origRot", origPhi, origTheta, origPsi);
922 TGeoCombiTrans origComb(origTrans, origRot);
924 std::cout <<
"The original field map transformation:" << std::endl;
928 TGeoTranslation newTrans(
"newTrans", theInfo.
x0_, theInfo.
y0_,
930 TGeoRotation newRot(
"newRot", theInfo.
phi_, theInfo.
theta_, theInfo.
psi_);
932 TGeoCombiTrans newComb(newTrans, newRot);
935 std::cout <<
"The volume transformation:" << std::endl;
940 newComb = newComb * origComb;
943 std::cout <<
"The combined transformation:" << std::endl;
948 const Double_t* newTransArray = newComb.GetTranslation();
949 theInfo.
x0_ = newTransArray[0];
950 theInfo.
y0_ = newTransArray[1];
951 theInfo.
z0_ = newTransArray[2];
953 const TGeoRotation* fullRot = newComb.GetRotation();
961 std::cout <<
"Creating field map copy for " << localName <<
" based on "
962 << mapField->GetName() <<
": x0 = " << theInfo.
x0_
963 <<
", y0 = " << theInfo.
y0_ <<
", z0 = " << theInfo.
z0_
964 <<
", phi = " << theInfo.
phi_
965 <<
", theta = " << theInfo.
theta_
966 <<
", psi = " << theInfo.
psi_ <<
", scale = " << scale
967 <<
" and symmetry = " << mapField->
HasSymmetry() << std::endl;
979 localField = localMap;
996 TGeoMatrix* theMatrix(0);
998 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
1001 <<
"Can't find the top volume in ShipFieldMaker::getTransformation"
1007 std::cout <<
"Finding transformation for " << volName << std::endl;
1013 this->
findNode(topVolume, volName);
1022 const Double_t* theTrans = theMatrix->GetTranslation();
1023 theInfo.
x0_ = theTrans[0];
1024 theInfo.
y0_ = theTrans[1];
1025 theInfo.
z0_ = theTrans[2];
1029 if (theMatrix->IsCombi()) {
1030 TGeoCombiTrans* theCombi =
dynamic_cast<TGeoCombiTrans*
>(theMatrix);
1032 TGeoRotation* combRotn = theCombi->GetRotation();
1038 }
else if (theMatrix->IsRotation()) {
1039 TGeoRotation* theRotn =
dynamic_cast<TGeoRotation*
>(theMatrix);
1056 TObjArray* volNodes = aVolume->GetNodes();
1060 int nNodes = volNodes->GetEntries();
1061 for (
int i = 0; i < nNodes; i++) {
1062 TGeoNode* node =
dynamic_cast<TGeoNode*
>(volNodes->At(i));
1065 const TString nodeName(node->GetName());
1066 if (!nodeName.CompareTo(volName, TString::kExact)) {
1072 }
else if (node->GetNodes()) {
1074 this->
findNode(node->GetVolume(), volName);
1083 TVirtualMagField* theField(0);
1084 TGeoVolume* theVol(0);
1086 theVol = gGeoManager->FindVolumeFast(volName.Data());
1091 theField =
dynamic_cast<TVirtualMagField*
>(theVol->GetField());
1098 Bool_t result(kFALSE);
1101 SFMap::const_iterator iter;
1103 TString key = iter->first;
1104 TVirtualMagField* theField = iter->second;
1107 if (!key.CompareTo(name, TString::kExact) && theField) {
1117 TVirtualMagField* theField(0);
1120 SFMap::const_iterator iter;
1122 TString key = iter->first;
1123 TVirtualMagField* BField = iter->second;
1126 if (!key.CompareTo(name, TString::kExact)) {
1136 const std::string& plotFile)
const {
1137 this->
plotField(0, xAxis, yAxis, plotFile);
1141 const std::string& plotFile)
const {
1142 this->
plotField(1, zAxis, xAxis, plotFile);
1146 const std::string& plotFile)
const {
1147 this->
plotField(2, zAxis, yAxis, plotFile);
1151 const TVector3& yAxis,
1152 const std::string& plotFile)
const {
1153 std::cout <<
"ShipFieldMaker plotField " << plotFile <<
": type = " << type
1156 Double_t xMin = xAxis(0);
1157 Double_t xMax = xAxis(1);
1158 Double_t dx = xAxis(2);
1161 Nx = std::lround((xMax - xMin) / dx);
1164 Double_t yMin = yAxis(0);
1165 Double_t yMax = yAxis(1);
1166 Double_t dy = yAxis(2);
1169 Ny = std::lround((yMax - yMin) / dy);
1173 const int nhistograms = 4;
1174 const int ncoordinates = 3;
1176 TH2D theHist[nhistograms];
1177 std::string titles[nhistograms] = {
"Bx (T)",
"By (T)",
"Bz (T)",
"B (T)"};
1178 for (
int icomponent = 0; icomponent < nhistograms; icomponent++) {
1179 theHist[icomponent] =
1180 TH2D(Form(
"theHist[%i]", icomponent), titles[icomponent].data(), Nx,
1181 xMin, xMax, Ny, yMin, yMax);
1182 theHist[icomponent].SetDirectory(0);
1185 theHist[icomponent].SetXTitle(
"x (cm)");
1186 theHist[icomponent].SetYTitle(
"y (cm)");
1187 }
else if (type == 1) {
1189 theHist[icomponent].SetXTitle(
"z (cm)");
1190 theHist[icomponent].SetYTitle(
"x (cm)");
1191 }
else if (type == 2) {
1193 theHist[icomponent].SetXTitle(
"z (cm)");
1194 theHist[icomponent].SetYTitle(
"y (cm)");
1199 for (Int_t ix = 0; ix < Nx; ix++) {
1200 Double_t x = dx * ix + xMin;
1203 for (Int_t iy = 0; iy < Ny; iy++) {
1204 Double_t y = dy * iy + yMin;
1207 Double_t
B[ncoordinates] = {0.0, 0.0, 0.0};
1210 Double_t position[ncoordinates] = {0.0, 0.0, 0.0};
1213 position[0] = x, position[1] = y;
1214 }
else if (type == 1) {
1216 position[0] = y, position[2] = x;
1217 }
else if (type == 2) {
1224 Bool_t inside(kFALSE);
1228 gGeoManager->FindNode(position[0], position[1], position[2]);
1232 TGeoVolume* theVol = theNode->GetVolume();
1236 TVirtualMagField* theField =
1237 dynamic_cast<TVirtualMagField*
>(theVol->GetField());
1241 theField->Field(position,
B);
1257 for (
int icomponent = 0; icomponent < ncoordinates; icomponent++) {
1258 theHist[icomponent].Fill(x, y,
B[icomponent] /
Tesla_);
1260 Double_t BMag = sqrt(
B[0] *
B[0] +
B[1] *
B[1] +
B[2] *
B[2]) /
Tesla_;
1261 theHist[3].Fill(x, y, BMag);
1267 Bool_t wasBatch = gROOT->IsBatch();
1269 gROOT->SetBatch(kTRUE);
1270 TCanvas theCanvas(
"theCanvas",
"", 900, 700);
1271 gROOT->SetStyle(
"Plain");
1272 gStyle->SetOptStat(0);
1274 gStyle->SetPalette(kBird);
1275 theCanvas.UseCurrentStyle();
1277 theCanvas.Divide(2, 2);
1278 for (
int icomponent = 0; icomponent < nhistograms; icomponent++) {
1279 theCanvas.cd(icomponent + 1);
1280 theHist[icomponent].Draw(
"colz");
1282 theCanvas.Print(plotFile.c_str());
1285 if (wasBatch == kFALSE) {
1286 gROOT->SetBatch(kFALSE);
1291 const float xRange,
const float yRange,
1292 const float zRange,
const float zShift) {
1293 std::ofstream myfile;
1294 myfile.open(fileName);
1295 int xSteps = ceil(xRange / step) + 1;
1296 int ySteps = ceil(yRange / step) + 1;
1297 int zSteps = ceil(zRange * 2. / step) + 1;
1298 Double_t position[3] = {0.0, 0.0, 0.0};
1299 myfile << xSteps <<
" " << ySteps <<
" " << zSteps <<
" " << step
1300 <<
" " << xRange <<
" " << yRange <<
" " << zRange
1302 for (
int i = 0; i < xSteps; i++) {
1303 for (
int k = 0; k < ySteps; k++) {
1304 for (
int m = 0;
m < zSteps;
m++) {
1305 Double_t
B[3] = {0.0, 0.0, 0.0};
1306 Double_t x = step * i;
1307 Double_t y = step * k;
1308 Double_t z =
m * step - zRange + zShift;
1312 Bool_t inside(kFALSE);
1314 gGeoManager->FindNode(position[0], position[1], position[2]);
1316 TGeoVolume* theVol = theNode->GetVolume();
1318 TVirtualMagField* theField =
1319 dynamic_cast<TVirtualMagField*
>(theVol->GetField());
1321 theField->Field(position,
B);
1329 myfile << x <<
" " << y <<
" " << z <<
" " <<
B[0] /
Tesla_
1339 std::string& theString, std::string& splitter)
const {
1343 if (!theString.empty() && !splitter.empty()) {
1344 for (std::string::size_type offset = 0;;) {
1345 std::string::size_type found = theString.find(splitter, offset);
1347 if (found != std::string::npos) {
1348 std::string tmpString = theString.substr(offset, found - offset);
1349 if (tmpString.size() > 0) {
1350 result.push_back(tmpString);
1352 offset = found + splitter.size();
1354 std::string tmpString =
1355 theString.substr(offset, theString.size() - offset);
1356 if (tmpString.size() > 0) {
1357 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 coordinate of the map 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 coordinate of the map for global positioning.
Float_t GetZOffset() const
Get the z offset coordinate 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)
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)
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))
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)
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.