depos.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 from wirecell import units
4 
5 import numpy
6 import matplotlib.pyplot as plt
7 
8 import json
9 import bz2
10 
11 
12 # 0123456
13 columns="xyzqtsn"
14 
15 def todict(depos):
16  'Return a dictionary of arrays instead of a 2D array.'
17  ret = dict()
18  for ind, letter in enumerate(columns):
19  ret[letter] = depos[:,ind]
20  return ret
21 
22 def remove_zero_steps(depos):
23  '''
24  For some reason sometimes zero steps are taken. This removes them
25  '''
26  ret = list()
27  for depo in depos:
28  if depo[5] == 0.0:
29  continue
30  ret.append(depo)
31  return numpy.asarray(ret)
32 
33 
34 def load(filename, jpath="depos"):
35  '''
36  Load a CWT JSON depo file and return numpy array of depo info.
37  '''
38 
39  if filename.endswith(".json"):
40  fopen = open
41  elif filename.endswith(".bz2"):
42  fopen = bz2.BZ2File
43  else:
44  return None
45 
46  with fopen(filename) as fp:
47  jdat = json.loads(fp.read())
48 
49  depos = list()
50  for jdepo in jdat["depos"]:
51  depo = tuple([jdepo.get(key,0.0) for key in columns])
52  depos.append(depo)
53  return numpy.asarray(depos)
54 
55 
56 def apply_units(depos, distance_unit, time_unit, energy_unit, step_unit=None, electrons_unit="1.0"):
57  'Apply units to a deposition array, return a new one'
58 
59  print "dtese=", distance_unit, time_unit, energy_unit, step_unit, electrons_unit,
60 
61  depos = numpy.copy(depos)
62 
63  dunit = eval(distance_unit, units.__dict__)
64  tunit = eval(time_unit, units.__dict__)
65  eunit = eval(energy_unit, units.__dict__)
66  if step_unit is None:
67  sunit = dunit
68  else:
69  sunit = eval(step_unit, units.__dict__)
70  nunit = eval(electrons_unit, units.__dict__)
71 
72  theunits = [dunit]*3 + [eunit] + [tunit] + [sunit] + [nunit]
73  for ind,unit in enumerate(theunits):
74  depos[:,ind] *= unit
75  return depos
76 
77 
78 
79 def dump(output_file, depos, jpath="depos"):
80  '''
81  Save a deposition array to JSON file
82  '''
83  jlist = list()
84  for depo in depos:
85  jdepo = {c:v for c,v in zip(columns, depo)}
86  jlist.append(jdepo)
87  out = {jpath: jlist}
88 
89  # indent for readability. If bz2 is used, there is essentially no change
90  # in file size between no indentation and indent=4. Plain JSON inflates by
91  # about 2x. bz2 is 5-10x smaller than plain JSON.
92  text = json.dumps(out, indent=4)
93 
94  if output_file.endswith(".json"):
95  fopen = open
96  elif output_file.endswith(".json.bz2"):
97  fopen = bz2.BZ2File
98  else:
99  raise IOError('Unknown file extension: "%s"' % filename)
100  with fopen(output_file, 'w') as fp:
101  fp.write(text)
102  return
103 
104 
105 
106 
107 def move(depos, offset):
108  '''
109  Return new set of depos all moved by given vector offset.
110  '''
111  offset = numpy.asarray(offset)
112  depos = numpy.copy(depos)
113  depos[:,0:3] += offset
114  return depos
115 
116 
117 def center(depos, point):
118  '''
119  Shift depositions so that they are centered on the given point
120  '''
121  point = numpy.asarray(point)
122  tot = numpy.asarray([0.0, 0.0, 0.0])
123  for depo in depos:
124  tot += depo[:3]
125  n = len(depos)
126  offset = point - tot/n
127  return move(depos, offset)
128 
129 
130 # 0123456
131 # columns="xyzqtsn"
132 def plot_hist(h, xlab, output):
133  fig = plt.figure()
134  ax = fig.add_subplot(111)
135  ax.set_xlabel(xlab)
136  ax.semilogy(h[1][:-1], h[0])
137  fig.savefig(output)
138 
139 
140 def plot_s(depos, output):
141  depos = todict(depos)
142  s = depos["s"]/units.cm
143  h = numpy.histogram(s, 1000, (0, 0.05))
144  plot_hist(h, "step [cm]", output)
145 def plot_q(depos, output):
146  depos = todict(depos)
147  q = depos["q"]/units.MeV
148  h = numpy.histogram(q, 1000, (0, 0.2))
149  plot_hist(h, "deposit [MeV]", output)
150 def plot_n(depos, output):
151  depos = todict(depos)
152  n = depos["n"]
153  h = numpy.histogram(n, 1000, (0, 10000))
154  plot_hist(h, "number [electrons]", output)
155 def plot_deds(depos, output):
156  depos = todict(remove_zero_steps(depos))
157  q = depos["q"]/units.MeV
158  s = depos["s"]/units.cm
159  h = numpy.histogram(q/s, 1000, (0,10))
160  plot_hist(h, "q/s [MeV/cm]", output)
161 def plot_dnds(depos, output):
162  depos = todict(remove_zero_steps(depos))
163  s = depos["s"]/units.cm
164  n = depos["n"]
165  h = numpy.histogram(n/s, 500, (0,5.0e5))
166  plot_hist(h, "n/s [#/cm]", output)
167 
168 
169 def plot_xz_weighted(x, z, w, title, output):
170  x = x/units.mm
171  z = z/units.mm
172  xmm = (numpy.min(x), numpy.max(x))
173  zmm = (numpy.min(z), numpy.max(z))
174 
175  # assuming data is in WCT SoU we want mm bins
176  nx = int((xmm[1] - xmm[0])/units.mm)
177  nz = int((zmm[1] - zmm[0])/units.mm)
178  print ("%d x %d pixels: " % (nx, nz))
179 
180  xedges = numpy.linspace(xmm[0], xmm[1], nx)
181  zedges = numpy.linspace(zmm[0], zmm[1], nz)
182 
183  fig = plt.figure()
184  ax = fig.add_subplot(111)
185  ax.set_title(title)
186 
187  h = ax.hist2d(x,z,bins=(xedges, zedges), weights=w)
188  ax.set_xlabel("X [mm]")
189  ax.set_ylabel("Z [mm]")
190  plt.colorbar(h[3], ax=ax)
191  fig.savefig(output)
192 
193 
194 def plot_qxz(depos, output):
195  'Plot colz q as X vs Z'
196  depos = todict(remove_zero_steps(depos))
197  x = depos["x"]
198  z = depos["z"]
199  q = depos["q"]/units.MeV
200  plot_xz_weighted(x, z, q, "q [MeV] per mm$^2$", output)
201 
202 
203 def plot_qsxz(depos, output):
204  'Plot colz q/s as X vs Z'
205  depos = todict(remove_zero_steps(depos))
206  x = depos["x"]
207  z = depos["z"]
208  q = depos["q"]/units.MeV
209  s = depos["s"]/units.cm
210  plot_xz_weighted(x, z, q/s, "q/s [MeV/cm] per mm$^2$", output)
211 
212 
213 def plot_nxz(depos, output):
214  "Plot colz number as X vs Z (transverse)"
215  depos = todict(remove_zero_steps(depos))
216  x = depos["x"]
217  z = depos["z"]
218  n = depos["n"]
219  plot_xz_weighted(x, z, n, "number e- per mm$^2$", output)
220 
221 def plot_nscat(depos, output):
222  'Plot number as scatter plot'
223  depos = todict(remove_zero_steps(depos))
224  x = depos["x"]/units.mm
225  z = depos["z"]/units.mm
226  n = depos["n"]
227 
228  nmax = float(numpy.max(n))
229  cmap = plt.get_cmap('seismic')
230 
231  sizes = [20.0*nv/nmax for nv in n]
232  colors = [cmap(nv/nmax) for nv in n]
233 
234  fig = plt.figure()
235  ax = fig.add_subplot(111)
236  ax.set_title("electrons")
237 
238  ax.set_xlabel("X [mm]")
239  ax.set_ylabel("Z [mm]")
240  #plt.colorbar(h[3], ax=ax)
241  ax.scatter(x, z, c=colors, edgecolor=colors, s=sizes)
242  fig.savefig(output)
def todict(depos)
Definition: depos.py:15
def plot_qxz(depos, output)
Definition: depos.py:194
def apply_units(depos, distance_unit, time_unit, energy_unit, step_unit=None, electrons_unit="1.0")
Definition: depos.py:56
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
def plot_dnds(depos, output)
Definition: depos.py:161
def move(depos, offset)
Definition: depos.py:107
def plot_deds(depos, output)
Definition: depos.py:155
def plot_xz_weighted(x, z, w, title, output)
Definition: depos.py:169
def plot_hist(h, xlab, output)
Definition: depos.py:132
def plot_nscat(depos, output)
Definition: depos.py:221
def plot_qsxz(depos, output)
Definition: depos.py:203
def dump(output_file, depos, jpath="depos")
Definition: depos.py:79
def plot_q(depos, output)
Definition: depos.py:145
def remove_zero_steps(depos)
Definition: depos.py:22
def plot_nxz(depos, output)
Definition: depos.py:213
def center(depos, point)
Definition: depos.py:117
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
Definition: zip.h:295
def plot_n(depos, output)
Definition: depos.py:150
def load(filename, jpath="depos")
Definition: depos.py:34
def plot_s(depos, output)
Definition: depos.py:140