summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gpu.py6
-rw-r--r--likelihood.py74
-rwxr-xr-xsim.py15
3 files changed, 85 insertions, 10 deletions
diff --git a/gpu.py b/gpu.py
index eeb759e..ff8db8c 100644
--- a/gpu.py
+++ b/gpu.py
@@ -240,9 +240,9 @@ class GPU(object):
assert len(photons.polarizations) == self.nphotons
assert len(photons.wavelengths) == self.nphotons
- self.positions_gpu = gpuarray.to_gpu(to_float3(photons.positions))#.astype(np.float32).view(gpuarray.vec.float3))
- self.directions_gpu = gpuarray.to_gpu(to_float3(photons.directions))#.astype(np.float32).view(gpuarray.vec.float3))
- self.polarizations_gpu = gpuarray.to_gpu(to_float3(photons.polarizations))#.astype(np.float32).view(gpuarray.vec.float3))
+ self.positions_gpu = gpuarray.to_gpu(to_float3(photons.positions))
+ self.directions_gpu = gpuarray.to_gpu(to_float3(photons.directions))
+ self.polarizations_gpu = gpuarray.to_gpu(to_float3(photons.polarizations))
self.wavelengths_gpu = gpuarray.to_gpu(photons.wavelengths.astype(np.float32))
if photons.times is not None:
diff --git a/likelihood.py b/likelihood.py
new file mode 100644
index 0000000..f0323fe
--- /dev/null
+++ b/likelihood.py
@@ -0,0 +1,74 @@
+import numpy as np
+from histogram import HistogramDD
+from uncertainties import ufloat, umath
+from itertools import izip, compress
+
+class Likelihood(object):
+ "Class to evaluate likelihoods for detector events."
+ def __init__(self, sim, event=None):
+ """
+ Args:
+ - sim: chroma.sim.Simulation
+ The simulation object used to simulate events and build pdfs.
+ - event: chroma.event.Event, *optional*
+ The detector event being reconstructed. If None, you must call
+ set_event() before eval().
+ """
+ self.sim = sim
+
+ if event is not None:
+ self.set_event(event)
+
+ self.pdfs = dict(zip(sim.detector.pmtids,[HistogramDD((100,10), range=[(0.0,1000.0),(-0.5,9.5)])]*len(sim.detector.pmtids)))
+
+ def set_event(self, event):
+ "Set the detector event being reconstructed."
+ self.event = event
+
+ def eval(self, vertex_generator, nevals):
+ """
+ Return the negative log likelihood that the detector event set in the
+ constructor or by set_event() was the result of a particle generated
+ by `vertex_generator`.
+ """
+ for pdf in self.pdfs.values():
+ pdf.reset()
+
+ for ev in self.sim.simulate(nevals, vertex_generator):
+ for i, t, q in compress(izip(range(ev.hits.hit.size),ev.hits.t,ev.hits.q),ev.hits.hit):
+ self.pdfs[i].fill((ev.hits.t[i],ev.hits.q[i]))
+
+ for pdf in self.pdfs.values():
+ if pdf.nentries > 0:
+ pdf.normalize()
+
+ log_likelihood = ufloat((0,0))
+
+ for i, t, q in compress(izip(range(self.event.channels.hit.size),self.event.channels.t,self.event.channels.q),self.event.channels.hit):
+ probability = self.pdfs[i].ueval((t,q)).item()
+
+ if probability.nominal_value == 0.0:
+ if self.pdfs[i].nentries > 0:
+ probability = ufloat([0.5/self.pdfs[i].nentries]*2)
+ else:
+ probability = ufloat([1.0/len(self.pdfs[i].bincenters)]*2)
+
+ log_likelihood += umath.log(probability)
+
+ return -log_likelihood
+
+if __name__ == '__main__':
+ from chroma import detectors
+ from chroma.sim import Simulation
+ from chroma.optics import water
+ from chroma.generator import constant_particle_gun
+
+ detector = detectors.find('minilbne')
+ sim = Simulation(detector, water)
+
+ event = sim.simulate(1, constant_particle_gun('e-',(0,0,0),(1,0,0),100.0)).next()
+
+ likelihood = Likelihood(sim, event)
+
+ for x in np.linspace(-1.0, 1.0, 20):
+ print 'x = %f, %s' % (x, likelihood.eval(constant_particle_gun('e-',(x,0,0),(1,0,0),100.0),100))
diff --git a/sim.py b/sim.py
index c52a071..3336f4d 100755
--- a/sim.py
+++ b/sim.py
@@ -1,6 +1,5 @@
#!/usr/bin/env python
import sys
-import optparse
import time
import os
import numpy as np
@@ -80,6 +79,7 @@ class Simulation(object):
if run_daq:
ev.hits = self.gpu_worker.get_hits()
+ ev.channels = ev.hits
yield ev
@@ -90,7 +90,9 @@ class Simulation(object):
@profile_if_possible
def main():
- parser = optparse.OptionParser('%prog')
+ import optparse
+
+ parser = optparse.OptionParser('%prog filename')
parser.add_option('-b', type='int', dest='nbits', default=11)
parser.add_option('-j', type='int', dest='device', default=None)
parser.add_option('-s', type='int', dest='seed', default=None,
@@ -111,15 +113,14 @@ def main():
help='Save final photon vertices to disk')
options, args = parser.parse_args()
- if len(args) != 1:
- print 'Must specify output filename!'
- sys.exit(1)
+
+ if len(args) < 1:
+ sys.exit(parser.format_help())
else:
output_filename = args[0]
if options.nevents <= 0:
- print '--nevents must be greater than 0!'
- sys.exit(1)
+ sys.exit('--nevents must be greater than 0!')
position = np.array(eval(options.pos), dtype=float)
direction = np.array(eval(options.dir), dtype=float)