示例#1
0
    def _extract_photons_from_tracking_action(self, sort=True):
        n = self.tracking_action.GetNumPhotons()
        pos = np.zeros(shape=(n, 3), dtype=np.float32)
        pos[:, 0] = self.tracking_action.GetX()
        pos[:, 1] = self.tracking_action.GetY()
        pos[:, 2] = self.tracking_action.GetZ()

        dir = np.zeros(shape=(n, 3), dtype=np.float32)
        dir[:, 0] = self.tracking_action.GetDirX()
        dir[:, 1] = self.tracking_action.GetDirY()
        dir[:, 2] = self.tracking_action.GetDirZ()

        pol = np.zeros(shape=(n, 3), dtype=np.float32)
        pol[:, 0] = self.tracking_action.GetPolX()
        pol[:, 1] = self.tracking_action.GetPolY()
        pol[:, 2] = self.tracking_action.GetPolZ()

        wavelengths = self.tracking_action.GetWavelength().astype(np.float32)

        t0 = self.tracking_action.GetT0().astype(np.float32)

        if sort:
            reorder = argsort_direction(dir)
            pos = pos[reorder]
            dir = dir[reorder]
            pol = pol[reorder]
            wavelengths = wavelengths[reorder]
            t0 = t0[reorder]

        return Photons(pos, dir, pol, wavelengths, t0)
示例#2
0
    def testCharge(self):
        '''Test PMT charge distribution'''

        # Run only one photon at a time
        nphotons = 1
        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)

        hit_charges = []
        for ev in self.sim.simulate(photons for i in xrange(1000)):
            if ev.channels.hit[0]:
                hit_charges.append(ev.channels.q[0])
        hit_charges = np.array(hit_charges)
        self.assertAlmostEqual(hit_charges.mean(), 1.0, delta=1e-1)
        self.assertAlmostEqual(hit_charges.std(), 0.1, delta=1e-1)
示例#3
0
    def testWorkQueue(self):

        # Run only one photon at a time
        nphotons = 32 * 12

        dphi = np.random.uniform(0, 2.0 * np.pi, nphotons)
        dcos = np.random.uniform(-1.0, 1.0, nphotons)
        dir = np.array(zip(
            np.sqrt(1 - dcos[:] * dcos[:]) * np.cos(dphi[:]),
            np.sqrt(1 - dcos[:] * dcos[:]) * np.sin(dphi[:]), dcos[:]),
                       dtype=np.float32)
        pos = np.tile([0, 0, 0], (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)
        pol = np.cross(pol, dir)
        for n, p in enumerate(pol):
            norm = np.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2])
            p /= norm

        t = np.zeros(nphotons,
                     dtype=np.float32) + 100.0  # Avoid negative photon times
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(128.0)

        photons = Photons(pos=pos,
                          dir=dir,
                          pol=pol,
                          t=t,
                          wavelengths=wavelengths)
示例#4
0
    def testTime(self):
        '''Test PMT time distribution'''

        # Run only one photon at a time
        nphotons = 1
        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) + 100.0  # Avoid negative photon times
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(400.0)

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

        hit_times = []
        for ev in self.sim.simulate((photons for i in xrange(500)),
                                    keep_photons_end=True,
                                    keep_photons_beg=True):
            #for ev in self.sim.simulate(photons for i in xrange(5)):
            if ev.channels.hit[0]:
                hit_times.append(ev.channels.t[0])
            print "Hits: ", ev.photons_end.pos, " with t=", ev.channels.t[
                0], ". starting from ", ev.photons_beg.pos, " Hit=", ev.channels.hit[
                    0]
        hit_times = np.array(hit_times)

        self.assertAlmostEqual(hit_times.std(), 1.2, delta=1e-1)
示例#5
0
    def testDet(self):

        # Run only one photon at a time
        nphotons = 1000000
        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 = np.cross((np.cos(phi), np.sin(phi), 0), dir)

        pol[:, 0] = np.cos(phi)
        pol[:, 1] = np.sin(phi)
        pol = np.cross(pol, dir)
        for n, p in enumerate(pol):
            norm = np.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2])
            p /= norm
        #print pol
        t = np.zeros(nphotons,
                     dtype=np.float32) + 100.0  # Avoid negative photon times
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(128.0)

        photons = Photons(pos=pos,
                          dir=dir,
                          pol=pol,
                          t=t,
                          wavelengths=wavelengths)
        hit_charges = []
        for ev in self.sim.simulate(
            (photons for i in xrange(1)),
                keep_photons_end=True,
                keep_photons_beg=False,
        ):
            ev.photons_end.dump_history()
            lht = ev.photons_end[0].last_hit_triangles
示例#6
0
def GenScintPhotons(protoString):
    nsphotons = 0
    for i, sData in enumerate(protoString.stepdata):
        nsphotons += sData.nphotons
    print "NSPHOTONS: ", nsphotons
    pos = np.zeros((nsphotons, 3), dtype=np.float32)
    pol = np.zeros_like(pos)
    t = np.zeros(nsphotons, dtype=np.float32)
    wavelengths = np.empty(nsphotons, np.float32)
    wavelengths.fill(128.0)
    dphi = np.random.uniform(0, 2.0 * np.pi, nsphotons)
    dcos = np.random.uniform(-1.0, 1.0, nsphotons)
    dir = np.array(zip(
        np.sqrt(1 - dcos[:] * dcos[:]) * np.cos(dphi[:]),
        np.sqrt(1 - dcos[:] * dcos[:]) * np.sin(dphi[:]), dcos[:]),
                   dtype=np.float32)
    stepPhotons = 0
    for i, sData in enumerate(protoString.stepdata):
        #instead of appending to array every loop, the full size (nsphotons x 3) is allocated to begin, then
        #values are filled properly by incrementing stepPhotons.
        for j in xrange(stepPhotons, (stepPhotons + sData.nphotons)):
            pos[j, 0] = np.random.uniform(sData.step_start_x, sData.step_end_x)
            pos[j, 1] = np.random.uniform(sData.step_start_y, sData.step_end_y)
            pos[j, 2] = np.random.uniform(sData.step_start_z, sData.step_end_z)
        for j in xrange(stepPhotons, (stepPhotons + sData.nphotons)):
            pol[j, 0] = np.random.uniform(0, ((1 / 3.0)**.5))
            pol[j, 1] = np.random.uniform(0, ((1 / 3.0)**.5))
            pol[j, 2] = ((1 - pol[j, 0]**2 - pol[j, 1]**2)**.5)
        for j in xrange(stepPhotons, (stepPhotons + sData.nphotons)):
            t[j] = (np.random.exponential(1 / 45.0) +
                    (sData.step_end_t - sData.step_start_t))
        stepPhotons += sData.nphotons
    return Photons(pos=pos, pol=pol, t=t, dir=dir, wavelengths=wavelengths)
示例#7
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]
示例#8
0
def constant_photons(pos, n):
    #constructs photons at one location with random propagation directions
    points = np.empty((n, 3))
    points[:] = pos
    pos = points
    dir = uniform_sphere(n)
    pol = np.cross(dir, uniform_sphere(n))
    #300 nm is roughly the pseudocumene scintillation wavelength
    wavelengths = np.repeat(300.0, n)
    return Photons(pos, dir, pol, wavelengths)
示例#9
0
def gaussian_sphere(pos, sigma, n):
    points = np.empty((n, 3))
    points[:, 0] = np.random.normal(0.0, sigma, n) + pos[0]
    points[:, 1] = np.random.normal(0.0, sigma, n) + pos[1]
    points[:, 2] = np.random.normal(0.0, sigma, n) + pos[2]
    pos = points
    dir = uniform_sphere(n)
    pol = np.cross(dir, uniform_sphere(n))
    #300 nm is roughly the pseudocumene scintillation wavelength
    wavelengths = np.repeat(300.0, n)
    return Photons(pos, dir, pol, wavelengths)
示例#10
0
    def init_source(n, wavelength, width, beamsize):
        """Generates laser profile of n photons, with wavelength, emanating from position pos_offset with direction 'direction'."""

        pos, direction = mfunctions.get_source(n, width, beamsize,
                                               wavelength / 25400000.0)
        #Note: Chroma only natively handles integer wavelengths, so we convert to inches here instead of earlier in the code.
        source_center = mfunctions.get_center('161') + np.array(
            (0, -0.1, 0))  #Position source just in front of slits
        pos = pos + np.tile(source_center, (n, 1))
        pol = np.cross(direction, (0, 0, 1))  #Polarisation
        wavelengths = np.repeat(wavelength, n)
        return Photons(pos, direction, pol, wavelengths)
示例#11
0
def photon_angle(rep, pos=[0, 0, 0]):
    off = 200
    photon_pos = np.zeros((rep, 3))
    upshift = 800
    for i in range(5):
        photon_pos[i, :] = [
            pos[0] - i * 100 + off - 100, pos[1] + off + 400, pos[2] + upshift
        ]
    photon_pos[5, :] = [-800, 600, 800]
    photon_dir = np.tile(np.array([0.2, -0.55, -1]), (rep, 1))
    pol = np.cross(photon_dir, uniform_sphere(rep))
    wavelength = np.repeat(300.0, rep)
    return Photons(photon_pos, photon_dir, pol, wavelength), photon_pos
示例#12
0
def uniform_photons(inscribed_radius, n):
    #constructs photons uniformly throughout the detector inside of the inscribed sphere.
    radius_root = inscribed_radius * np.power(np.random.rand(n), 1.0 / 3.0)
    theta = np.arccos(np.random.uniform(-1.0, 1.0, n))
    phi = np.random.uniform(0.0, 2 * np.pi, n)
    points = np.empty((n, 3))
    points[:, 0] = radius_root * np.sin(theta) * np.cos(phi)
    points[:, 1] = radius_root * np.sin(theta) * np.sin(phi)
    points[:, 2] = radius_root * np.cos(theta)
    pos = points
    dir = uniform_sphere(n)
    pol = np.cross(dir, uniform_sphere(n))
    #300 nm is roughly the pseudocumene scintillation wavelength
    wavelengths = np.repeat(300.0, n)
    return Photons(pos, dir, pol, wavelengths)
示例#13
0
    def testCharge(self):
        '''Test PMT charge distribution'''

        # Run only one photon at a time
        phi = 1.0
        theta = 1.0
        nphotons = 100
        pos = np.tile([0, 0, 0], (nphotons, 1)).astype(np.float32)
        dir = np.tile([
            np.sin(theta * np.pi / 180.0) * np.cos(phi * np.pi / 180.0),
            np.sin(theta * np.pi / 180.0) * np.sin(phi * np.pi / 180.0),
            np.cos(theta * np.pi / 180.0)
        ], (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) + 100.0
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(400.0)

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

        hit_charges = []
        for ev in self.sim.simulate((photons for i in xrange(1)),
                                    keep_photons_end=True,
                                    keep_photons_beg=False):
            if ev.channels.hit[0]:
                hit_charges.append(ev.channels.q[0])
                self.hcharge.Fill(ev.channels.q[0])
                self.htime.Fill(ev.channels.t[0])
                #print "Hits:  with q=",ev.channels.q[0],". Hit=",ev.channels.hit[0]
            ev.photons_end.dump_history()
        hit_charges = np.array(hit_charges)

        self.assertAlmostEqual(hit_charges.mean() / float(hit_charges.size),
                               1.0,
                               delta=1e-1)
        self.assertAlmostEqual(hit_charges.std() / float(hist_chargs.size),
                               0.1,
                               delta=1e-1)
示例#14
0
    def setUp(self):
        self.cube = Geometry(water)
        self.cube.add_solid(Solid(box(100,100,100), water, water))
        self.geo = create_geometry_from_obj(self.cube, update_bvh_cache=False)
        self.sim = Simulation(self.geo, geant4_processes=0)

        nphotons = 100000
        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)

        self.photons = Photons(pos=pos, dir=dir, pol=pol, t=t, wavelengths=wavelengths)
示例#15
0
    def testCharge(self):
        '''Test PMT charge distribution'''

        # Run only one photon at a time
        phi = 1.0
        theta = 1.0
        nphotons = 1
        pos = np.tile([0, 0, 0], (nphotons, 1)).astype(np.float32)
        dir = np.tile([
            np.sin(theta * np.pi / 180.0) * np.cos(phi * np.pi / 180.0),
            np.sin(theta * np.pi / 180.0) * np.sin(phi * np.pi / 180.0),
            np.cos(theta * np.pi / 180.0)
        ], (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)

        hit_charges = []
        for ev in self.sim.simulate((photons for i in xrange(100)),
                                    keep_photons_end=True,
                                    keep_photons_beg=True):
            if ev.channels.hit[0]:
                hit_charges.append(ev.channels.q[0])
            traveled = 0
            for v in range(0, 3):
                traveled += ev.photons_end.pos[0][v] * ev.photons_end.pos[0][v]
            traveled = np.sqrt(traveled)
            print "Hits: ", ev.photons_end.pos, " with q=", ev.channels.q[
                0], ". starting from ", ev.photons_beg.pos, " Hit=", ev.channels.hit[
                    0], " dist traveled=", traveled
        hit_charges = np.array(hit_charges)

        self.assertAlmostEqual(hit_charges.mean(), 1.0, delta=1e-1)
        self.assertAlmostEqual(hit_charges.std(), 0.1, delta=1e-1)
示例#16
0
def gen_test(n, r, det_res):
    pos = np.random.normal(0, 0.01, (n * det_res.n_lens_sys, 3))
    if r == 0.0:
        lns_dir = config_stat.normalize(det_res.lens_centers, 1)
        drct = np.repeat(lns_dir, n, axis=0) + np.random.normal(
            0.0, 0.001, (n * det_res.n_lens_sys, 3))
    else:
        u_proj = config_stat.normalize(
            np.cross(det_res.lens_centers, [0, 0, 1]), 1)
        v_proj = config_stat.normalize(np.cross(det_res.lens_centers, u_proj),
                                       1)
        angle = 2 * np.pi * np.random.rand(n * det_res.n_lens_sys)
        drct = np.repeat(det_res.lens_centers, n, axis=0) + r * np.einsum(
            'i,ij->ij', np.sin(angle), np.repeat(
                u_proj, n, axis=0)) + r * np.einsum(
                    'i,ij->ij', np.cos(angle), np.repeat(v_proj, n, axis=0))
    pol = np.cross(drct, np.random.rand(n * det_res.n_lens_sys, 3))
    wavelengths = np.repeat(300.0, n * det_res.n_lens_sys)
    return Photons(pos, drct, pol, wavelengths)
示例#17
0
    def testTime(self):
        '''Test PMT time distribution'''

        # Run only one photon at a time
        nphotons = 1
        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) + 100.0  # Avoid negative photon times
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(400.0)

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

        hit_times = []
        for ev in self.sim.simulate((photons for i in xrange(1)),
                                    keep_photons_end=True,
                                    keep_photons_beg=False):
            for n, hit in enumerate(ev.channels.hit):
                if hit:
                    hit_times.append(ev.channels.t[n])
                    print "Hits from photon %d: " % (n), ev.photons_end[0].pos[
                        n], " with t=", ev.channels.t[n], " q=", ev.channels.q[
                            n], " Hit=", ev.channels.hit[n]
                    self.htime.Fill(ev.channels.t[n])
                    self.hcharge.Fill(ev.channels.q[n])
        hit_times = np.array(hit_times)

        self.assertAlmostEqual(hit_times.std(), 1.2, delta=1e-1)
示例#18
0
sample = 15
off_center = np.einsum(
    'ij,i->ij',
    np.tile(u_vers, sample).reshape(sample, 3),
    np.linspace(0, np.linalg.norm(det_res.lens_centers[0]), sample))
for alpha in off_center:
    off_axis = np.random.rand(amount, 3) * 2 - 1
    drc = np.tile((l_c + alpha) / np.linalg.norm(l_c + alpha),
                  amount).reshape(amount, 3)
    pos = np.einsum(
        'ij,i->ij',
        np.einsum('ij,i->ij', off_axis, 1 / np.linalg.norm(off_axis, axis=1)),
        np.linspace(0, det_res.lens_rad, amount)) * 0.5 - alpha
    pol = np.cross(drc, np.random.rand(amount, 3))
    wavelengths = np.repeat(300.0, amount)
    gun = Photons(pos, drc, pol, wavelengths)

    for ev in sim.simulate(gun,
                           keep_photons_beg=True,
                           keep_photons_end=True,
                           run_daq=False,
                           max_steps=100):
        #b_pos = ev.photons_beg.pos
        e_pos = ev.photons_end.pos
        _, _, detected = analyzer.generate_tracks(ev,
                                                  heat_map=True,
                                                  detec=True)

    e_pos = e_pos[detected]
    msk = np.einsum('ij,j->i', e_pos, l_c) > 0
    e_pos = e_pos[msk]
示例#19
0
    def testPhotonBomb(self):

        # Run only one photon at a time
        #nphotons = 7200000
        #nphotons = 256*10000
        nphotons = 256 * 1000

        dphi = np.random.uniform(0, 2.0 * np.pi, nphotons)
        dcos = np.random.uniform(-1.0, 1.0, nphotons)
        dir = np.array(zip(
            np.sqrt(1 - dcos[:] * dcos[:]) * np.cos(dphi[:]),
            np.sqrt(1 - dcos[:] * dcos[:]) * np.sin(dphi[:]), dcos[:]),
                       dtype=np.float32)

        pos = np.tile([-200.0, -400.0, -500.0],
                      (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)
        pol = np.cross(pol, dir)
        for n, p in enumerate(pol):
            norm = np.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2])
            p /= norm

        t = np.zeros(nphotons,
                     dtype=np.float32) + 100.0  # Avoid negative photon times
        wavelengths = np.empty(nphotons, np.float32)
        wavelengths.fill(128.0)

        photons = Photons(pos=pos,
                          dir=dir,
                          pol=pol,
                          t=t,
                          wavelengths=wavelengths)
        hit_charges = []

        if has_root:
            root_file = root_open("output_test_lbne35t_nowires.root",
                                  "recreate")
            root_tree = Tree("PhotonData", model=PhotonData)
            root_tree.reset()

        for ev in self.sim.simulate((photons for i in xrange(1)),
                                    keep_photons_end=True,
                                    keep_photons_beg=False):
            ev.photons_end.dump_history()
            #    lht = ev.photons_end[0].last_hit_triangles
            #    nhits = ev.channels.hit[ np.arange(0,30)[:] ]
            #
            #    print "nchannels: ",len(ev.channels.hit)
            #    print nhits
            #    print ev.channels.q
            #    print ev.channels.t
            if True:
                # Fill Tree
                #print "save info for ",len(ev.photons_end)
                for photon in ev.photons_end:
                    root_tree.end_x = photon.pos[0]
                    root_tree.end_y = photon.pos[1]
                    root_tree.end_z = photon.pos[2]

                    root_tree.reflect_diffuse = int(event.REFLECT_DIFFUSE
                                                    & photon.flags)
                    root_tree.reflect_specular = int(event.REFLECT_SPECULAR
                                                     & photon.flags)
                    root_tree.bulk_scatter = int(event.RAYLEIGH_SCATTER
                                                 & photon.flags)
                    root_tree.bulk_absorb = int(event.BULK_ABSORB
                                                & photon.flags)
                    root_tree.surface_detect = int(event.SURFACE_DETECT
                                                   & photon.flags)
                    root_tree.surface_absorb = int(event.SURFACE_ABSORB
                                                   & photon.flags)
                    root_tree.surface_reemit = int(event.SURFACE_REEMIT
                                                   & photon.flags)
                    root_tree.fill()
        if has_root:
            root_tree.write()
示例#20
0
    def testBulkReemission(self):
        '''Test bulk reemission 

        Start a bunch of monoenergetic photons at the center of a wavelength-
        shifting sphere, forcing reemission, and check that the final
        wavelength distribution matches the wls spectrum.
        '''
        import scipy.stats
        nphotons = 1e5

        # set up detector -- a sphere of 'scintillator' surrounded by a
        # detecting sphere
        scint = Material('scint')
        scint.set('refractive_index', 1)
        scint.set('absorption_length', 1.0)
        scint.set('scattering_length', 1e7)
        scint.set('reemission_prob', 1)

        x = np.arange(0,1000,10)
        norm = scipy.stats.norm(scale=50, loc=600)
        pdf = 10 * norm.pdf(x)
        cdf = norm.cdf(x)
        scint.reemission_cdf = np.array(zip(x, cdf))

        detector = Surface('detector')
        detector.set('detect', 1)

        world = Geometry(vacuum)
        world.add_solid(Solid(sphere(1000), vacuum, vacuum, surface=detector))
        world.add_solid(Solid(sphere(500), scint, vacuum))
        w = create_geometry_from_obj(world, update_bvh_cache=False)

        sim = Simulation(w, geant4_processes=0)

        # initial photons -- isotropic 250 nm at the origin
        pos = np.tile([0,0,0], (nphotons,1)).astype(np.float32)
        dir = np.random.rand(nphotons, 3).astype(np.float32) * 2 - 1
        dir /= np.sqrt(dir[:,0]**2 + dir[:,1]**2 + dir[:,2]**2)[:,np.newaxis]
        pol = np.zeros_like(pos)
        t = np.zeros(nphotons, dtype=np.float32)
        wavelengths = np.ones(nphotons).astype(np.float32) * 250

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

        # run simulation and extract final wavelengths
        event = sim.simulate([photons], keep_photons_end=True).next()
        mask = (event.photons_end.flags & SURFACE_DETECT) > 0
        final_wavelengths = event.photons_end.wavelengths[mask]

        # compare wavelength distribution to scintillator's reemission pdf
        hist, edges = np.histogram(final_wavelengths, bins=x)
        print 'detected', hist.sum(), 'of', nphotons, 'photons'
        hist_norm = 1.0 * hist / (1.0 * hist.sum() / 1000)
        pdf /= (1.0 * pdf.sum() / 1000)

        chi2 = scipy.stats.chisquare(hist_norm, pdf[:-1])[1]
        print 'chi2 =', chi2

        # show histogram comparison
        #plt.figure(1)
        #width = edges[1] - edges[0]
        #plt.bar(left=edges, height=pdf, width=width, color='red')
        #plt.bar(left=edges[:-1], height=hist_norm, width=width)
        #plt.show()

        self.assertTrue(chi2 > 0.75)
    def calibrate(self,
                  simname,
                  directory=".",
                  nevents=-1,
                  fast_calibration=False):
        # Use with a simulation file 'simname' to calibrate the detector
        # Creates a list of mean angles and their uncertainties (sigma for
        # a cone of unit length), one for each PMT
        # There are 1000 events in a typical simulation.
        # Uses all photons hitting a given PMT at once (better estimate of sigma,
        # but may run out of memory in some cases).
        # Will not calibrate PMTs with <n_min hits
        logger.info('Fast calibration: %s' % str(fast_calibration))
        self.is_calibrated = True
        start_time = time.time()

        base_hits_file_name = self.configname + '-hits'
        pickle_name = base_hits_file_name + '.pickle'
        hit_file_exists = False
        n_min = 10  # Do not calibrate a PMT if <n_min photons hit it
        try:
            logger.info('Attempting to load pickle hits file: %s%s' %
                        (directory, pickle_name))
            # TODO: This generally won't do anything because we no longer write this file
            with open(directory + pickle_name, 'rb') as inf:
                pmt_hits = pickle.load(inf)
            logger.info('Hit map pickle file loaded: ' + pickle_name)
            pmt_bins = pmt_hits['pmt_bins']
            end_direction_array = pmt_hits['end_direction_array']
            n_det = len(pmt_bins)
            hit_file_exists = True
        except IOError as error:
            # Assume file not found
            logger.info('Hit map pickle file not found.  Creating: ' +
                        base_hits_file_name)

            using_h5 = False
            if simname.endswith('.h5'):
                using_h5 = True
                ev_file = dd.io.load(simname)
                # TODO: Check the UUID!!
                events_in_file = len(ev_file['photons_start'])
            else:
                from ShortIO.root_short import GaussAngleRootWriter, GaussAngleRootReader, ShortRootReader
                reader = ShortRootReader(simname)
                events_in_file = len(reader)
            logger.info('Loaded simulation file: %s' % simname)
            logger.info('Simulation event count: %d' % events_in_file)

            if nevents < 1:
                nevents = events_in_file

            max_storage = min(
                nevents * 1000000, 120000000
            )  #600M is too much, 400M is OK (for np.float32; using 300M)
            end_direction_array = np.empty((max_storage, 3), dtype=np.float32)
            pmt_bins = np.empty(max_storage, dtype=np.int)
            n_det = 0

            # Loop through events, store for each photon the index of the PMT it hit (pmt_bins)
            # and the direction pointing back to its origin (end_direction_array)
            loops = 0
            event_source = ev_file['photons_start'] if using_h5 else reader
            for index, ev_proxy in enumerate(
                    event_source):  # Not sure if we can enumerate a reader????
                # TODO: This needs to be cleaned up
                if (using_h5):
                    photons_beg = Photons(ev_proxy, [], [], [])
                    photons_end = Photons(ev_file['photons_stop'][index], [],
                                          [], [],
                                          flags=ev_file['photon_flags'][index])
                else:
                    photons_beg = ev_proxy.photons_beg
                    photons_end = ev_proxy.photons_end

                loops += 1
                if loops > nevents:
                    break

                if loops % 100 == 0:
                    logger.info("Event " + str(loops) + " of " + str(nevents))
                    logger.handlers[0].flush()

                detected = (photons_end.flags & (0x1 << 2)).astype(bool)
                '''
                reflected_diffuse = (ev.photons_end.flags & (0x1 << 5)).astype(bool)
                reflected_specular = (ev.photons_end.flags & (0x1 << 6)).astype(bool)
                logger.info("Total detected: " + str(sum(detected * 1)))
                logger.info("Total reflected: " + str(sum(reflected_diffuse * 1) + sum(reflected_specular * 1)))
                good_photons = detected & np.logical_not(reflected_diffuse) & np.logical_not(reflected_specular)
                logger.info("Total detected and not reflected: " + str(sum(good_photons * 1)))
                '''
                if fast_calibration:
                    ending_photons, length = self._find_photons_for_pmt(
                        photons_beg.pos, photons_end.pos, detected,
                        end_direction_array, n_det, max_storage)
                    pmt_b = self.find_pmt_bin_array(ending_photons)
                    if length is None:
                        break
                else:
                    beginning_photons = photons_beg.pos[
                        detected]  # Include reflected photons
                    ending_photons = photons_end.pos[detected]
                    length = np.shape(ending_photons)[0]
                    pmt_b = self.find_pmt_bin_array(ending_photons)
                    end_point = self.lens_centers[pmt_b / self.n_pmts_per_surf]
                    end_dir = normalize(end_point - beginning_photons)
                    # if end_direction_array is None:
                    #     end_direction_array = end_dir
                    # else:
                    #     end_direction_array = np.vstack((end_direction_array, end_dir))
                    #end_direction_array.append(end_dir)
                    if n_det + length > max_storage:
                        logger.info(
                            'Too many photons to store in memory; not reading any further events.'
                        )
                        break
                    end_direction_array[n_det:(n_det + length), :] = end_dir
                    # if pmt_bins is None:
                    #     pmt_bins = pmt_b
                    # else:
                    #     pmt_bins = np.hstack((pmt_bins, pmt_b))
                    #pmt_bins.append(pmt_b)
                pmt_bins[n_det:(n_det + length)] = pmt_b
                n_det += length
                if loops % 100 == 0:
                    logger.info('Photons detected so far: ' +
                                str(n_det + length))
                    # logger.info('Sample pmt bins: ' + str(pmt_bins[n_det:(n_det+length)]))
                    logger.info("Time: " + str(time.time() - start_time))

        total_means = np.zeros((self.npmt_bins, 3))
        total_variances = np.zeros((self.npmt_bins))
        total_u_minus_v = np.zeros((self.npmt_bins))
        amount_of_hits = np.zeros((self.npmt_bins))

        end_direction_array.resize((n_det, 3))
        logger.info("Time: " + str(time.time() - start_time))
        pmt_bins.resize(n_det)

        if not hit_file_exists:
            # TODO: No longer writing the pickle file
            # Write the pickle hits file regardless of whether using fast_calibration or not
            #pmt_hits = {'pmt_bins': pmt_bins, 'end_direction_array': end_direction_array}
            #with open(directory+pickle_name, 'wb') as outf:
            #    pickle.dump(pmt_hits, outf)
            with h5py.File(directory + base_hits_file_name + '.h5',
                           'w') as h5file:
                _ = h5file.create_dataset(
                    'pmt_bins', data=pmt_bins,
                    chunks=True)  # TODO: Should we assign max shape?
                _ = h5file.create_dataset(
                    'end_direction_array',
                    data=end_direction_array,
                    chunks=True)  # TODO: Should we assign max shape?
            logger.info('Hit map file created: ' + pickle_name)

        logger.info(
            "Finished collecting photons (or loading photon hit list).  Time: "
            + str(time.time() - start_time))

        if fast_calibration:
            bins_base_file_name = self.configname + '-pmt-bins'
            bins_pickle_file = bins_base_file_name + '.pickle'
            try:
                with open(
                        directory + bins_pickle_file, 'rb'
                ) as inf:  # TODO: This generally won't do anything because we no longer write this file
                    pmt_photons = pickle.load(inf)
                logger.info('PMT photon list pickle file loaded: ' +
                            bins_pickle_file)
            except IOError as error:
                start_assign = time.time()
                pmt_photons = assign_photons(self.npmt_bins, n_det, pmt_bins)
                logger.info("assign_photons took: " +
                            str(time.time() - start_assign))
                # TODO: No longer writing the pickle file
                #with open(directory + bins_pickle_file, 'wb') as outf:
                #    pickle.dump(pmt_photons, outf)

                # TODO: Pure H5 does not work.  (Because?)
                #with h5py.File(directory + bins_file + '.h5', 'w') as h5file:
                #    _ = h5file.create_dataset('photon_pmts', data=pmt_photons, chunks=True)   # Should we assign max shape?
                #logger.info('Type: ' + str(type(pmt_photons)) + ' ' + str(type(pmt_photons[0])))
                dd.io.save(directory + bins_base_file_name + '.h5',
                           pmt_photons)
                logger.info('PMT photon list file created: ' +
                            bins_base_file_name + '.h5')

        logger.info("Finished listing photons by pmt.  Time: " +
                    str(time.time() - start_time))

        draw_pmt_ind = -1

        # looping through each pmt in order to save a mean_angle and a variance
        for i in range(self.npmt_bins):
            if i % 10000 == 0:
                logger.info(
                    str(i) + ' out of ' + str(self.npmt_bins) + ' PMTs')
                logger.handlers[0].flush()
                logger.info("Time: " + str(time.time() - start_time))

            if fast_calibration:
                photon_list = pmt_photons[i]
                angles_for_pmt = end_direction_array[photon_list]
                n_angles = len(angles_for_pmt)  # np.shape(angles_for_pmt)[0]
                # skipping pmts with <2 photon hits (in which case the variance will be undefined with ddof=1)
                # also skipping if <n_min photon hits
                if n_angles < 2 or n_angles < n_min:
                    logger.warning('Not enough angles for PMT: %d, %d' %
                                   (i, n_angles))
                    continue

                mean_angle, variance, uvvar = compute_pmt_calibration(
                    angles_for_pmt, n_min)
            else:
                pmt_indices = np.where(pmt_bins == i)[0]
                if np.shape(pmt_indices)[0] == 0:
                    continue
                angles_for_pmt = end_direction_array[pmt_indices]

                n_angles = np.shape(angles_for_pmt)[0]
                #skipping pmts with <2 photon hits (in which case the variance will be undefined with ddof=1)
                #also skipping if <n_min photon hits
                if n_angles < 2 or n_angles < n_min:
                    continue
                mean_angle = normalize(np.mean(angles_for_pmt, axis=0))

                # For each PMT, get a pair of axes which form an
                # orthonormal coordinate system with the PMT mean direction
                u_dir = np.cross(mean_angle, np.array([0, 0, 1]))
                if not (np.dot(u_dir, u_dir) >
                        0):  # In case mean_angle = [0,0,1]
                    u_dir = np.cross(mean_angle, np.array([0, 1, 0]))
                u_dir = normalize(u_dir)
                v_dir = np.cross(mean_angle, u_dir)

                u_proj = np.dot(angles_for_pmt, u_dir)
                u_var = np.var(u_proj, ddof=1)
                v_proj = np.dot(angles_for_pmt, v_dir)
                v_var = np.var(v_proj, ddof=1)
                variance = (u_var + v_var) / 2.

                # Old method, which calculated variance of projected norma, even though
                # the mean of the projections wasn't 0 due to the solid angle factor
                norms = np.repeat(1.0, n_angles)
                projection_norms = np.dot(angles_for_pmt, mean_angle)
                orthogonal_complements = np.sqrt(
                    np.maximum(norms**2 - projection_norms**2, 0.))
                #variance = np.var(orthogonal_complements, ddof=1)

                uvvar = u_var - v_var
            try:
                #draw_pmt_ind = None
                draw_pmt_ind = int(draw_pmt_ind)
                '''
                if i == draw_pmt_ind or draw_pmt_ind<0:
                    # Temporary, to visualize histogram of angles, distances
                    #angles = np.arccos(projection_norms)
                    #ang_variance = np.var(angles, ddof=1)
                    #fig1 = plt.figure(figsize=(7.8, 6))
                    #plt.hist(angles, bins=20)
                    #plt.xlabel('Angular Separation to Mean Angle')
                    #plt.ylabel('Counts per bin')
                    #plt.title('Angles Histogram for PMT ' + str(i))
                    ##plt.show()
                    #
                    #fig2 = plt.figure(figsize=(7.8, 6))
                    #plt.hist(angles, bins=20, weights=1./np.sin(angles))
                    #plt.xlabel('Angular Separation to Mean Angle')
                    #plt.ylabel('Counts per solid angle')
                    #plt.title('Angles Histogram for PMT ' + str(i))

                    fig3 = plt.figure(figsize=(7.8, 6))
                    plt.hist(orthogonal_complements, bins=20)
                    plt.xlabel('Normalized Distance to Mean Angle')
                    plt.ylabel('Counts per bin')
                    plt.title('Distances Histogram for PMT ' + str(i))

                    fig4 = plt.figure(figsize=(7.8, 6))
                    plt.hist(u_proj, bins=20)
                    plt.xlabel('U Distance to Mean Angle')
                    plt.ylabel('Counts per bin')
                    plt.title('U Distances Histogram for PMT ' + str(i))

                    fig5 = plt.figure(figsize=(7.8, 6))
                    plt.hist(v_proj, bins=20)
                    plt.xlabel('V Distance to Mean Angle')
                    plt.ylabel('Counts per bin')
                    plt.title('V Distances Histogram for PMT ' + str(i))
                    plt.show()

                    #print "Average projected variance: ", variance
                    #print "Variance of projected 2D norms: ", np.var(orthogonal_complements, ddof=1)
                    draw_pmt_ind = raw_input("Enter index of next PMT to draw; will stop drawing if not a valid PMT index.\n")
                '''
            except ValueError:
                pass
            except TypeError:
                pass

            total_means[i] = mean_angle
            total_variances[i] = variance
            total_u_minus_v[i] = np.abs(uvvar)
            amount_of_hits[i] = n_angles
            if np.isnan(variance):
                print "Nan for PMT " + str(i)
                # nan_ind = np.where(np.isnan(orthogonal_complements))
                # print nan_ind
                # print projection_norms
                # print orthogonal_complements
                # print angles_for_pmt
                # print variance
                # print mean_angle

        # temporary, for debugging:
        n_hits = np.sum(amount_of_hits, axis=0)
        print "Total hits for calibrated PMTs: " + str(n_hits)
        print "PMTs w/ < n_events hits: " + str(
            len(np.where(amount_of_hits < nevents)[0]) * 1.0 / self.npmt_bins)
        print "PMTs w/ < n_min hits: " + str(
            len(np.where(amount_of_hits < n_min)[0]) * 1.0 / self.npmt_bins)
        print "PMTs w/ < 100 hits: " + str(
            len(np.where(amount_of_hits < 100)[0]) * 1.0 / self.npmt_bins)
        print "Mean U-V variance (abs): " + str(np.mean(total_u_minus_v))

        # Store final calibrated values
        self.means = -total_means.astype(np.float32).T
        self.sigmas = np.sqrt(total_variances.astype(np.float32))
示例#22
0
    def testPhotonBomb(self):

        # Run only one photon at a time
        nphotons_test = 256 * 1000
        #nphotons = 7200000

        if has_root:
            root_file = root_open("output_test_lar1nd_scanx_high_stats.root",
                                  "recreate")
            root_tree = Tree("PhotonData", model=PhotonData)
            root_tree.reset()
            root_channels = Tree("OpDet", model=OpDet)
            root_opmap = Tree("OpMap", model=OpMap)
            channelmap = self.sim.gpu_geometry.solid_id_to_channel_index_gpu.get(
            )
            channels = np.argwhere(channelmap > -1)
            nchannels = NCHANNELS
            channeldict = dict(
                zip(range(0, nchannels),
                    channels.ravel().tolist()))
            for ich in range(0, nchannels):
                root_opmap.opid = ich
                solid = self.sim.detector.solids[channeldict[ich]]
                root_opmap.x = np.sum(solid.mesh.vertices[:, 0]) / len(
                    solid.mesh.vertices)
                root_opmap.y = np.sum(solid.mesh.vertices[:, 1]) / len(
                    solid.mesh.vertices)
                root_opmap.z = np.sum(solid.mesh.vertices[:, 2]) / len(
                    solid.mesh.vertices)
                root_opmap.fill()
            root_opmap.write()

        for eventid in xrange(0, 102):
            print "Event: ", eventid

            if eventid < 101:
                nphotons = nphotons_test * 20
                z = -200 + 4 * eventid
            else:
                # reference
                nphotons = nphotons_test
                z = 0

            t_photon_start = time.time()
            dphi = np.random.uniform(0, 2.0 * np.pi, nphotons)
            dcos = np.random.uniform(-1.0, 1.0, nphotons)
            dir = np.array(zip(
                np.sqrt(1 - dcos[:] * dcos[:]) * np.cos(dphi[:]),
                np.sqrt(1 - dcos[:] * dcos[:]) * np.sin(dphi[:]), dcos[:]),
                           dtype=np.float32)
            pos = np.tile([-1000 + z, 0, 0], (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) + 100.0  # Avoid negative photon times
            wavelengths = np.empty(nphotons, np.float32)
            wavelengths.fill(128.0)
            photons = Photons(pos=pos,
                              dir=dir,
                              pol=pol,
                              t=t,
                              wavelengths=wavelengths)
            t_end_start = time.time()
            print "define photon time: ", t_end_start - t_photon_start, "sec"

            for ev in self.sim.simulate(
                (photons for i in xrange(1)),
                    keep_photons_end=True,
                    keep_photons_beg=False,
            ):
                #ev.photons_end.dump_history()
                #print ev.channels.t
                if (eventid % 10 == 0):
                    print "Event: ", eventid
                #print "nchannels: ",len(ev.channels.hit)
                #print nhits
                #print ev.channels.q
                #print ev.channels.t

                if False:
                    # Fill Tree
                    #print "save info for ",len(ev.photons_end)
                    for photon in ev.photons_end:
                        root_tree.end_x = photon.pos[0]
                        root_tree.end_y = photon.pos[1]
                        root_tree.end_z = photon.pos[2]

                        root_tree.reflect_diffuse = int(event.REFLECT_DIFFUSE
                                                        & photon.flags)
                        root_tree.reflect_specular = int(event.REFLECT_SPECULAR
                                                         & photon.flags)
                        root_tree.bulk_scatter = int(event.RAYLEIGH_SCATTER
                                                     & photon.flags)
                        root_tree.bulk_absorb = int(event.BULK_ABSORB
                                                    & photon.flags)
                        root_tree.surface_detect = int(event.SURFACE_DETECT
                                                       & photon.flags)
                        root_tree.surface_absorb = int(event.SURFACE_ABSORB
                                                       & photon.flags)
                        root_tree.surface_reemit = int(event.SURFACE_REEMIT
                                                       & photon.flags)
                        root_tree.fill()
                if True:
                    root_channels.eventid = eventid
                    t_root_start = time.time()
                    for ichannel in xrange(0, NCHANNELS):
                        root_channels.id = ichannel
                        root_channels.NTDC = GPUDaqUBooNE.NTDC
                        root_channels.NS_PER_TDC = GPUDaqUBooNE.NS_PER_TDC
                        channeladc = ev.channels.q[GPUDaqUBooNE.NTDC *
                                                   ichannel:(ichannel + 1) *
                                                   GPUDaqUBooNE.NTDC]
                        root_channels.adc[:] = array.array(
                            'f', channeladc[:].ravel().tolist())[:]
                        root_channels.q = np.sum(channeladc)
                        #if root_channels.q>0:
                        #    print channeladc[ np.where( channeladc>0.0 ) ]
                        root_channels.t = ev.channels.t[ichannel]
                        root_channels.fill()
                    t_root_end = time.time()
                    print "ROOT Fill time: ", t_root_end - t_root_start, " sec"
        if has_root:
            root_tree.write()
            root_channels.write()
示例#23
0
文件: g4gen.py 项目: smnaugle/chroma
    def generate_photons(self, vertices, mute=False, tracking=False):
        """Use GEANT4 to generate photons produced by propagating `vertices`.
           
        Args:
            vertices: list of event.Vertex objects
                List of initial particle vertices.

            mute: bool
                Disable GEANT4 output to console during generation.  (GEANT4 can
                be quite chatty.)

        Returns:
            photons: event.Photons
                Photon vertices generated by the propagation of `vertices`.
        """
        if mute:
            pass
            #g4mute()

        self.stepping_action.EnableTracking(tracking)

        photons = Photons()
        if tracking:
            photon_parent_tracks = []

        try:
            tracked_vertices = []
            for vertex in vertices:
                self.particle_gun.SetParticleByName(vertex.particle_name)
                #Geant4 seems to call 'ParticleEnergy' KineticEnergy - see G4ParticleGun
                kinetic_energy = vertex.ke * MeV
                self.particle_gun.SetParticleEnergy(kinetic_energy)

                # Must be float type to call GEANT4 code
                pos = np.asarray(vertex.pos, dtype=np.float64)
                dir = np.asarray(vertex.dir, dtype=np.float64)

                self.particle_gun.SetParticlePosition(G4ThreeVector(*pos) * mm)
                self.particle_gun.SetParticleMomentumDirection(
                    G4ThreeVector(*dir).unit())
                self.particle_gun.SetParticleTime(vertex.t0 * ns)

                if vertex.pol is not None:
                    self.particle_gun.SetParticlePolarization(
                        G4ThreeVector(*vertex.pol).unit())

                self.tracking_action.Clear()
                self.stepping_action.ClearTracking()
                gRunManager.BeamOn(1)

                if tracking:
                    vertex = self._extract_vertex_from_stepping_action()
                    photon_parent_tracks.append(
                        self.tracking_action.GetParentTrackID().astype(
                            np.int32))
                tracked_vertices.append(vertex)
                photons += self._extract_photons_from_tracking_action()
            if tracking:
                photon_parent_tracks = [
                    track for track in photon_parent_tracks if len(track) > 0
                ]
                photon_parent_tracks = np.concatenate(
                    photon_parent_tracks
                ) if len(photon_parent_tracks) > 0 else []

        finally:
            if mute:
                pass
                #g4unmute()

        if tracking:
            return (tracked_vertices, photons, photon_parent_tracks)
        else:
            return (tracked_vertices, photons)
示例#24
0
pos = np.tile([1200, 0, 1000], (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)
pol = np.cross(pol, dir)
for n, p in enumerate(pol):
    norm = np.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2])
    p /= norm

t = np.zeros(nphotons, dtype=np.float32) + 100.0  # Avoid negative photon times
wavelengths = np.empty(nphotons, np.float32)
wavelengths.fill(128.0)

photons = Photons(pos=pos, dir=dir, pol=pol, t=t, wavelengths=wavelengths)
print "photons generated"
events = sim.simulate(photons, keep_photons_end=True, max_steps=2000)
photon_endpos = None
photon_colors = None

colordict = {
    chroma.event.SURFACE_DETECT: (1.0, 0.0, 0.0, 1.0),
    chroma.event.BULK_ABSORB: (0.0, 1.0, 0.0, 1.0),
    chroma.event.WIREPLANE_ABSORB: (1.0, 1.0, 0.0, 0.5),
    chroma.event.SURFACE_ABSORB:
    (14.0 / 255.0, 26.0 / 255.0, 191.0 / 255.0, 0.5),
    0: (0.0, 0.0, 0.0, 0.1)
}

for ev in events:
示例#25
0
 def photon_bomb(n, wavelength, pos):
     pos = np.tile(pos, (n, 1))
     dir = uniform_sphere(n)
     pol = np.cross(dir, uniform_sphere(n))
     wavelengths = np.repeat(wavelength, n)
     return Photons(pos, dir, pol, wavelengths)