def setUp(self): self.cache_dir = random_tempdir('chroma_cache_test') self.cache = Cache(self.cache_dir) self.a = Geometry() self.a.add_solid(Solid(box(1, 1, 1))) self.a.add_solid(Solid(box(1, 1, 1)), displacement=(10, 10, 10)) self.a.flatten() self.b = Geometry() self.b.add_solid(Solid(box(2, 2, 2))) self.b.add_solid(Solid(box(2, 2, 2)), displacement=(10, 10, 10)) self.b.add_solid(Solid(box(2, 2, 2)), displacement=(-10, -10, -10)) self.b.flatten()
def setUp(self): self.cache_dir = random_tempdir('chroma_cache_test') self.cache = Cache(self.cache_dir) self.a = Geometry() self.a.add_solid(Solid(box(1,1,1))) self.a.add_solid(Solid(box(1,1,1)), displacement=(10,10,10)) self.a.flatten() self.b = Geometry() self.b.add_solid(Solid(box(2,2,2))) self.b.add_solid(Solid(box(2,2,2)), displacement=(10,10,10)) self.b.add_solid(Solid(box(2,2,2)), displacement=(-10,-10,-10)) self.b.flatten()
def bvh_mesh(geometry, layer): lower_bounds, upper_bounds = geometry.bvh.get_layer(layer).get_bounds() if len(lower_bounds) == 0 or len(upper_bounds) == 0: raise Exception('no nodes at layer %i' % layer) dx, dy, dz = upper_bounds[0] - lower_bounds[0] center = np.mean([upper_bounds[0],lower_bounds[0]], axis=0) mesh = make.box(dx, dy, dz, center) for center, dx, dy, dz in zip(np.mean([lower_bounds,upper_bounds],axis=0), *zip(*upper_bounds-lower_bounds))[1:]: mesh += make.box(dx,dy,dz,center) return mesh
def build_detector(): """Returns a cubic detector made of cubic photodetectors.""" g = Geometry(water) for pos, dir in iter_box(nx,ny,nz,spacing): # convert to arrays pos, dir = np.array(pos), np.array(dir) # we need to figure out what rotation matrix to apply to each # photodetector so that the photosensitive surface will be facing # `dir`. if tuple(dir) == (0,0,1): rotation = None elif tuple(dir) == (0,0,-1): rotation = make_rotation_matrix(np.pi,(1,0,0)) else: rotation = make_rotation_matrix(np.arccos(dir.dot((0,0,1))), np.cross(dir,(0,0,1))) # add the photodetector g.add_solid(build_pd(size,glass_thickness),rotation=rotation, displacement=pos) world = Solid(make.box(spacing*nx,spacing*ny,spacing*nz),water,vacuum, color=0x33ffffff) g.add_solid(world) return g
def build_detector(): """Returns a cubic detector made of cubic photodetectors.""" g = Geometry(water) for pos, dir in iter_box(nx, ny, nz, spacing): # convert to arrays pos, dir = np.array(pos), np.array(dir) # we need to figure out what rotation matrix to apply to each # photodetector so that the photosensitive surface will be facing # `dir`. if tuple(dir) == (0, 0, 1): rotation = None elif tuple(dir) == (0, 0, -1): rotation = make_rotation_matrix(np.pi, (1, 0, 0)) else: rotation = make_rotation_matrix(np.arccos(dir.dot((0, 0, 1))), np.cross(dir, (0, 0, 1))) # add the photodetector g.add_solid(build_pd(size, glass_thickness), rotation=rotation, displacement=pos) world = Solid(make.box(spacing * nx, spacing * ny, spacing * nz), water, vacuum, color=0x33ffffff) g.add_solid(world) return g
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]
def bvh_mesh(geometry, layer): lower_bounds, upper_bounds = geometry.bvh.get_layer(layer).get_bounds() if len(lower_bounds) == 0 or len(upper_bounds) == 0: raise Exception('no nodes at layer %i' % layer) dx, dy, dz = upper_bounds[0] - lower_bounds[0] center = np.mean([upper_bounds[0],lower_bounds[0]], axis=0) geometry = Geometry() geometry.add_solid(Solid(make.box(dx,dy,dz,center), vacuum, vacuum, color=0x33ffffff)) for center, dx, dy, dz in list(zip(np.mean([lower_bounds,upper_bounds],axis=0), *list(zip(*upper_bounds-lower_bounds))))[1:]: geometry.add_solid(Solid(make.box(dx,dy,dz,center), vacuum, vacuum, color=0x33ffffff)) return create_geometry_from_obj(geometry)
def setUp(self): # Setup geometry cube = Detector(vacuum) cube.add_pmt(Solid(box(10.0,10,10), vacuum, vacuum, surface=r7081hqe_photocathode)) cube.set_time_dist_gaussian(1.2, -6.0, 6.0) cube.set_charge_dist_gaussian(1.0, 0.1, 0.5, 1.5) geo = create_geometry_from_obj(cube, update_bvh_cache=False) self.geo = geo self.sim = Simulation(self.geo, geant4_processes=0)
def setUp(self): self.cache_dir = random_tempdir('chroma_cache_test') self.cache = Cache(self.cache_dir) self.a = Geometry() self.a.add_solid(Solid(box(1, 1, 1))) self.a.add_solid(Solid(box(1, 1, 1)), displacement=(10, 10, 10)) self.a.flatten() self.b = Geometry() self.b.add_solid(Solid(box(2, 2, 2))) self.b.add_solid(Solid(box(2, 2, 2)), displacement=(10, 10, 10)) self.b.add_solid(Solid(box(2, 2, 2)), displacement=(-10, -10, -10)) self.b.flatten() # c is not in cache self.c = Geometry() self.c.add_solid(Solid(box(2, 2, 2))) self.c.flatten() self.a_hash = self.a.mesh.md5() self.b_hash = self.b.mesh.md5() self.c_hash = self.c.mesh.md5() self.cache.save_geometry('a', self.a) self.cache.save_geometry('b', self.b)
def setUp(self): self.cache_dir = random_tempdir('chroma_cache_test') self.cache = Cache(self.cache_dir) self.a = Geometry() self.a.add_solid(Solid(box(1,1,1))) self.a.add_solid(Solid(box(1,1,1)), displacement=(10,10,10)) self.a.flatten() self.b = Geometry() self.b.add_solid(Solid(box(2,2,2))) self.b.add_solid(Solid(box(2,2,2)), displacement=(10,10,10)) self.b.add_solid(Solid(box(2,2,2)), displacement=(-10,-10,-10)) self.b.flatten() # c is not in cache self.c = Geometry() self.c.add_solid(Solid(box(2,2,2))) self.c.flatten() self.a_hash = self.a.mesh.md5() self.b_hash = self.b.mesh.md5() self.c_hash = self.c.mesh.md5() self.cache.save_geometry('a', self.a) self.cache.save_geometry('b', self.b)
def setUp(self): # Setup geometry cube = Detector(vacuum) cube.add_pmt( Solid(box(10.0, 10, 10), vacuum, vacuum, surface=r7081hqe_photocathode)) cube.set_time_dist_gaussian(1.2, -6.0, 6.0) cube.set_charge_dist_gaussian(1.0, 0.1, 0.5, 1.5) geo = create_geometry_from_obj(cube, update_bvh_cache=False) self.geo = geo self.sim = Simulation(self.geo, geant4_processes=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())
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)
def build_detector(): """Returns a cubic detector made of cubic photodetectors.""" world_size = 1000000 # 1 km d = Detector(ice) #add DOMs at locations x,y,z channel_id = 0 for x in np.arange(-500000,500001,100000): for y in np.arange(-500000,500001,100000): for z in np.arange(-500000,500001,100000): d.add_pmt(build_dom(),displacement=(x,y,z),channel_id=channel_id) channel_id += 1 world = Solid(make.box(world_size,world_size,world_size),ice,vacuum,color=0x33ffffff) d.add_solid(world) return d
def setUp(self): # Setup geometry cube = Detector(vacuum) cube.add_pmt( Solid(box(10.0, 10.0, 10.0), vacuum, vacuum, surface=r7081hqe_photocathode)) cube.set_time_dist_gaussian(1.2, -6.0, 6.0) cube.set_charge_dist_gaussian(1.0, 0.1, 0.5, 1.5) geo = create_geometry_from_obj(cube, update_bvh_cache=True, read_bvh_cache=False) print "Number of channels in detector: ", geo.num_channels() self.geo = geo self.sim = Simulation(self.geo, geant4_processes=0, nthreads_per_block=1, max_blocks=1) self.rfile = rt.TFile("output_test_detector.root", "recreate") self.htime = rt.TH1D("htime", "Time;ns", 120, 80, 120) self.hcharge = rt.TH1D("hcharge", "Charge;pe", 100, 0.5, 1.5)
def build(slit_width): directory = 'stls/' #directory containing individual detector .stls ##### Generating World ##### print 'Generating world...' size = (40,40,40) #Bounds for world box world = Geometry(vacuum) bounds = Solid(make.box(*size),vacuum,vacuum,color=0x33ffffff) world.add_solid(bounds,displacement=(18,-18,10)) ##### Generating Non-Special Solids ##### print 'Generating non-special solids...' blacklist = mfunctions.get_blacklist() #Mesh read-in blacklist tol = 0.005 #Tolerance for painting meshes using conditionals setup_solid = Solid(make.cube(1),vacuum,vacuum,color=0xf0fc03) #origin for filename in os.listdir(directory): path = os.path.join(directory,filename) tmp_mesh = mesh_from_stl(path) mesh_no = re.findall('\d+',path)[0] #Select mesh number if mesh_no in ['141','142']: #Angled mirrors setup_surf, setup_col = mfunctions.mirror(mesh_no) """ elif mesh_no in ['161','206']: #Slit housing setup_surf = shiny_surface setup_col = 0x7d6b56 #grey """ else: #Non-optical components setup_surf = black_surface setup_col = 0x7d6b56 #grey #print 'Adding solid '+mesh_no+'/249' if mesh_no not in blacklist: #Remove blacklisted meshes from setup setup_solid += Solid(tmp_mesh,vacuum,vacuum,surface=setup_surf,color=setup_col) world.add_solid(setup_solid) ##### Generating Special Solids ##### print 'Generating special solids...' """ #Laser Absorb laser_absorb = Solid(make.segmented_cylinder(1,0.1),vacuum,vacuum,surface=black_surface,color=0xffff00) cap_center = np.array((18.470600,-26.771999,19.469999)) world.add_solid(laser_absorb,displacement=cap_center) """ #SiPM Plate sipm_plate = Solid(mesh_from_stl(directory+'vuv_setup - Mesh 188.stl'),vacuum,vacuum,surface=black_surface,color=0xfc7f03) rotation_matrix = mfunctions.Ry(np.arctan(0.0755832)) #Correction for SiPM plate rotation in the STL sipm_center = np.array((18.48695,-22.89630,9.08933)) #Centre of SiPM plate correction = sipm_center-np.matmul(rotation_matrix,sipm_center) #Off-centre rotation induces displacement, this corrects for this world.add_solid(sipm_plate,rotation=rotation_matrix,displacement=correction+np.array((0,1,0))) #Detector Plate/SiPM detector = Solid(make.box(2,3,0.01),vacuum,vacuum,surface=mfunctions.get_sipm_surface(),color=0x0dff00) world.add_solid(detector,displacement=sipm_center+np.array((0,0.8,0))) #Closed Mirror #mirror_surf,mirror_col = mfunctions.mirror('250') mirror_surf = mfunctions.get_mirror_surface() mirror_col = 0xe6ad12 closed_mirror = Solid(mesh_from_stl(directory+'vuv_setup - Mesh 250.stl'),vacuum,vacuum,surface=mirror_surf,color=mirror_col) world.add_solid(closed_mirror,rotation=mfunctions.Ry(np.pi),displacement=np.array((18.470901,-21.916050,19.602501))+np.array((0,0,0.613293))) #Post-Monochromator Slit Doors basex = np.array((0.0,0.0,0.074744,0.6,0.6))#x-points for door base basey = np.array((0.0,0.00488564,0.0800017,0.0800017,0.0))#y-points height = 0.65 #Max slit width: 1000micron door1 = make.linear_extrude(basex,basey,height) door2 = make.linear_extrude(-basex,basey,height) slit_center = mfunctions.get_center('161') door1_solid = Solid(door1,vacuum,vacuum,surface=shiny_surface,color=0xffff00) door2_solid = Solid(door2,vacuum,vacuum,surface=shiny_surface,color=0xffff00) world.add_solid(door1_solid,displacement=slit_center+np.array((0.5*slit_width,-0.144076,-0.05))) world.add_solid(door2_solid,displacement=slit_center+np.array((-0.5*slit_width,-0.144076,-0.05))) #PMT plate pmt_center = mfunctions.get_center('210') pmt_center += np.array((0.4,0,0)) pmt_solid = Solid(make.segmented_cylinder(1.5,0.1),vacuum,vacuum,surface=mfunctions.get_pmt_surface(),color=0x0dff00) world.add_solid(pmt_solid,rotation=mfunctions.Rz(np.pi/2),displacement=pmt_center) ##### Saving Geometry to File ##### config_path = open('config/geometry.pickle','wb') cPickle.dump(world,config_path) config_path.close() config_path = open('config/vars.txt','wb') config_path.write(str(slit_width)+'\n') config_path.write('This is the config file for geometry.pickle.\nAltering this file will cause geometry.pickle to regenerate!') config_path.close() print 'Done.' return world