示例#1
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)
示例#2
0
from chroma.geometry import Material
from chroma.geometry import Surface

from Geant4.hepunit import *

import numpy as np

ls_refractive_index = 1.5
lensmat_refractive_index = 2.0
lensmat_ohara_refractive_index = 1.923

# This is elemental helium - vs. G4_HE
he = Material('He')
he.set('refractive_index', 1.0)
he.set('absorption_length', 1e8)
he.set('scattering_length', 1e8)
he.density = 0.5
he.composition = { 'He' : 1.0 }

lensmat = Material('lensmat')
lensmat.set('refractive_index', lensmat_refractive_index)
lensmat.set('absorption_length', 1e8)
lensmat.set('scattering_length', 1e8)

lensmat_ohara = Material('lensmat_ohara')
lensmat_ohara.set('refractive_index', lensmat_ohara_refractive_index)
lensmat_ohara.set('absorption_length', 1e8)
lensmat_ohara.set('scattering_length', 1e8)

blackhole = Material('blackhole')
blackhole.set('refractive_index', 1.0)
示例#3
0
def create_scintillation_material():
	global _ls
	if _ls is None:
		# ls stands for "liquid scintillator"
		_ls = Material('liquid-scintillator')
		_ls.set('refractive_index', ls_refractive_index)
		_ls.set('absorption_length', 1e8)
		_ls.set('scattering_length', 1e8)
		_ls.density = 0.780
		_ls.composition = {'H': 0.663210, 'C': 0.336655, 'N': 1.00996e-4, 'O': 3.36655e-5}

		#_ls.set('refractive_index', np.linspace(ls_refractive_index, ls_refractive_index, 38))

		# Scintillation properties
		energy_scint = list((2 * pi * hbarc / (np.linspace(320, 300, 11).astype(float) * nanometer)))
		spect_scint = list([0.04, 0.07, 0.20, 0.49, 0.84, 1.00, 0.83, 0.55, 0.40, 0.17, 0.03])
		# See https://geant4.web.cern.ch/geant4/UserDocumentation/UsersGuides/ForApplicationDeveloper/html/ch02s03.html
		# Need to validate that the types are being passed through properly.  Previously was using list(Scnt_PP.astype(float)
		_ls.set_scintillation_property('FASTCOMPONENT', energy_scint, spect_scint)

		# TODO: These keys much match the Geant4 pmaterial property names.  (Magic strings)
		_ls.set_scintillation_property('SCINTILLATIONYIELD', 8000. / MeV)  # Was 10000 originally
		_ls.set_scintillation_property('RESOLUTIONSCALE', 1.0)  # Was 1.0 originally
		_ls.set_scintillation_property('FASTTIMECONSTANT', 1. * ns)
		_ls.set_scintillation_property('YIELDRATIO', 1.0)  # Was 0.8 - I think this is all fast

		# Required for scintillation yield per particle
		# Commenting out these three lines causes a "malloc: *** error for object 0x1298c02d0: pointer being freed was not allocated" WTF?
		electron_energy_scint = list([0., 1. * MeV, 10. * MeV, 100. * MeV])
		electron_yield = list([0, 8000., 80000., 800000.])
		_ls.set_scintillation_property('ELECTRONSCINTILLATIONYIELD', electron_energy_scint, electron_yield)
		proton_energy_scint = list([0 * MeV, 0.1 * MeV, 0.5 * MeV, 1 * MeV, 1.5 * MeV, 2 * MeV, 2.5 * MeV, 3 * MeV, 3.5 * MeV, 4 * MeV, 4.4 * MeV, 5 * MeV, 6 * MeV, 7 * MeV, 8 * MeV, 9 * MeV, 10 * MeV, 12 * MeV, 14 * MeV, 16 * MeV, 18 * MeV, 19.9])
		proton_yield = list([0, 43, 581, 1637, 2988, 4562, 6316, 8219, 10249, 12389, 14171, 16946, 21809, 26921, 32240, 37736, 43383, 55059, 67150, 79575, 92277, 104558])
		_ls.set_scintillation_property('PROTONSCINTILLATIONYIELD', proton_energy_scint , proton_yield)

	return _ls
示例#4
0
#!/usr/bin/env python
from chroma.geometry import Material, Solid, Surface
import numpy as np
#***************************************************************************
#***************************************************************************
sipm = Material('sipm')
sipm.set('detection', 1)

copper = Material('copper')
copper.set(
    'refractive_index', 0.97333
)  # 0.87 #https://refractiveindex.info/?shelf=main&book=Cu&page=Werner with wavelength 175nm extrapolated on TREND function excel
copper.set('absorption_length', 50)  #1058100
copper.set('scattering_length', 1e6)  #10e6
copper.density = 8.96
copper.composition = {'Cu': 1.00}
#***************************************************************************
#***************************************************************************
vacuum = Material('vac')
vacuum.set('refractive_index', 1.0)
vacuum.set('absorption_length', 0)
vacuum.set('scattering_length', 1e6)
vacuum.set('reemission_prob', 0)
#***************************************************************************
#***************************************************************************
LXenon = Material('LXenon')
LXenon.set(
    'refractive_index', 1.69
)  #https://arxiv.org/ftp/physics/papers/0307/0307044.pdf #possibly 1.57 but lower occurances #1.69
LXenon.set('absorption_length',
           1e6)  #20000 Changed 364 --> 0 8/9/2018, used 1000mm June 11 2019
示例#5
0
import numpy as np
from chroma.geometry import Material, Surface

vacuum = Material('vacuum')
vacuum.set('refractive_index', 1.0)
vacuum.set('absorption_length', 1e6)
vacuum.set('scattering_length', 1e6)

lambertian_surface = Surface('lambertian_surface')
lambertian_surface.set('reflect_diffuse', 1)

black_surface = Surface('black_surface')
black_surface.set('absorb', 1)

shiny_surface = Surface('shiny_surface')
shiny_surface.set('reflect_specular', 1)

glossy_surface = Surface('glossy_surface')
glossy_surface.set('reflect_diffuse', 0.5)
glossy_surface.set('reflect_specular', 0.5)

red_absorb_surface = Surface('red_absorb')
red_absorb_surface.set('absorb', [0.0, 0.0, 1.0], [465, 545, 685])
red_absorb_surface.set('reflect_diffuse', [1.0, 1.0, 0.0], [465, 545, 685])

# r7081hqe photocathode material surface
# source: hamamatsu supplied datasheet for r7081hqe pmt serial number zd0062
r7081hqe_photocathode = Surface('r7081hqe_photocathode')
r7081hqe_photocathode.detect = \
    np.array([(260.0,  0.00),
              (270.0,  0.04), (280.0,  0.07), (290.0,  0.77), (300.0,  4.57),
示例#6
0
    def convert_materials(self, debug=False):
        """
        #. creates chroma Material instances for each collada material 
        #. fills in properties from the collada extras
        #. records materials in a map keyed by material.name

        Chroma materials default to None, 3 settings:

        * refractive_index
        * absorption_length
        * scattering_length

        And defaults to zero, 2 settings:

        * reemission_prob
        * reemission_cdf

        G4DAE materials have an extra attribute dict that 
        contains keys such as

        * RINDEX
        * ABSLENGTH
        * RAYLEIGH

        Uncertain of key correspondence, especially REEMISSIONPROB
        and what about reemission_cdf ? Possibly the many Scintillator
        keys can provide that ?

        Probably many the scintillator keys are only relevant to photon 
        production rather than photon propagation, so they are irrelevant 
        to Chroma.

        Which materials have each::

             EFFICIENCY                     [1 ] Bialkali 

             -------------- assumed to not apply to optical photons ---------

             FASTTIMECONSTANT               [2 ] GdDopedLS,LiquidScintillator 
             SLOWTIMECONSTANT               [2 ] GdDopedLS,LiquidScintillator 
             YIELDRATIO                     [2 ] GdDopedLS,LiquidScintillator 

             GammaFASTTIMECONSTANT          [2 ] GdDopedLS,LiquidScintillator 
             GammaSLOWTIMECONSTANT          [2 ] GdDopedLS,LiquidScintillator 
             GammaYIELDRATIO                [2 ] GdDopedLS,LiquidScintillator 

             AlphaFASTTIMECONSTANT          [2 ] GdDopedLS,LiquidScintillator 
             AlphaSLOWTIMECONSTANT          [2 ] GdDopedLS,LiquidScintillator 
             AlphaYIELDRATIO                [2 ] GdDopedLS,LiquidScintillator 

             NeutronFASTTIMECONSTANT        [2 ] GdDopedLS,LiquidScintillator 
             NeutronSLOWTIMECONSTANT        [2 ] GdDopedLS,LiquidScintillator 
             NeutronYIELDRATIO              [2 ] GdDopedLS,LiquidScintillator 

             SCINTILLATIONYIELD             [2 ] GdDopedLS,LiquidScintillator 
             RESOLUTIONSCALE                [2 ] GdDopedLS,LiquidScintillator 

             ---------------------------------------------------------------------

             ReemissionFASTTIMECONSTANT     [2 ] GdDopedLS,LiquidScintillator      for opticalphoton
             ReemissionSLOWTIMECONSTANT     [2 ] GdDopedLS,LiquidScintillator 
             ReemissionYIELDRATIO           [2 ] GdDopedLS,LiquidScintillator 

             FASTCOMPONENT                  [2 ] GdDopedLS,LiquidScintillator     "Fast_Intensity"
             SLOWCOMPONENT                  [2 ] GdDopedLS,LiquidScintillator     "Slow_Intensity"
             REEMISSIONPROB                 [2 ] GdDopedLS,LiquidScintillator     "Reemission_Prob"

             ------------------------------------------------------------------------

             RAYLEIGH                       [5 ] GdDopedLS,Acrylic,Teflon,LiquidScintillator,MineralOil 
             RINDEX                         [14] Air,GdDopedLS,Acrylic,Teflon,LiquidScintillator,Bialkali,
                                                 Vacuum,Pyrex,MineralOil,Water,NitrogenGas,IwsWater,OwsWater,DeadWater 
             ABSLENGTH                      [20] PPE,Air,GdDopedLS,Acrylic,Teflon,LiquidScintillator,Bialkali,
                                                 Vacuum,Pyrex,UnstStainlessSteel,StainlessSteel,
                                                 ESR,MineralOil,Water,NitrogenGas,IwsWater,ADTableStainlessSteel,Tyvek,OwsWater,DeadWater 

        Observations:
 
        #. no RAYLEIGH for water 


        """
        keymap = {
            "RINDEX": 'refractive_index',
            "ABSLENGTH": 'absorption_length',
            "RAYLEIGH": 'scattering_length',
            "REEMISSIONPROB": 'reemission_prob',
        }

        keymat = {}
        collada = self.nodecls.orig
        for dmaterial in collada.materials:
            material = Material(dmaterial.id)
            if DEBUG:
                material.dae = dmaterial

            # vacuum like defaults ? is that appropriate ? what is the G4 equivalent ?
            material.set('refractive_index', 1.0)
            material.set('absorption_length', 1e6)
            material.set('scattering_length', 1e6)

            if dmaterial.extra is not None:
                props = dmaterial.extra.properties
                for dkey, dval in props.items():
                    if dkey not in keymat:
                        keymat[dkey] = []
                    keymat[dkey].append(
                        material.name
                    )  # record of materials that have each key

                    if dkey in keymap:
                        key = keymap[dkey]
                        material.set(key, dval[:, 1], wavelengths=dval[:, 0])
                        log.debug(
                            "for material %s set Chroma prop %s from G4DAE prop %s vals %s "
                            % (material.name, key, dkey, len(dval)))
                    else:
                        log.debug(
                            "for material %s skipping G4DAE prop %s vals %s " %
                            (material.name, dkey, len(dval)))
                    pass
                    self.setup_cdf(material, props)
                pass
            pass
            self.materials[material.name] = material
        pass
        log.debug("convert_materials G4DAE keys encountered : %s " %
                  len(keymat))
        if debug:
            for dkey in sorted(keymat, key=lambda _: len(keymat[_])):
                mats = keymat[dkey]
                print " %-30s [%-2s] %s " % (dkey, len(mats), ",".join(
                    map(matshorten, mats)))
示例#7
0
import numpy as np
from chroma.geometry import Material, Surface
from chroma.demo.optics import vacuum, r7081hqe_photocathode
import math

glass = Material('glass')
glass.set('refractive_index', 1.49)
glass.absorption_length = \
    np.array([(200, 0.1e-6), (300, 1000), (330, 1000.0), (500, 2000.0), (600, 1000.0), (770, 500.0), (800, 0.1e-6)])
glass.set('scattering_length', 1e6)

silica =   np.array([(180, .9), (200, .93), (220,.94), (240, .95), (260, .95), (280, .95), (800,.95)])
gel    =   np.array([(180, 0.0), (260, 0.0),(280, .09),(300.,.4), (320, .83), (365,.98), (404.7,0.99), (480,1.0), (800,1.0)])
mirror =   np.array([(180, 0), (220, 0), (240,.0), (260, .1), (280, .4), (300, .7), (340,.88), (360, .95), (400, .97), (550, .97), (600, .95), (700, .92), (800, .87)])

mcp_boro_photocathode = Surface('mcp_boro_photocathode')
mcp_silica_photocathode = Surface('mcp_silica_photocathode')

'''
mcp_boro_photocathode.detect = \
    np.array([(240.0,  0.00), (250.0,  0.04), (260.0,  2), 
              (270.0,  8.77), (280.0,  24), (290.0,  26), (300.0,  27),
              (310.0, 28.00), (320.0, 28.8), (330.0, 29.7), (340.0, 30.1),
              (350.0, 30.52), (360.0, 31.0), (370.0, 31.30), (380.0, 31.20),
              (390.0, 31.00), (400.0, 30.90), (410.0, 30.50), (420.0, 30.16),
              (430.0, 29.24), (440.0, 28.31), (450.0, 27.41), (460.0, 26.25),
              (470.0, 24.90), (480.0, 23.05), (490.0, 21.58), (500.0, 19.94),
              (510.0, 18.48), (520.0, 17.01), (530.0, 15.34), (540.0, 12.93),
              (550.0, 10.17), (560.0,  7.86), (570.0,  6.23), (580.0,  5.07),
              (590.0,  4.03), (600.0,  3.18), (610.0,  2.38), (620.0,  1.72),
              (630.0,  0.95), (640.0,  0.71), (650.0,  0.44), (660.0,  0.25),
示例#8
0
import numpy as np
from chroma.geometry import Material, Surface

vacuum = Material('vacuum')
vacuum.set('refractive_index', 1.0)
vacuum.set('absorption_length', 1e6)
vacuum.set('scattering_length', 1e6)

lambertian_surface = Surface('lambertian_surface')
lambertian_surface.set('reflect_diffuse', 1)

black_surface = Surface('black_surface')
black_surface.set('absorb', 1)

shiny_surface = Surface('shiny_surface')
shiny_surface.set('reflect_specular', 1)

glossy_surface = Surface('glossy_surface')
glossy_surface.set('reflect_diffuse', 0.5)
glossy_surface.set('reflect_specular', 0.5)

red_absorb_surface = Surface('red_absorb')
red_absorb_surface.set('absorb', [0.0, 0.0, 1.0], [465, 545, 685])
red_absorb_surface.set('reflect_diffuse', [1.0, 1.0, 0.0], [465, 545, 685])

# r7081hqe photocathode material surface
# source: hamamatsu supplied datasheet for r7081hqe pmt serial number zd0062
r7081hqe_photocathode = Surface('r7081hqe_photocathode')
r7081hqe_photocathode.detect = \
    np.array([(260.0,  0.00),
              (270.0,  0.04), (280.0,  0.07), (290.0,  0.77), (300.0,  4.57),