def render_particle_track(self): x = 10.0 h = x * np.sqrt(3) / 2 pyramid = make.linear_extrude([-x / 2, 0, x / 2], [-h / 2, h / 2, -h / 2], h, [0] * 3, [0] * 3) marker = Solid(pyramid, vacuum, vacuum) if self.photon_display_mode == 'beg': photons = self.ev.photons_beg else: photons = self.ev.photons_end geometry = Geometry() sample_factor = max(1, len(photons.pos) / 10000) for pos in photons.pos[::sample_factor]: geometry.add_solid(marker, displacement=pos, rotation=make_rotation_matrix( np.random.uniform(0, 2 * np.pi), uniform_sphere())) geometry = create_geometry_from_obj(geometry) gpu_geometry = gpu.GPUGeometry(geometry) self.gpu_geometries = [self.gpu_geometry, gpu_geometry]
def render_photons(self,geometry,photons): x = 10.0 h = x*np.sqrt(3)/2 pyramid = make.linear_extrude([-x/2,0,x/2], [-h/2,h/2,-h/2], h, [0]*3, [0]*3) marker = Solid(pyramid, vacuum, vacuum) sample_factor = 1 subset = photons[::sample_factor] for p,d,w in zip(subset.pos,subset.dir,subset.wavelengths): geometry.add_solid(marker, displacement=p, rotation=gen_rot([0,1,0],d))
def render_vertex( self, geometry, vertex, children=2, sz=5.0, colors={ 'mu+': 0x50E0FF, 'mu-': 0xFFE050, 'e+': 0x0000FF, 'e-': 0xFF0000, 'gamma': 0x00FF00 }): steps = np.vstack((vertex.steps.x, vertex.steps.y, vertex.steps.z)).T for index in range(len(steps) - 1): vec = steps[index + 1] - steps[index] mag = np.linalg.norm(vec) u = vec / mag axis = np.cross(u, [0, 0, 1]) ang = np.arccos(np.dot(u, [0, 0, 1])) rotmat = make_rotation_matrix(ang, axis) x = sz / 2 y = x * np.sqrt(3) / 2 segment = make.linear_extrude([-x, 0, x], [-y, y, -y], mag, [0, 0, 0], [0, 0, 0]) segment.vertices[:, 2] += mag / 2.0 marker = Solid(segment, vacuum, vacuum, color=colors[vertex.particle_name] if vertex.particle_name in colors else 0xAAAAAA) geometry.add_solid(marker, displacement=steps[index], rotation=rotmat) if children and vertex.children: for child in vertex.children: if isinstance(children, bool): self.render_vertex(geometry, child, children) else: self.render_vertex(geometry, child, children - 1)
def render_particle_track(self): x = 10.0 h = x*np.sqrt(3)/2 pyramid = make.linear_extrude([-x/2,0,x/2], [-h/2,h/2,-h/2], h, [0]*3, [0]*3) marker = Solid(pyramid, vacuum, vacuum) if self.photon_display_mode == 'beg': photons = self.ev.photons_beg else: photons = self.ev.photons_end geometry = Geometry() sample_factor = max(1, len(photons.pos) / 10000) for pos in photons.pos[::sample_factor]: geometry.add_solid(marker, displacement=pos, rotation=make_rotation_matrix(np.random.uniform(0,2*np.pi), uniform_sphere())) geometry = create_geometry_from_obj(geometry) gpu_geometry = gpu.GPUGeometry(geometry) self.gpu_geometries = [self.gpu_geometry, gpu_geometry]
def build_pmt_icosahedron(kabamland, vtx, focal_length=1.0): offset = 1.2 * (vtx + focal_length) angles = np.linspace(np.pi / 4, 2 * np.pi + np.pi / 4, 4, endpoint=False) square = make.linear_extrude(offset * np.sqrt(2) * np.cos(angles), offset * np.sqrt(2) * np.sin(angles), 2.0) vrs = np.eye(3) for vr in vrs: if np.array_equal(vr, [0, 0, 1]): kabamland.add_pmt(Solid(square, glass, kabamland.detector_material, lm.fullabsorb, 0xBBFFFFFF), displacement=offset * vr) kabamland.add_pmt(Solid(square, glass, kabamland.detector_material, lm.fullabsorb, 0xBBFFFFFF), displacement=-offset * vr) else: trasl = np.cross(vr, [0, 0, 1]) kabamland.add_pmt(Solid(square, glass, kabamland.detector_material, lm.fullabsorb, 0xBBFFFFFF), rotation=make_rotation_matrix(np.pi / 2, vr), displacement=offset * trasl) kabamland.add_pmt(Solid(square, glass, kabamland.detector_material, lm.fullabsorb, 0xBBFFFFFF), rotation=make_rotation_matrix(np.pi / 2, vr), displacement=-offset * trasl)
def main(suppress=False): ##### Loading in Results ##### print '-'*90 print 'ANALYSIS SCRIPT FOR VUV SIMULATION'.center(90,'=') print '-'*90 print 'Available files:\n' filenames = [] display = ['#','Date:','Time:','n:',u'\u03bb (nm)'.encode('utf-8'),u'd (\u03bcm)'.encode('utf-8'),u's (\u03bcm)'.encode('utf-8')] print '{:<3}{:<12}{:<9}{:<9}{:<9}{:<9}{:<9}'.format(*display) for pos,filename in enumerate(os.listdir('results/')): filenames.append(filename) date = re.findall('\d+\-\d+\-\d+',filename)[0] time = re.findall('\d{2}\:\d{2}',filename)[0] args = re.findall('\d+\:\d+:\d+\.\d+\:\d+\.\d+',filename)[0] display = [str(pos),date,time] + args.split(':') print '{:<3}{:<12}{:<9}{:<9}{:<8}{:<8}{:<9}'.format(*display) print '(d - Slit Width, s - Beam Width)' print '='*90 proceed = False while proceed == False: usrin = raw_input('Please select a file: ').strip() if usrin not in [str(i) for i in list(range(len(filenames)))]: print 'Bad input!' else: proceed = True selection = filenames[int(usrin)] n,wavelength,width,beamsize = [float(i) for i in re.findall('\d+\:\d+:\d+\.\d+\:\d+\.\d+',selection)[0].split(':')] #print '\nSelected: '+ selection + '\n' ##### Data Loading and Results ##### itm = 25.4 #Inches to millimetre conversion tol = 0.05 #Tolerance for selecting photons res = 10 #Seed resolution seed = np.genfromtxt('config/seed.dat',delimiter=',') #display seed x = 0.01 #marker params h = x*np.sqrt(3)/2 pyramid = make.linear_extrude([-x/2,0,x/2],[-h/2,h/2,-h/2],h,[0]*3,[0]*3) beg_marker = Solid(pyramid,vacuum,vacuum,color=0x32a8a2) #photon start marker end_marker = Solid(pyramid,vacuum,vacuum,color=0xfc0303) #photon end marker dir_marker = Solid(pyramid,vacuum,vacuum,color=0x00ff00) #Direction data = p.read_csv('results/'+selection,sep = '\t').values[:] photon_ids = data[:,0].astype(int) beg_pos = data[:,1:4] end_pos = data[:,4:7] wavelengths = data[:,7].astype(int) flags = data[:,8].astype(int) if suppress == False: if os.path.exists('config/geometry.pickle'): print 'Loading geometry from file...' geometry_path = open('config/geometry.pickle','rb') world = cPickle.load(geometry_path) world.add_solid(dir_marker,displacement = mfunctions.get_center('161')+np.array((0,1,0))) geometry_path.close() else: world = builder.build() #Regenerate geometry sipm_ids = [] pmt_ids = [] for p_id in photon_ids: if (flags[p_id] & 0x1 << 2) == 4: if abs(end_pos[p_id,2]-9.08933)<tol: #Photons detected at SiPM sipm_ids.append(p_id) elif abs(end_pos[p_id,0]-23.6555999)<tol: #Photons detected at PMT pmt_ids.append(p_id) if suppress == False and seed[p_id] <= 1.0/res: world.add_solid(beg_marker,displacement=beg_pos[p_id]) world.add_solid(end_marker,displacement=end_pos[p_id]) pcount = len(pmt_ids) scount = len(sipm_ids) print 'Total photons:\t\t', n print 'Detections (PMT):\t', pcount print 'Detections (SiPM):\t',scount print 'Relative detection rate: {:.2f}%'.format(100*float(scount+pcount)/len(photon_ids)) if suppress == False: view(world) elif suppress == True and scount == 0: print 'No photons detected!' exit() else: detectedx = np.asarray(list(end_pos[i,0]*itm for i in sipm_ids)) #Compiling points to plot and converting to mm detectedy = np.asarray(list(end_pos[i,1]*itm for i in sipm_ids)) detectedwavs = np.array(list(wavelengths[i] for i in pmt_ids)) meanx = np.mean(detectedx) #Mean detected positions meany = np.mean(detectedy) detectedx -= meanx #Centering plot about detected photons detectedy -= meany sampleset = np.sqrt(detectedx**2 + detectedy**2) #Heatmap info binwidth = 2*ss.iqr(sampleset)/np.cbrt(len(sampleset)) #Freedman-Diaconis rule bins = (max(sampleset)-min(sampleset))/binwidth heatmap,xedges,yedges = np.histogram2d(detectedx,detectedy,bins=bins) extent = [xedges[0],xedges[-1],yedges[0],yedges[-1]] fig = plt.figure() ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) ax1.axis('equal') ax2.axis('equal') fig.suptitle(u'n: {} | \u03bb: {}nm | d: {}\u03bcm | s: {}\u03bcm'.format(int(n),int(wavelength),width,beamsize)) r = 0.059813*itm #Iris radius theta = np.linspace(0,2*np.pi,1000) iris_center = np.array((18.4429,-21.8872))*itm iris_x = r*np.cos(theta)+iris_center[0]-meanx iris_y = r*np.sin(theta)+iris_center[1]-meany ax1.scatter(detectedx,detectedy,s=0.3,c='k',label='Photon Hits') #ax1.plot(iris_x,iris_y,c='r',label='Iris Overlay') ax1.set_xlabel('x (mm)') ax1.set_ylabel('y (mm)') ax1.set_title('SiPM Hits') ax1.legend() im = ax2.imshow(heatmap.T,extent=extent,origin='lower',cmap='hot_r',interpolation='gaussian') ax2.set_xlabel('x (mm)') ax2.set_ylabel('y (mm)') ax2.set_title('SiPM Heat Map') fig.colorbar(im,ax=ax2) plt.show()
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