WCSim
findClosestPacking.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import math
3 import numpy as np
4 from scipy.optimize import root, brentq #root needs scipy 0.11.0 (python > 2.7?)
5 
6 print 'Make sure you have scipy > 0.11.0 or adjust the rootsolver function'
7 #eq. 11 from Meas. Sci. Technol. 10 (1999) 1015-1019.
8 def view_angle_func(x,alpha_prev,eta_prev, n_in_circ):
9  if np.cos(x*math.pi/180)*np.cos(x*math.pi/180) - np.sin((alpha_prev + x + eta_prev)*math.pi/180)*np.sin((alpha_prev + x + eta_prev)*math.pi/180) < 0:
10  return -100
11  return math.sqrt(np.cos(x*math.pi/180)*np.cos(x*math.pi/180)
12  - np.sin((alpha_prev + x + eta_prev)*math.pi/180)*
13  np.sin((alpha_prev + x + eta_prev)*math.pi/180))/np.cos((alpha_prev+x+eta_prev)*math.pi/180) - np.cos(math.pi/n_in_circ)
14 
15 
16 id_spacing = 1.33 # meter (1 PD/1.5m^2)
17 nPMT = 33
18 min_angle = 13 # np.arctan( radius + expose + outer_thickness + dist_glass_to_cover/ id_spacing) : (245mm + 15.3mm + 16 mm + 2.5 mm / sqrt(1500 mm))
19 configs = []
20 # Circle 1
21 i = nPMT
22 while i > 11:
23  # Circle 2
24  j = nPMT-i
25  while j > 0:
26  # Circle 3
27  k = nPMT-i-j
28  while k > 0:
29  # Circle 4
30  l = nPMT-i-j-k
31  while l > 0:
32  #'''
33  # Circle 5: too slow
34  #m = nPMT-i-j-k-l
35  #while m > 0:
36  for m in [0,1]:
37  if i+j+k+l+m == nPMT and k > 1 and l > 1 and j > 1:
38  configs.append((i,j,k,l,m))
39  #m -= 1
40  #'''
41  if i+j+k+l == nPMT and k > 1 and j > 1:
42  configs.append((i,j,k,l,0))
43  l -= 1
44  if i+j+k == nPMT and j > 1:
45  configs.append((i,j,k,0,0))
46  k -= 1
47  if i+j == nPMT:
48  configs.append((i,j,0,0,0))
49  j -= 1
50  if i == nPMT:
51  configs.append((i,0,0,0,0))
52  i -= 1
53 
54 
60 view_angles_conf = [] #only minimum angle per conf
61 alpha_conf = dict()
62 eta_conf = dict()
63 for conf in configs:
64  alpha0 = min_angle
65  eta0 = 0
66  view_angles = []
67  alphas = []
68  etas = []
69  for nPMT_per_circ in conf:
70  if nPMT_per_circ > 1:
71  sol = root(view_angle_func, 0.01, (alpha0, eta0, nPMT_per_circ))
72  #print conf, nPMT_per_circ, sol.x[0]
73  alpha0 = alpha0 + eta0 + sol.x[0]
74  eta0 = sol.x[0]
75  etas.append(eta0)
76  alphas.append(alpha0)
77  view_angles.append(sol.x[0])
78  elif nPMT_per_circ == 1:
79  alphas.append(90)
80  etas.append(90-eta0-alpha0)
81  view_angles.append(90-eta0-alpha0)
82  #print conf, nPMT_per_circ, 90-eta0-alpha0
83  alpha_conf[conf] = alphas
84  eta_conf[conf] = etas
85  if len(view_angles) > 1:
86  view_angles_conf.append(min(view_angles))
87  elif len(view_angles) == 1:
88  view_angles_conf.append(view_angles[0])
89 
90 opt_view_angle = max(view_angles_conf)
91 print "Optimal viewing angle %.2lf " %(opt_view_angle)
92 
93 print "Total number of PMTs: %i" %(nPMT)
94 print "Percentage of covered hemispherical surface = %.2lf %%" %(nPMT*(1-np.cos(opt_view_angle*math.pi/180))*100)
95 print "Percentage of covered hemispherical surface above min. tilt= %.2lf %%" %(nPMT*(1-np.cos(opt_view_angle*math.pi/180))*100/
96  (1-np.cos(math.pi/2 - min_angle*math.pi/180)))
97 
98 
99 
100 
101 i = 0
102 candidate = 0
103 for conf in configs:
104  if abs(view_angles_conf[i]-max(view_angles_conf)) < 0.1: #1:
105  candidate += 1
106  print conf, view_angles_conf[i]
107  # Write best one(s) to separate txt file.
108  # I want full config, the eta's and the alpha's
109  outfile = open('mPMTconfig_%i_%i_%i.txt'%(nPMT,min_angle,candidate),'w')
110  for j in conf:
111  outfile.write('%i '%j)
112  outfile.write('\n')
113  for j in eta_conf[conf]:
114  outfile.write('%.3lf '%j)
115  outfile.write('\n')
116  for j in alpha_conf[conf]:
117  outfile.write('%.3lf '%j)
118  outfile.write('\n')
119 
120  outfile.close()
121  i += 1
122 
123 
def view_angle_func(x, alpha_prev, eta_prev, n_in_circ)