diff --git a/Tracker/MagneticField/FASERBField_xyz.txt b/Tracker/MagneticField/FASERBField_xyz.txt new file mode 100644 index 0000000000000000000000000000000000000000..d6cec352653ad301705f06cf3684dd53e46a60fc Binary files /dev/null and b/Tracker/MagneticField/FASERBField_xyz.txt differ diff --git a/Tracker/MagneticField/README.txt b/Tracker/MagneticField/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..98085e11e27f1fb1b593afff4779c6fb0a32f2be --- /dev/null +++ b/Tracker/MagneticField/README.txt @@ -0,0 +1,16 @@ +brief info for FASERBField_xyz.txt +file format : txt +coordinate system : xyz +Dimensions : x[-100.,100.],y[-100.,100.],z[0.,4400.] +Length units : mm +bField unit : T +nBins : [41,41,880] +first quadrant/octant : false + +The file FASERBField_xyz.txt was created on 21.08.2019. It contains full magnetic field map (all octants) of the magnetic flux density in cartesian coordinates for different positions, spanning from -0.1m to 0.1m in x/y and from 0m to 4.4m in z. The first row gives the x position, the second the y position, the third the z position, the fourth the magnetic flux density in x (Bx), the fith the magnetic flux density in y (By), the sixth row is the magnetic flux density in z (Bz), and the last the total magnitude of the flux density. The positions are given in 0.05m steps and have 41 bins in x/y and 880 bins in z. The length unit is millimeter (mm) and the unit of the magnetic flux density is Tesla(T). + +The file FASERBField_xyz.root was created on 21.08.2019 from the the file FASERBField_xyz.txt using the script 'calypso/Tracker/MagneticField/translateBFieldMap.cpp' with the following command: + +translateBFieldMap("FASERBField_xyz.txt","FASERBField_xyz.root","bField",false,1.,1.) + +It contains the full magnetic field map (all octants) of the magnetic flux density in cartesian coordinates for different positions, spanning from -0.1m to 0.1m in x/y and from 0m to 4.4m in z. The positions are given in 0.05m steps and have 41 bins in r/x/y 880 bins in z. The length unit is millimeter (mm) and the unit of the magnetic flux density is Tesla(T). The file contains a tree ‘bField’ which has the following branches describing the coordinates of the positions and the different components of the magnetic flux density: ‘x’,’y’,’z’,’Bx’,’By’,’Bz’. \ No newline at end of file diff --git a/Tracker/MagneticField/translateBFieldMap.cpp b/Tracker/MagneticField/translateBFieldMap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e76dcfbb2f67b231ffdde4736a30db329a05768e --- /dev/null +++ b/Tracker/MagneticField/translateBFieldMap.cpp @@ -0,0 +1,129 @@ +/* + * translateBFieldMap.cpp + * + * Created on: 29 Jan 2018 + * Author: jhrdinka + */ + +/// This root file translates a txt/csv bField map into a root ttree + +/// @param inFile The path to the txt/csv input file +/// @param outFile The name of the output root file +/// @param outTreeName The name of the tree of the output file +/// @param rz Set this flag to true if the magnetic field map is given in rz +/// cooridantes instead of cartesian coordinates +/// @param bScalor A scalor for the magnetic field to be applied +/// @param lScalor A scalor to the length to be applied +void +translateBFieldMap(std::string inFile, + std::string outFile, + std::string outTreeName, + bool rz, + double bScalor = 1., + double lScalor = 1.) +{ + + std::cout << "Registering new ROOT output File : " << outFile << std::endl; + + TFile* outputFile = TFile::Open(outFile.c_str(), "RECREATE"); + if (!outputFile) std::cout << "Could not open '" << outFile << std::endl; + TTree* outputTree = new TTree(outTreeName.c_str(), outTreeName.c_str()); + if (!outputTree) std::cout << "Could not allocate tree" << std::endl; + + if (rz) { + + /// [1] Read in field map file + std::cout << "Opening new txt/csv input File : " << outFile << std::endl; + std::ifstream map_file(inFile.c_str(), std::ios::in); + // [1] Read in file and fill values + std::string line; + double rpos = 0., zpos = 0.; + double br = 0., bz = 0.; + + // The position value in r + double r; + outputTree->Branch("r", &r); + + double z; + outputTree->Branch("z", &z); + // The BField value in r + double Br; + outputTree->Branch("Br", &Br); + + double Bz; + outputTree->Branch("Bz", &Bz); + + while (std::getline(map_file, line)) { + if (line.empty() || line[0] == '%' || line[0] == '#' + || line.find_first_not_of(' ') == std::string::npos) + continue; + + std::istringstream tmp(line); + tmp >> rpos >> zpos >> br >> bz; + + z = zpos * lScalor; + r = rpos * lScalor; + Br = br * bScalor; + Bz = bz * bScalor; + outputTree->Fill(); + } + + outputFile->cd(); + + outputFile->cd(); + outputTree->Write(); + + map_file.close(); + + } else { + /// [1] Read in field map file + std::cout << "Opening new txt/csv input File : " << outFile << std::endl; + std::ifstream map_file(inFile.c_str(), std::ios::in); + + // The position values in xy + double x; + outputTree->Branch("x", &x); + + double y; + outputTree->Branch("y", &y); + + double z; + outputTree->Branch("z", &z); + + // The BField values in xy + double Bx; + outputTree->Branch("Bx", &Bx); + + double By; + outputTree->Branch("By", &By); + + double Bz; + outputTree->Branch("Bz", &Bz); + + std::string line; + double xpos = 0., ypos = 0., zpos = 0.; + double bx = 0., by = 0., bz = 0.; + while (std::getline(map_file, line)) { + if (line.empty() || line[0] == '%' || line[0] == '#' + || line.find_first_not_of(' ') == std::string::npos) + continue; + + std::istringstream tmp(line); + tmp >> xpos >> ypos >> zpos >> bx >> by >> bz; + + x = xpos * lScalor; + y = ypos * lScalor; + z = zpos * lScalor; + Bx = bx * bScalor; + By = by * bScalor; + Bz = bz * bScalor; + + outputTree->Fill(); + } + + outputFile->cd(); + outputTree->Write(); + + map_file.close(); + } +} diff --git a/Tracker/MagneticField/visualisation/README.txt b/Tracker/MagneticField/visualisation/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..3da4e59efb8748dd1559cc8aa9525f9816071048 --- /dev/null +++ b/Tracker/MagneticField/visualisation/README.txt @@ -0,0 +1,9 @@ +This repository contains plots and pictures of the FASER magnetic field. + +The file 'FASERBField_xyz_Map.root' was created from 'FASERBField_xyz.root' using the root script 'printBField' : + +printBField("../FASERBField_xyz.root","bField","FASERBField_xyz_Map.root",-0.1,0.1,0.,4.4,41,880) + +It contains histograms of the FASER magnetic field map in xy,zx and zy. + +The files 'xy.png', 'xz.png' and 'yz.png’ are screen shots of the above histograms. \ No newline at end of file diff --git a/Tracker/MagneticField/visualisation/printBField.cpp b/Tracker/MagneticField/visualisation/printBField.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf3be6498b060a559f62b3fbb59a2a2f1ab7cea3 --- /dev/null +++ b/Tracker/MagneticField/visualisation/printBField.cpp @@ -0,0 +1,144 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <TTreeReader.h> +#include <TTreeReaderValue.h> +#include "TFile.h" +#include "TH1F.h" +#include "TH2F.h" +#include "TProfile.h" +#include "TROOT.h" +#include "TTree.h" + +// This script prints the histogram of a magnetic field map. +// To be used with the Output of the RootInterpolatedBFieldWriter. + +/// to print out the FCC field map please use +/// @code +/// printBField("FCChhBField.root","bField","printBField_FCC.root",-20.,20.,-30.,30.,400.) +/// @endcode +/// ro print out the ATLAS BField map pleas use +/// @code +/// printBField("ATLASBField.root","bField","printBField_ATLAS.root",-10.,10.,-15.,15.,200.) +/// @endcode + +/// @param inFile The root input file containing the magnetic field values and +/// positions either in cylinder (Branch names: 'r','z','Br','Bz') or cartesian +/// coordinates (Branch names: 'x','y','z','Bx','By','Bz') +/// @param the name of the tree containing the branches +/// @param rMin The minimum value of the position in either r (for cylinder +/// coordinates) or x/y (for cartesian coordinates) to be printed in [m] +/// @param rMin The minimum value of the position in either r (for cylinder +/// coordinates) or x/y (for cartesian coordinates) to be printed in [m] +/// @param rMin The maximum value of the position in either r (for cylinder +/// coordinates) or x/y (for cartesian coordinates) to be printed in [m] +/// @param rMin The minimum value of the position in z in [m] +/// @param rMin The maximum value of the position in z in [m] +/// @param nBins Number of bins which should be used for the histogram (on all +/// axes) +/// @note This script just writes out the values which are read in from the +/// given input file. It does no interpolation inbetween the values. This means, +/// in case the binning is chosen too high, empty bins will appear. +void +printBField(std::string inFile, + std::string treeName, + std::string outFile, + float rmin, + float rmax, + float zmin, + float zmax, + int nBins, + int nBinsZ) +{ + const Int_t NRGBs = 5; + const Int_t NCont = 255; + Double_t stops[NRGBs] = {0.00, 0.34, 0.61, 0.84, 1.00}; + Double_t red[NRGBs] = {0.00, 0.00, 0.87, 1.00, 0.51}; + Double_t green[NRGBs] = {0.00, 0.81, 1.00, 0.20, 0.00}; + Double_t blue[NRGBs] = {0.51, 1.00, 0.12, 0.00, 0.00}; + TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont); + gStyle->SetNumberContours(NCont); + gStyle->SetOptStat(0); + + std::cout << "Opening file: " << inFile << std::endl; + TFile inputFile(inFile.c_str()); + std::cout << "Reading tree: " << treeName << std::endl; + TTree* tree = (TTree*)inputFile.Get(treeName.c_str()); + + TTreeReader reader(treeName.c_str(), &inputFile); + + double x = 0., y = 0., z = 0., r = 0.; + double Bx = 0., By = 0., Bz = 0., Br = 0.; + + // find out if file is given in cylinder coordinates or cartesian corrdinates + bool cylinderCoordinates = false; + if (tree->FindBranch("r")) { + cylinderCoordinates = true; + tree->SetBranchAddress("r", &r); + tree->SetBranchAddress("Br", &Br); + } else { + tree->SetBranchAddress("x", &x); + tree->SetBranchAddress("y", &y); + tree->SetBranchAddress("Bx", &Bx); + tree->SetBranchAddress("By", &By); + } + // should be given for sure + tree->SetBranchAddress("z", &z); + tree->SetBranchAddress("Bz", &Bz); + + Int_t entries = tree->GetEntries(); + std::cout << "Creating new output file: " << outFile + << " and writing out histograms. " << std::endl; + TFile outputFile(outFile.c_str(), "recreate"); + + TProfile2D* bField_rz = new TProfile2D( + "BField_rz", "Magnetic Field", nBinsZ, zmin, zmax, nBins * 0.5, 0., rmax); + bField_rz->GetXaxis()->SetTitle("z [m]"); + bField_rz->GetYaxis()->SetTitle("r [m]"); + TProfile2D* bField_xy = new TProfile2D( + "BField_xy", "Magnetic Field", nBins, rmin, rmax, nBins, rmin, rmax); + bField_xy->GetXaxis()->SetTitle("x [m]"); + bField_xy->GetYaxis()->SetTitle("y [m]"); + TProfile2D* bField_yz = new TProfile2D( + "BField_yz", "Magnetic Field", nBinsZ, zmin, zmax, nBins, rmin, rmax); + bField_yz->GetXaxis()->SetTitle("z [m]"); + bField_yz->GetYaxis()->SetTitle("y [m]"); + TProfile2D* bField_xz = new TProfile2D( + "BField_xz", "Magnetic Field", nBinsZ, zmin, zmax, nBins, rmin, rmax); + bField_xz->GetXaxis()->SetTitle("z [m]"); + bField_xz->GetYaxis()->SetTitle("x [m]"); + + for (int i = 0; i < entries; i++) { + tree->GetEvent(i); + if (cylinderCoordinates) { + float bFieldValue = sqrt(Br * Br + Bz * Bz); + bField_rz->Fill(z / 1000., r / 1000., bFieldValue); + } else { + float bFieldValue = sqrt(Bx * Bx + By * By + Bz * Bz); + + bField_xy->Fill(x / 1000., y / 1000., bFieldValue); + bField_yz->Fill(z / 1000., y / 1000., bFieldValue); + bField_xz->Fill(z / 1000., x / 1000., bFieldValue); + } + } + inputFile.Close(); + + if (!cylinderCoordinates) { + bField_xy->Write(); + bField_yz->Write(); + bField_xz->Write(); + } else + bField_rz->Write(); + + delete bField_rz; + delete bField_xy; + delete bField_yz; + delete bField_xz; + + outputFile.Close(); +} diff --git a/Tracker/MagneticField/visualisation/xy.png b/Tracker/MagneticField/visualisation/xy.png new file mode 100644 index 0000000000000000000000000000000000000000..8a862de2e513aa85c3b548be61e57373b1abe188 Binary files /dev/null and b/Tracker/MagneticField/visualisation/xy.png differ diff --git a/Tracker/MagneticField/visualisation/xz.png b/Tracker/MagneticField/visualisation/xz.png new file mode 100644 index 0000000000000000000000000000000000000000..b6ff7217e86cad35143e0bd8337b863c67156491 Binary files /dev/null and b/Tracker/MagneticField/visualisation/xz.png differ diff --git a/Tracker/MagneticField/visualisation/yz.png b/Tracker/MagneticField/visualisation/yz.png new file mode 100644 index 0000000000000000000000000000000000000000..636611e7cd4d72192e34b827dafab3a416513d64 Binary files /dev/null and b/Tracker/MagneticField/visualisation/yz.png differ