SND@LHC Software
Loading...
Searching...
No Matches
convertRALMap.py
Go to the documentation of this file.
1#!/bin/python
2
3# Python script to convert B field maps into text and ROOT files for FairShip.
4# Reduce the number of decimal places to try to reduce the file size.
5# Also add to the file info about the binning, offsets etc..
6# Input file distances are in m; convert them to centimetres
7
8from __future__ import print_function
9import ROOT
10
11# Struct for the ROOT file TTree data: coord range and field info
12
13ROOT.gROOT.ProcessLine(
14"struct rangeStruct{\
15 float xMin;\
16 float xMax;\
17 float dx;\
18 float yMin;\
19 float yMax;\
20 float dy;\
21 float zMin;\
22 float zMax;\
23 float dz;\
24};");
25
26# The field map is assumed to obey the following co-ordinate bin ordering:
27# z is increased first, y is increased 2nd, x is increased last.
28# So we only store the field components (x,y,z is known from the ordering).
29# For the coordinate bin (iX, iY, iZ), the field bin = (iX*Ny + iY)*Nz + iZ,
30# where Ny and Nz are the number of y and z bins
31
32ROOT.gROOT.ProcessLine(
33"struct dataStruct{\
34 float Bx;\
35 float By;\
36 float Bz;\
37};");
38
39
40def run(inFileName = 'test07_10cm_grid.table',
41 outFileName = 'MuonFilterBFieldMap1.txt'):
42
43 # Text format
44 createTextMap(inFileName, outFileName)
45
46 # Also create ROOT file based on the restructured text output
47 rootFileName = outFileName.replace('.txt', '.root')
48 createRootMap(outFileName, rootFileName)
49
50
51def createTextMap(inFileName, outFileName):
52
53 print('Creating text map {0} from {1}'.format(outFileName, inFileName))
54
55 tmpFileName = 'tmpFile.txt'
56
57 inFile = open(inFileName, 'r')
58 tmpFile = open(tmpFileName, 'w')
59
60 iLine = 0
61 xMin = 0.0
62 xMax = 0.0
63 dx = 0.0
64 yMin = 0.0
65 yMax = 0.0
66 dy = 0.0
67 zMin = 0.0
68 zMax = 0.0
69 dz = 0.0
70
71 # Offsets (in cm)
72 #ox = 0.0
73 #oy = 0.0
74 #oz = 0.0
75
76 iLine = 0
77 # Convert metres to centimetres
78 m2cm = 100.0
79
80 # For finding the delta bin widths
81 xOld = 0.0
82 yOld = 0.0
83 zOld = 0.0
84 gotdx = 0
85 gotdy = 0
86 gotdz = 0
87
88 firstDataLine = 9
89
90 for inLine in inFile:
91
92 iLine += 1
93 # Skip the first few lines
94 if iLine >= firstDataLine:
95 words = inLine.split()
96 #print 'words = {0}'.format(words)
97 # Convert the x,y,z co-ords to centimetres
98 x = float(words[0])*m2cm
99 y = float(words[1])*m2cm
100 z = float(words[2])*m2cm
101 Bx = float(words[3])
102 By = float(words[4])
103 Bz = float(words[5])
104
105 BxWord = formatNumber(Bx)
106 ByWord = formatNumber(By)
107 BzWord = formatNumber(Bz)
108
109 # Write out the new line. Just print out the B field components, since we
110 # can infer x,y,z co-ords from the ordering
111 newLine = '{0} {1} {2}\n'.format(BxWord, ByWord, BzWord)
112 #newLine = '{0:.0f} {1:.0f} {2:.0f} {3:.3e} {4:.3e} {5:.3e}\n'.format(x,y,z,Bx,By,Bz)
113 tmpFile.write(newLine)
114
115 # Keep track of the min/max values
116 if iLine == firstDataLine:
117 xMin = x
118 xMax = x
119 xOld = x
120 yMin = y
121 yMax = y
122 yOld = y
123 zMin = z
124 zMax = z
125 zOld = z
126
127 if x < xMin:
128 xMin = x
129 if x > xMax:
130 xMax = x
131 if y < yMin:
132 yMin = y
133 if y > yMax:
134 yMax = y
135 if z < zMin:
136 zMin = z
137 if z > zMax:
138 zMax = z
139
140 if gotdx == 0 and x != xOld:
141 dx = x - xOld
142 gotdx = 1
143 if gotdy == 0 and y != yOld:
144 dy = y - yOld
145 gotdy = 1
146 if gotdz == 0 and z != zOld:
147 dz = z - zOld
148 gotdz = 1
149
150 print('dx = {0}, dy = {1}, dz = {2}'.format(dx,dy,dz))
151 print('x = {0} to {1}, y = {2} to {3}, z = {4} to {5}'.format(xMin, xMax, yMin, yMax, zMin, zMax))
152
153 tmpFile.close()
154 inFile.close()
155
156 # Write out the map containing the co-ordinate ranges and offsets etc
157 tmpFile2 = open(tmpFileName, 'r')
158 outFile = open(outFileName, 'w')
159
160 outLine = 'CLimits {0:.0f} {1:.0f} {2:.0f} {3:.0f} {4:.0f} {5:.0f} ' \
161 '{6:.0f} {7:.0f} {8:.0f}\n'.format(xMin, xMax, dx, yMin, yMax, dy, zMin, zMax, dz)
162 outFile.write(outLine)
163
164 #outLine = 'Offsets {0:.0f} {1:.0f} {2:.0f}\n'.format(ox, oy, oz)
165 #outFile.write(outLine)
166
167 # Write a line showing the variable names (for file readability)
168 outLine = 'Bx(T) By(T) Bz(T)\n'
169 #outLine = 'x(cm) y(cm) z(cm) Bx(T) By(T) Bz(T)\n'
170 outFile.write(outLine)
171
172 # Copy the tmp file data
173 for tLine in tmpFile2:
174
175 outFile.write(tLine)
176
177 outFile.close()
178 tmpFile2.close()
179
181
182 # To save disk space, reduce the precision of the field value
183 # as we go below various thresholds
184
185 # Let the general precision be 0.01 mT. Anything below this
186 # is set to zero.
187 xWord = '{0:.5f}'.format(x)
188
189 if abs(x) < 1e-5:
190
191 # Set to zero
192 xWord = '0'
193
194 return xWord
195
196def createRootMap(inFileName, outFileName):
197
198 print('Create ROOT map {0} from {1}'.format(outFileName, inFileName))
199
200 # Define ROOT file and its TTree
201 theFile = ROOT.TFile.Open(outFileName, 'recreate')
202
203 rangeTree = ROOT.TTree('Range', 'Range')
204 rangeTree.SetDirectory(theFile)
205
206 # Co-ordinate ranges
207 rStruct = ROOT.rangeStruct()
208 rangeTree.Branch('xMin', ROOT.AddressOf(rStruct, 'xMin'), 'xMin/F')
209 rangeTree.Branch('xMax', ROOT.AddressOf(rStruct, 'xMax'), 'xMax/F')
210 rangeTree.Branch('dx', ROOT.AddressOf(rStruct, 'dx'), 'dx/F')
211 rangeTree.Branch('yMin', ROOT.AddressOf(rStruct, 'yMin'), 'yMin/F')
212 rangeTree.Branch('yMax', ROOT.AddressOf(rStruct, 'yMax'), 'yMax/F')
213 rangeTree.Branch('dy', ROOT.AddressOf(rStruct, 'dy'), 'dy/F')
214 rangeTree.Branch('zMin', ROOT.AddressOf(rStruct, 'zMin'), 'zMin/F')
215 rangeTree.Branch('zMax', ROOT.AddressOf(rStruct, 'zMax'), 'zMax/F')
216 rangeTree.Branch('dz', ROOT.AddressOf(rStruct, 'dz'), 'dz/F')
217
218 dataTree = ROOT.TTree('Data', 'Data')
219 dataTree.SetDirectory(theFile)
220
221 # Field components with (x,y,z) coordinate binning ordered such that
222 # z, then y, then x is increased. For the coordinate bin (iX, iY, iZ),
223 # the field bin = (iX*Ny + iY)*Nz + iZ, where Ny and Nz are the number
224 # of y and z bins
225 dStruct = ROOT.dataStruct()
226 dataTree.Branch('Bx', ROOT.AddressOf(dStruct, 'Bx'), 'Bx/F')
227 dataTree.Branch('By', ROOT.AddressOf(dStruct, 'By'), 'By/F')
228 dataTree.Branch('Bz', ROOT.AddressOf(dStruct, 'Bz'), 'Bz/F')
229
230 # Open text file and process the information
231 iLine = 0
232
233 # Number of bins initialised by reading first line
234 Nx = 0
235 Ny = 0
236 Nz = 0
237 Nzy = 0
238
239 with open(inFileName, 'r') as f:
240
241 for line in f:
242 iLine += 1
243 sLine = line.split()
244
245 # First line contains ranges
246 if iLine == 1:
247 rStruct.xMin = float(sLine[1])
248 rStruct.xMax = float(sLine[2])
249 rStruct.dx = float(sLine[3])
250 rStruct.yMin = float(sLine[4])
251 rStruct.yMax = float(sLine[5])
252 rStruct.dy = float(sLine[6])
253 rStruct.zMin = float(sLine[7])
254 rStruct.zMax = float(sLine[8])
255 rStruct.dz = float(sLine[9])
256
257 Nx = int(((rStruct.xMax - rStruct.xMin)/rStruct.dx) + 1.0)
258 Ny = int(((rStruct.yMax - rStruct.yMin)/rStruct.dy) + 1.0)
259 Nz = int(((rStruct.zMax - rStruct.zMin)/rStruct.dz) + 1.0)
260 Nzy = Nz*Ny
261
262 print('Nx = {0}, Ny = {1}, Nz = {2}'.format(Nx, Ny, Nz))
263
264 rangeTree.Fill()
265
266 elif iLine > 2:
267
268 # B field components
269 dStruct.Bx = float(sLine[0])
270 dStruct.By = float(sLine[1])
271 dStruct.Bz = float(sLine[2])
272
273 # Also store bin centre coordinates.
274 # Map is ordered in ascending z, y, then x
275 #iBin = iLine - 3
276 #zBin = iBin%Nz
277 #yBin = int((iBin/Nz))%Ny
278 #xBin = int(iBin/Nzy)
279 #dStruct.x = rStruct.dx*(xBin + 0.5) + rStruct.xMin
280 #dStruct.y = rStruct.dy*(yBin + 0.5) + rStruct.yMin
281 #dStruct.z = rStruct.dz*(zBin + 0.5) + rStruct.zMin
282
283 dataTree.Fill()
284
285 theFile.cd()
286 rangeTree.Write()
287 dataTree.Write()
288 theFile.Close()
289
290
291if __name__ == "__main__":
292
293 run('test07_10cm_grid.table', 'MuonFilterBFieldMap1.txt')
294 #run('test08_10cm_grid.table', 'MuonFilterBFieldMap2.txt')
295 #run('test09_10cm_grid.table', 'MuonFilterBFieldMap3.txt')
296 #run('test10_10cm_grid.table', 'MuonFilterBFieldMap4.txt')
297 #run('test12_10cm_grid.table', 'MuonFilterBFieldMap5.txt')
createRootMap(inFileName, outFileName)
createTextMap(inFileName, outFileName)
run(inFileName='test07_10cm_grid.table', outFileName='MuonFilterBFieldMap1.txt')