diff options
Diffstat (limited to 'generator/photon.py')
-rw-r--r-- | generator/photon.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/generator/photon.py b/generator/photon.py new file mode 100644 index 0000000..dcfc292 --- /dev/null +++ b/generator/photon.py @@ -0,0 +1,74 @@ +import g4gen +import multiprocessing +import threading +import numpy as np +import itertools + +class G4GeneratorProcess(multiprocessing.Process): + def __init__(self, idnum, material, input_queue, output_queue, seed=None): + multiprocessing.Process.__init__(self) + + self.idnum = idnum + self.material = material + self.input_queue = input_queue + self.output_queue = output_queue + self.seed = seed + self.daemon = True + + def run(self): + gen = g4gen.G4Generator(self.material, seed=self.seed) + while True: + ev = self.input_queue.get() + ev.photon_start = gen.generate_photons(ev) + self.output_queue.put(ev) + +class G4VertexGeneratorProcess(multiprocessing.Process): + def __init__(self, vertex_iterator, queue): + multiprocessing.Process.__init__(self) + self.vertex_iterator = vertex_iterator + self.queue = queue + + def run(self): + for ev in self.vertex_iterator: + self.queue.put(ev) + +def partition(num, partitions): + '''Generator that returns num//partitions, with the last item including the remainder. + + Useful for partitioning a number into mostly equal parts while preserving the sum. + + >>> list(partition(800, 3)) + [266, 266, 268] + >>> sum(list(partition(800, 3))) + 800 + ''' + step = num // partitions + for i in xrange(partitions): + if i < partitions - 1: + yield step + else: + yield step + (num % partitions) + +def queue_iterator(nelements, queue): + for i in xrange(nelements): + yield queue.get() + +class G4ParallelGenerator(object): + def __init__(self, nprocesses, material, base_seed=None): + self.material = material + self.vertex_queue = multiprocessing.Queue() + self.photon_queue = multiprocessing.Queue() + self.processes = [ G4GeneratorProcess(i, material, self.vertex_queue, self.photon_queue, seed=base_seed + i) + for i in xrange(nprocesses) ] + for p in self.processes: + p.start() + + def generate_events(self, nevents, vertex_iterator): + # Doing this to avoid a deadlock caused by putting to one queue while getting from another + for ev in itertools.islice(vertex_iterator, nevents): + self.vertex_queue.put(ev) + + return queue_iterator(nevents, self.photon_queue) + + + |