SND@LHC Software
Loading...
Searching...
No Matches
convertMisisMap.py
Go to the documentation of this file.
1#!/bin/python
2
3# Python script to convert B field maps from MISIS text files into
4# ROOT files for FairShip. Text files are assumed to contain two
5# preamble lines giving the binning details and variable names, followed
6# by data lines x y z Bx By Bz, where the co-ordinates are assumed to
7# be in ascending z, y and x, in that order. Need distances in cm
8
9from __future__ import print_function
10import ROOT
11
12# Struct for the ROOT file TTree data: coord range and field info
13
14ROOT.gROOT.ProcessLine(
15"struct rangeStruct{\
16 float xMin;\
17 float xMax;\
18 float dx;\
19 float yMin;\
20 float yMax;\
21 float dy;\
22 float zMin;\
23 float zMax;\
24 float dz;\
25};");
26
27# The field map is assumed to obey the following co-ordinate bin ordering:
28# z is increased first, y is increased 2nd, x is increased last.
29# So we only store the field components (x,y,z is known from the ordering).
30# For the coordinate bin (iX, iY, iZ), the field bin = (iX*Ny + iY)*Nz + iZ,
31# where Ny and Nz are the number of y and z bins
32
33ROOT.gROOT.ProcessLine(
34"struct dataStruct{\
35 float Bx;\
36 float By;\
37 float Bz;\
38};");
39
40
41def run(inFileName = 'BFieldTest.txt',
42 rootFileName = 'BFieldTest.root'):
43
44 createRootMap(inFileName, rootFileName)
45
46
47def createRootMap(inFileName, rootFileName):
48
49 print('Create ROOT map {0} from {1}'.format(rootFileName, inFileName))
50
51 # Define ROOT file and its TTree
52 theFile = ROOT.TFile.Open(rootFileName, 'recreate')
53
54 rangeTree = ROOT.TTree('Range', 'Range')
55 rangeTree.SetDirectory(theFile)
56
57 # Co-ordinate ranges
58 rStruct = ROOT.rangeStruct()
59 rangeTree.Branch('xMin', ROOT.AddressOf(rStruct, 'xMin'), 'xMin/F')
60 rangeTree.Branch('xMax', ROOT.AddressOf(rStruct, 'xMax'), 'xMax/F')
61 rangeTree.Branch('dx', ROOT.AddressOf(rStruct, 'dx'), 'dx/F')
62 rangeTree.Branch('yMin', ROOT.AddressOf(rStruct, 'yMin'), 'yMin/F')
63 rangeTree.Branch('yMax', ROOT.AddressOf(rStruct, 'yMax'), 'yMax/F')
64 rangeTree.Branch('dy', ROOT.AddressOf(rStruct, 'dy'), 'dy/F')
65 rangeTree.Branch('zMin', ROOT.AddressOf(rStruct, 'zMin'), 'zMin/F')
66 rangeTree.Branch('zMax', ROOT.AddressOf(rStruct, 'zMax'), 'zMax/F')
67 rangeTree.Branch('dz', ROOT.AddressOf(rStruct, 'dz'), 'dz/F')
68
69 dataTree = ROOT.TTree('Data', 'Data')
70 dataTree.SetDirectory(theFile)
71
72 # Field components with (x,y,z) coordinate binning ordered such that
73 # z, then y, then x is increased. For the coordinate bin (iX, iY, iZ),
74 # the field bin = (iX*Ny + iY)*Nz + iZ, where Ny and Nz are the number
75 # of y and z bins
76 dStruct = ROOT.dataStruct()
77 dataTree.Branch('Bx', ROOT.AddressOf(dStruct, 'Bx'), 'Bx/F')
78 dataTree.Branch('By', ROOT.AddressOf(dStruct, 'By'), 'By/F')
79 dataTree.Branch('Bz', ROOT.AddressOf(dStruct, 'Bz'), 'Bz/F')
80
81 # mm to cm conversion
82 mm2cm = 0.1
83 # m to cm conversion
84 m2cm = 100.0
85
86 # Open text file and process the information
87 iLine = 0
88
89 # Number of bins initialised by reading first line
90 Nx = 0
91 Ny = 0
92 Nz = 0
93 Nzy = 0
94
95 # Field centering co-ordinates
96 x0 = 0.0
97 y0 = 0.0
98 z0 = 0.0
99
100 with open(inFileName, 'r') as f:
101
102 for line in f:
103 iLine += 1
104
105 # First line contains ranges
106 if iLine == 1:
107 # Remove extraneous, unneeded symbols in the line
108 line = line.replace('[','')
109 line = line.replace(']','')
110 line = line.replace('mm','')
111 sLine = line.split()
112
113 # Bin info line assumed to be formatted as:
114 # Grid Output Min: xMin yMin zMin Max: xMax yMax zMax Grid Size: dx dy dz
115 # These co-ordinate limits are in mm, but the actual data lines use m
116
117 print('sLine = {0}'.format(sLine))
118 # For each value, convert from mm to cm
119 rStruct.xMin = float(sLine[3])*mm2cm
120 rStruct.xMax = float(sLine[7])*mm2cm
121 rStruct.dx = float(sLine[12])*mm2cm
122 rStruct.yMin = float(sLine[4])*mm2cm
123 rStruct.yMax = float(sLine[8])*mm2cm
124 rStruct.dy = float(sLine[13])*mm2cm
125 rStruct.zMin = float(sLine[5])*mm2cm
126 rStruct.zMax = float(sLine[9])*mm2cm
127 rStruct.dz = float(sLine[14])*mm2cm
128
129 Nx = int(((rStruct.xMax - rStruct.xMin)/rStruct.dx) + 1.0)
130 Ny = int(((rStruct.yMax - rStruct.yMin)/rStruct.dy) + 1.0)
131 Nz = int(((rStruct.zMax - rStruct.zMin)/rStruct.dz) + 1.0)
132 Nzy = Nz*Ny
133
134 print('Nx = {0}, Ny = {1}, Nz = {2}'.format(Nx, Ny, Nz))
135
136 # Centre the field map on the local origin (cm)
137 x0 = 0.5*(rStruct.xMin + rStruct.xMax)
138 y0 = 0.5*(rStruct.yMin + rStruct.yMax)
139 z0 = 0.5*(rStruct.zMin + rStruct.zMax)
140
141 print('Centering field map using co-ordinate shift {0} {1} {2} cm'.format(x0, y0, z0))
142
143 # Center co-ordinate range limits (cm)
144 rStruct.xMin = rStruct.xMin - x0
145 rStruct.xMax = rStruct.xMax - x0
146
147 rStruct.yMin = rStruct.yMin - y0
148 rStruct.yMax = rStruct.yMax - y0
149
150 rStruct.zMin = rStruct.zMin - z0
151 rStruct.zMax = rStruct.zMax - z0
152
153 # Fill info into range tree
154 rangeTree.Fill()
155
156
157 # Field data values start from line 3
158 elif iLine > 2:
159
160 sLine = line.split()
161
162 # Bin centre coordinates (m to cm), with origin shift (cm)
163 dStruct.x = float(sLine[0])*m2cm - x0
164 dStruct.y = float(sLine[1])*m2cm - y0
165 dStruct.z = float(sLine[2])*m2cm - z0
166
167 # B field components (Tesla)
168 dStruct.Bx = float(sLine[3])
169 dStruct.By = float(sLine[4])
170 dStruct.Bz = float(sLine[5])
171
172 dataTree.Fill()
173
174 theFile.cd()
175 rangeTree.Write()
176 dataTree.Write()
177 theFile.Close()
178
179
180if __name__ == "__main__":
181
182 run('BFieldTest.txt', 'BFieldTest.root')
createRootMap(inFileName, rootFileName)
run(inFileName='BFieldTest.txt', rootFileName='BFieldTest.root')