Esempio n. 1
0
    def write_event(self, pyev):
        "Write an event.Event object to the ROOT tree as a ROOT.Event object."
        self.ev.id = pyev.id

        if pyev.primary_vertex is not None:
            self.ev.primary_vertex.particle_name = \
                pyev.primary_vertex.particle_name
            self.ev.primary_vertex.pos.SetXYZ(*pyev.primary_vertex.pos)
            self.ev.primary_vertex.dir.SetXYZ(*pyev.primary_vertex.dir)
            if pyev.primary_vertex.pol is not None:
                self.ev.primary_vertex.pol.SetXYZ(*pyev.primary_vertex.pol)
            self.ev.primary_vertex.ke = pyev.primary_vertex.ke
            self.ev.primary_vertex.t0 = pyev.primary_vertex.t0

        if pyev.photons_beg is not None:
            photons = pyev.photons_beg
            ROOT.fill_photons(self.ev.photons_beg,
                              len(photons.pos),
                              photons.pos.ravel(),
                              photons.dir.ravel(),
                              photons.pol.ravel(),
                              photons.wavelengths, photons.t,
                              photons.last_hit_triangles, photons.flags)

        if pyev.photons_end is not None:
            photons = pyev.photons_end
            ROOT.fill_photons(self.ev.photons_end,
                              len(photons.pos),
                              photons.pos.ravel(),
                              photons.dir.ravel(),
                              photons.pol.ravel(),
                              photons.wavelengths, photons.t,
                              photons.last_hit_triangles, photons.flags)

        self.ev.vertices.resize(0)
        if pyev.vertices is not None:
            self.ev.vertices.resize(len(pyev.vertices))
            for i, vertex in enumerate(pyev.vertices):
                self.ev.vertices[i].particle_name = vertex.particle_name
                self.ev.vertices[i].pos.SetXYZ(*vertex.pos)
                self.ev.vertices[i].dir.SetXYZ(*vertex.dir)
                if vertex.pol is not None:
                    self.ev.vertices[i].pol.SetXYZ(*vertex.pol)
                self.ev.vertices[i].ke = vertex.ke
                self.ev.vertices[i].t0 = vertex.t0

        if pyev.channels is not None:
            nhit = count_nonzero(pyev.channels.hit)
            if nhit > 0:
                ROOT.fill_channels(self.ev, nhit, np.arange(len(pyev.channels.t))[pyev.channels.hit].astype(np.uint32), pyev.channels.t, pyev.channels.q, pyev.channels.flags, len(pyev.channels.hit))
            else:
                self.ev.nhit = 0
                self.ev.channels.resize(0)
                self.ev.nchannels = len(pyev.channels.hit)
        else:
            self.ev.nhit = 0
            self.ev.channels.resize(0)
            self.ev.nchannels = 0

        self.T.Fill()
Esempio n. 2
0
    def setup_pdf_eval(self, event_hit, event_time, event_charge, min_twidth,
                       trange, min_qwidth, qrange, min_bin_content=10,
                       time_only=True):
        """Setup GPU arrays to compute PDF values for the given event.
        The pdf_eval calculation allows the PDF to be evaluated at a
        single point for each channel as the Monte Carlo is run.  The
        effective bin size will be as small as (`min_twidth`,
        `min_qwidth`) around the point of interest, but will be large
        enough to ensure that `min_bin_content` Monte Carlo events
        fall into the bin.

            event_hit: ndarray
              Hit or not-hit status for each channel in the detector.
            event_time: ndarray
              Hit time for each channel in the detector.  If channel 
              not hit, the time will be ignored.
            event_charge: ndarray
              Integrated charge for each channel in the detector.
              If channel not hit, the charge will be ignored.

            min_twidth: float
              Minimum bin size in the time dimension
            trange: (float, float)
              Range of time dimension in PDF
            min_qwidth: float
              Minimum bin size in charge dimension
            qrange: (float, float)
              Range of charge dimension in PDF
            min_bin_content: int
              The bin will be expanded to include at least this many events
            time_only: bool
              If True, only the time observable will be used in the PDF.
        """
        self.event_nhit = count_nonzero(event_hit)
        
        # Define a mapping from an array of len(event_hit) to an array of length event_nhit
        self.map_hit_offset_to_channel_id = np.where(event_hit)[0].astype(np.uint32)
        self.map_hit_offset_to_channel_id_gpu = ga.to_gpu(self.map_hit_offset_to_channel_id)
        self.map_channel_id_to_hit_offset = np.maximum(0, event_hit.cumsum() - 1).astype(np.uint32)
        self.map_channel_id_to_hit_offset_gpu = ga.to_gpu(self.map_channel_id_to_hit_offset)

        self.event_hit_gpu = ga.to_gpu(event_hit.astype(np.uint32))
        self.event_time_gpu = ga.to_gpu(event_time.astype(np.float32))
        self.event_charge_gpu = ga.to_gpu(event_charge.astype(np.float32))

        self.eval_hitcount_gpu = ga.zeros(len(event_hit), dtype=np.uint32)
        self.eval_bincount_gpu = ga.zeros(len(event_hit), dtype=np.uint32)
        self.nearest_mc_gpu = ga.empty(shape=self.event_nhit * min_bin_content, 
                                             dtype=np.float32)
        self.nearest_mc_gpu.fill(1e9)
        
        self.min_twidth = min_twidth
        self.trange = trange
        self.min_qwidth = min_qwidth
        self.qrange = qrange
        self.min_bin_content = min_bin_content

        assert time_only # Only support time right now
        self.time_only = time_only
Esempio n. 3
0
    def setup_pdf_eval(self, event_hit, event_time, event_charge, min_twidth,
                       trange, min_qwidth, qrange, min_bin_content=10,
                       time_only=True):
        """Setup GPU arrays to compute PDF values for the given event.
        The pdf_eval calculation allows the PDF to be evaluated at a
        single point for each channel as the Monte Carlo is run.  The
        effective bin size will be as small as (`min_twidth`,
        `min_qwidth`) around the point of interest, but will be large
        enough to ensure that `min_bin_content` Monte Carlo events
        fall into the bin.

            event_hit: ndarray
              Hit or not-hit status for each channel in the detector.
            event_time: ndarray
              Hit time for each channel in the detector.  If channel 
              not hit, the time will be ignored.
            event_charge: ndarray
              Integrated charge for each channel in the detector.
              If channel not hit, the charge will be ignored.

            min_twidth: float
              Minimum bin size in the time dimension
            trange: (float, float)
              Range of time dimension in PDF
            min_qwidth: float
              Minimum bin size in charge dimension
            qrange: (float, float)
              Range of charge dimension in PDF
            min_bin_content: int
              The bin will be expanded to include at least this many events
            time_only: bool
              If True, only the time observable will be used in the PDF.
        """
        self.event_nhit = count_nonzero(event_hit)
        
        # Define a mapping from an array of len(event_hit) to an array of length event_nhit
        self.map_hit_offset_to_channel_id = np.where(event_hit)[0].astype(np.uint32)
        self.map_hit_offset_to_channel_id_gpu = ga.to_gpu(self.map_hit_offset_to_channel_id)
        self.map_channel_id_to_hit_offset = np.maximum(0, event_hit.cumsum() - 1).astype(np.uint32)
        self.map_channel_id_to_hit_offset_gpu = ga.to_gpu(self.map_channel_id_to_hit_offset)

        self.event_hit_gpu = ga.to_gpu(event_hit.astype(np.uint32))
        self.event_time_gpu = ga.to_gpu(event_time.astype(np.float32))
        self.event_charge_gpu = ga.to_gpu(event_charge.astype(np.float32))

        self.eval_hitcount_gpu = ga.zeros(len(event_hit), dtype=np.uint32)
        self.eval_bincount_gpu = ga.zeros(len(event_hit), dtype=np.uint32)
        self.nearest_mc_gpu = ga.empty(shape=self.event_nhit * min_bin_content, 
                                             dtype=np.float32)
        self.nearest_mc_gpu.fill(1e9)
        
        self.min_twidth = min_twidth
        self.trange = trange
        self.min_qwidth = min_qwidth
        self.qrange = qrange
        self.min_bin_content = min_bin_content

        assert time_only # Only support time right now
        self.time_only = time_only
Esempio n. 4
0
    def testAbort(self):
        '''Photons that hit a triangle at normal incidence should not abort.

        Photons that hit a triangle at exactly normal incidence can sometimes
        produce a dot product that is outside the range allowed by acos().
        Trigger these with axis aligned photons in a box.
        '''

        # Setup geometry
        cube = Geometry(vacuum)
        cube.add_solid(Solid(box(100, 100, 100), vacuum, vacuum))
        geo = create_geometry_from_obj(cube, update_bvh_cache=False)

        # Initialize simulation (without geant4)
        sim = Simulation(geo, geant4_processes=0)

        # Create initial photons
        nphotons = 5
        pos = np.tile([0, 0, 0], (nphotons, 1)).astype(np.float32)
        dir = np.tile([0, 0, 1], (nphotons, 1)).astype(np.float32)
        pol = np.zeros_like(pos)
        phi = np.random.uniform(0, 2 * np.pi, nphotons).astype(np.float32)
        pol[:, 0] = np.cos(phi)
        pol[:, 1] = np.sin(phi)
        t = np.zeros(nphotons, dtype=np.float32)
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(400.0)

        photons = Photons(pos=pos,
                          dir=dir,
                          pol=pol,
                          t=t,
                          wavelengths=wavelengths)

        # First make one step to check for strangeness
        photons_end = sim.simulate([photons],
                                   keep_photons_end=True,
                                   max_steps=1).next().photons_end
        print "FIRST STEP"
        print photons_end.pos[0:10]

        self.assertFalse(np.isnan(photons_end.pos).any())
        self.assertFalse(np.isnan(photons_end.dir).any())
        self.assertFalse(np.isnan(photons_end.pol).any())
        self.assertFalse(np.isnan(photons_end.t).any())
        self.assertFalse(np.isnan(photons_end.wavelengths).any())

        # Now let it run the usual ten steps
        photons_end = sim.simulate([photons],
                                   keep_photons_end=True,
                                   max_steps=10).next().photons_end
        aborted = (photons_end.flags & (1 << 31)) > 0
        print 'aborted photon fracttion: %1.1f' % (
            float(count_nonzero(aborted)) / nphotons)
        self.assertFalse(aborted.any())
        print "LAST STEPS"
        print photons_end.pos[0:10]
Esempio n. 5
0
    def testAbort(self):
        '''Photons that hit a triangle at normal incidence should not abort.

        Photons that hit a triangle at exactly normal incidence can sometimes
        produce a dot product that is outside the range allowed by acos().
        Trigger these with axis aligned photons in a box.
        '''

        # Setup geometry
        cube = Geometry(vacuum)
        cube.add_solid(Solid(box(100,100,100), vacuum, vacuum))
        geo = create_geometry_from_obj(cube, update_bvh_cache=False)
        sim = Simulation(geo, geant4_processes=0)

        # Create initial photons
        nphotons = 10000
        pos = np.tile([0,0,0], (nphotons,1)).astype(np.float32)
        dir = np.tile([0,0,1], (nphotons,1)).astype(np.float32)
        pol = np.zeros_like(pos)
        phi = np.random.uniform(0, 2*np.pi, nphotons).astype(np.float32)
        pol[:,0] = np.cos(phi)
        pol[:,1] = np.sin(phi)
        t = np.zeros(nphotons, dtype=np.float32)
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(400.0)

        photons = Photons(pos=pos, dir=dir, pol=pol, t=t,
                          wavelengths=wavelengths)

        # First make one step to check for strangeness
        photons_end = sim.simulate([photons], keep_photons_end=True,
                                   max_steps=1).next().photons_end

        self.assertFalse(np.isnan(photons_end.pos).any())
        self.assertFalse(np.isnan(photons_end.dir).any())
        self.assertFalse(np.isnan(photons_end.pol).any())
        self.assertFalse(np.isnan(photons_end.t).any())
        self.assertFalse(np.isnan(photons_end.wavelengths).any())

        # Now let it run the usual ten steps
        photons_end = sim.simulate([photons], keep_photons_end=True,
                                   max_steps=10).next().photons_end
        aborted = (photons_end.flags & (1 << 31)) > 0
        print 'aborted photons: %1.1f' % \
            (float(count_nonzero(aborted)) / nphotons)
        self.assertFalse(aborted.any())
Esempio n. 6
0
    def write_event(self, pyev):
        "Write an event.Event object to the ROOT tree as a ROOT.Event object."
        self.ev.id = pyev.id

        if pyev.photons_beg is not None:
            photons = pyev.photons_beg
            ROOT.fill_photons(self.ev.photons_beg, len(photons.pos),
                              photons.pos.ravel(), photons.dir.ravel(),
                              photons.pol.ravel(), photons.wavelengths,
                              photons.t, photons.last_hit_triangles,
                              photons.flags)

        if pyev.photons_end is not None:
            photons = pyev.photons_end
            ROOT.fill_photons(self.ev.photons_end, len(photons.pos),
                              photons.pos.ravel(), photons.dir.ravel(),
                              photons.pol.ravel(), photons.wavelengths,
                              photons.t, photons.last_hit_triangles,
                              photons.flags)

        self.ev.vertices.resize(0)
        if pyev.vertices is not None:
            self.ev.vertices.resize(len(pyev.vertices))
            for i, vertex in enumerate(pyev.vertices):
                python_vertex_to_root_vertex(vertex, self.ev.vertices[i])

        if pyev.channels is not None:
            nhit = count_nonzero(pyev.channels.hit)
            if nhit > 0:
                ROOT.fill_channels(
                    self.ev, nhit,
                    np.arange(len(pyev.channels.t))[pyev.channels.hit].astype(
                        np.uint32), pyev.channels.t, pyev.channels.q,
                    pyev.channels.flags, len(pyev.channels.hit))
            else:
                self.ev.nhit = 0
                self.ev.channels.resize(0)
                self.ev.nchannels = len(pyev.channels.hit)
        else:
            self.ev.nhit = 0
            self.ev.channels.resize(0)
            self.ev.nchannels = 0

        self.T.Fill()
Esempio n. 7
0
    def write_event(self, pyev):
        "Write an event.Event object to the ROOT tree as a ROOT.Event object."
        self.ev.id = pyev.id

        if pyev.photons_beg is not None:
            photons = pyev.photons_beg
            ROOT.fill_photons(self.ev.photons_beg,
                              len(photons.pos),
                              photons.pos.ravel(),
                              photons.dir.ravel(),
                              photons.pol.ravel(),
                              photons.wavelengths, photons.t,
                              photons.last_hit_triangles, photons.flags)

        if pyev.photons_end is not None:
            photons = pyev.photons_end
            ROOT.fill_photons(self.ev.photons_end,
                              len(photons.pos),
                              photons.pos.ravel(),
                              photons.dir.ravel(),
                              photons.pol.ravel(),
                              photons.wavelengths, photons.t,
                              photons.last_hit_triangles, photons.flags)

        self.ev.vertices.resize(0)
        if pyev.vertices is not None:
            self.ev.vertices.resize(len(pyev.vertices))
            for i, vertex in enumerate(pyev.vertices):
                python_vertex_to_root_vertex(vertex,self.ev.vertices[i])

        if pyev.channels is not None:
            nhit = count_nonzero(pyev.channels.hit)
            if nhit > 0:
                ROOT.fill_channels(self.ev, nhit, np.arange(len(pyev.channels.t))[pyev.channels.hit].astype(np.uint32), pyev.channels.t, pyev.channels.q, pyev.channels.flags, len(pyev.channels.hit))
            else:
                self.ev.nhit = 0
                self.ev.channels.resize(0)
                self.ev.nchannels = len(pyev.channels.hit)
        else:
            self.ev.nhit = 0
            self.ev.channels.resize(0)
            self.ev.nchannels = 0

        self.T.Fill()
Esempio n. 8
0
    from chroma.demo import detector as build_detector
    from chroma.sim import Simulation
    from chroma.generator import constant_particle_gun
    from chroma import tools
    import time

    tools.enable_debug_on_crash()

    detector = build_detector()
    sim = Simulation(detector, seed=0)

    event = sim.simulate(
        islice(constant_particle_gun('e-', (0, 0, 0), (1, 0, 0), 100.0),
               1)).next()

    print 'nhit = %i' % count_nonzero(event.channels.hit)

    likelihood = Likelihood(sim, event)

    x = np.linspace(-10.0, 10.0, 100)
    l = []

    for pos in izip(x, repeat(0), repeat(0)):
        t0 = time.time()
        ev_vertex_iter = constant_particle_gun('e-', pos, (1, 0, 0), 100.0)
        l.append(likelihood.eval(ev_vertex_iter, 1000))
        elapsed = time.time() - t0

        print '(%.1f, %.1f, %.1f), %s (%1.1f sec)' % \
            (pos[0], pos[1], pos[2], tools.ufloat_to_str(l[-1]), elapsed)
Esempio n. 9
0
if __name__ == '__main__':
    from chroma.demo import detector as build_detector
    from chroma.sim import Simulation
    from chroma.generator import constant_particle_gun
    from chroma import tools
    import time

    tools.enable_debug_on_crash()

    detector = build_detector()
    sim = Simulation(detector, seed=0)

    event = sim.simulate(islice(constant_particle_gun('e-',(0,0,0),(1,0,0),100.0), 1)).next()

    print 'nhit = %i' % count_nonzero(event.channels.hit)

    likelihood = Likelihood(sim, event)

    x = np.linspace(-10.0, 10.0, 100)
    l = []

    for pos in izip(x, repeat(0), repeat(0)):
        t0 = time.time()
        ev_vertex_iter = constant_particle_gun('e-',pos,(1,0,0),100.0)
        l.append(likelihood.eval(ev_vertex_iter, 1000))
        elapsed = time.time() - t0

        print '(%.1f, %.1f, %.1f), %s (%1.1f sec)' % \
            (pos[0], pos[1], pos[2], tools.ufloat_to_str(l[-1]), elapsed)