xboa
File_Convert.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 #This file is a part of xboa
3 #
4 #xboa is free software: you can redistribute it and/or modify
5 #it under the terms of the GNU General Public License as published by
6 #the Free Software Foundation, either version 3 of the License, or
7 #(at your option) any later version.
8 #
9 #xboa is distributed in the hope that it will be useful,
10 #but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 #GNU General Public License for more details.
13 #
14 #You should have received a copy of the GNU General Public License
15 #along with xboa in the doc folder. If not, see
16 #<http://www.gnu.org/licenses/>.
17 #
18 """
19 Set of algorithms for transforming between different file formats and bunch structures. Reads in input command file, by default file_convert.inp, and uses information to read beam in a user specified file format and output in a different user specified file format. Command line options are:
20  -c=<filename> <filename> is the input control file (default is 'file_convert.inp')
21 e.g. ./File_Convert.py -c=my_control_data.inp
22 
23 Input file cav contain the following control variables and data, one on each line. Hash (#) or exclamation mark (!) symbols are comments.
24 
25 Mandatory data to control input and output formats:
26  file_in <filename>
27  format_in <format_string>
28  file_out <filename>
29  format_out <format_string>
30 
31 The rest of the control variables are optional:
32 If you need to define a station or region from the input file:
33  station_in <value>
34 Otherwise the routine will add all stations/regions to the output
35 
36 To perform a transformation in phase space, about some origin, to a desired covariance matrix:
37  rotate <variable1> <variable2> ... one label for each axis in the rotation
38  origin <variable1> <value>
39  origin <variable2> <value>
40  ...
41  covariance <variable1> <variable2> <value>
42 If not defined, values default to 0. The covariance matrix should be symmetric and positive definite. The rotation will be scaled such that emittance is conserved. If called as a python script, this function requires a correct installation of NumPy on the user's PC
43 
44 To perform a translation in phase space:
45  translate <variable1> <value1> <variable2> <value2> ... one variable/value pair for each variable to be translated
46 
47 To enforce E^2 + p^2 = m^2:
48  mass_shell_condition <momentum_variable>
49 <momentum_variable> should be one of energy, p, px, py, pz. This is the variable that is changed to maintain the mass shell condition
50 
51 To make 1d histograms or 2d scatter plots of either input or output data:
52  plot_format <format> (default is png)
53  scatter_in <x-axis_variable> <x-units> <y-axis_variable> <y-units>
54  ... one line for each histogram
55  scatter_out <x-axis_variable> <x-units> <y-axis_variable> <y-units>
56  ... one line for each histogram
57  histogram_in <x-axis_variable> <x-units>
58  ... one line for each histogram
59  histogram_out <x-axis_variable> <x-units>
60  ... one line for each histogram
61 You can do as many of these as you like. If called as python script, this function requires a correct PyRoot installation on the user's PC
62 
63 The routine goes like:
64 (i) read input data
65 (ii) make input plots
66 (iii) apply rotation
67 (iv) apply translation
68 (v) make output plots
69 (vi) write output data
70 
71 Possible formats are:
72  icool_for009
73  icool_for003
74  g4beamline_bl_track_file
75  g4mice_special_hit
76 
77 Possible variables are:
78  local_weight
79  energy
80  pid
81  ey
82  ex
83  ez
84  pz
85  px
86  py
87  station
88  status
89  proper_time
90  path_length
91  sx
92  bx
93  by
94  bz
95  sz
96  sy
97  particleNumber
98  eventNumber
99  mass
100  t
101  y
102  x
103  z
104  x'
105  y'
106  p
107  global_weight
108  t'
109 
110 Possible units are:
111  GeV
112  cm
113  GeV/c2
114  GeV/c
115  MeV
116  GHz
117  GV/m
118  mus
119  Gauss
120  mum
121  ns
122  GV
123  degree
124  MeV/c2
125  mT
126  echarge
127  T
128  kT
129  coulomb
130  mm
131  m
132  radians
133  km
134  s
135  MV
136  MHz
137  GV/mm
138  MeV/c
139 
140 Obviously feel free to take this python script as a basis to hack with...
141 """
142 
143 try:
144  import common
145  import hit
146  from hit import Hit
147  import bunch
148  from bunch import Bunch
149 except ImportError:
150  print 'Error during x-boa import. Check your x-boa installation is in the PYTHONPATH environment variable'
151  raise ImportError
152 
153 try:
154  import sys
155  import copy
156  import operator
157  import math
158  import string
159 except ImportError:
160  print 'Error during python import. Check your python installation.'
161  raise ImportError
162 
163 debug = False #Set to true for full error output
165 def file_convert(control_file):
166  lines = read_control(control_file)
167  bunch = read_input(lines)
168  plots(lines, bunch, True)
169  rotate(lines, bunch)
170  translate(lines, bunch)
171  mass_shell_condition(lines, bunch)
172  plots(lines, bunch, False)
173  write_output(lines, bunch)
174 
175 def read_control(filename):
176  fh = open(filename)
177  lines = fh.readlines()
178  lines_read = []
179  for i in range( len(lines) ): #strip comments then split into words
180  (line,dummy,dummy) = lines[i].partition('#')
181  (line,dummy,dummy) = line.partition('!')
182  line = line.split()
183  if len(line) > 0: lines_read.append(line)
184  return lines_read
185 
186 def read_input(lines):
187  file_in = ''
188  format_in = ''
189  station = None
190  for line in lines:
191  if line[0] == 'file_in': file_in = line[1]
192  if line[0] == 'format_in': format_in = line[1]
193  if line[0] == 'station_in': station = int(line[1])
194  if station == None:
195  print 'Reading file \''+file_in+'\' of type \''+format_in+'\''
196  bunch = Bunch.new_from_read_builtin(format_in, file_in)
197  else:
198  print 'Reading station',station,'from file \''+file_in+'\' of type \''+format_in+'\''
199  bunch = Bunch.new_dict_from_read_builtin(format_in, file_in)[station]
200  print 'Loaded',bunch
201  return bunch
202 
203 def write_output(lines, bunch):
204  file_out = ''
205  format_out = ''
206  for line in lines:
207  if line[0] == 'file_out': file_out = line[1]
208  if line[0] == 'format_out': format_out = line[1]
209  bunch.hit_write_builtin(format_out, file_out)
210  print 'Written a',format_out,'file to',file_out
211 
212 def rotate(lines, bunch):
213  variables = []
214  origin = {}
215  for line in lines:
216  if line[0] == 'rotate':
217  for i in range(1,len(line)): variables.append(line[i])
218  if line[0] == 'origin': origin[line[1]] = float(line[2])
219  if len(variables) <= 1: return
220  import numpy
221  target_matrix = numpy.zeros( (len(variables),len(variables)))
222  for line in lines:
223  if line[0] == 'covariance':
224  i1 = variables.index(line[1])
225  i2 = variables.index(line[2])
226  target_matrix[i1,i2] = float(line[3])
227  target_matrix[i2,i1] = float(line[3])
228  print 'Rotation in variables\n',variables,'\nto matrix\n',target_matrix,'\nabout origin\n',origin
229  bunch.transform_to(variables, target_matrix, origin)
230  print 'gives\n',bunch.covariance_matrix(variables, origin)
231 
232 def translate(lines, bunch):
233  translation = {}
234  for line in lines:
235  if line[0] == 'translate':
236  for i in range(1,len(line),2):
237  translation[ line[i] ] = float(line[i+1])
238  print 'Translating through\n',translation
239  bunch.translate(translation)
240 
241 def mass_shell_condition(lines, bunch):
242  for line in lines:
243  if line[0] == 'mass_shell_condition':
244  print 'Changing momentum variable',line[1],'to force E^2 = p^2 + m^2'
245  for hit in bunch:
246  hit.mass_shell_condition(line[1])
247  return
248 
249 def plots(lines, bunch, do_in):
250  histogram_format = 'png'
251  print 'Making plots'
252  for line in lines:
253  if line[0] == 'histogram_format': histogram_format = line[0]
254  for line in lines:
255  if line[0] == 'histogram_in' and do_in: bunch.root_histogram(line[1], line[2]).Print(line[1]+'_in.'+histogram_format)
256  if line[0] == 'histogram_out' and not do_in: bunch.root_histogram(line[1], line[2]).Print(line[1]+'_out.'+histogram_format)
257  if line[0] == 'scatter_in' and do_in: bunch.root_scatter_graph(line[1], line[3], line[2], line[4])\
258  .Print(line[1]+'_vs_'+line[3]+'_in.'+histogram_format)
259  if line[0] == 'scatter_out' and not do_in: bunch.root_scatter_graph(line[1], line[3], line[2], line[4])\
260  .Print(line[1]+'_vs_'+line[3]+'_out.'+histogram_format)
261 
262 def main(argv=None):
263  contname = 'file_convert.inp'
264  if len(sys.argv) > 1:
265  (arg_name,dummy,argument) = sys.argv[1].partition('=')
266  if arg_name == '-c': contname = argument
267  else: print 'Warning - didnt recognise command line argument',arg
268 
269  if sys.argv[0].find( 'File_Convert' ) > -1:
270  if debug: file_convert(contname)
271  else:
272  try: file_convert(contname)
273  except Exception, error:
274  print 'There was a problem during execution. Error was:\n',error
275 
276 if __name__ == "__main__":
277  sys.exit(main())