In [ ]:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
matplotlib.rc('font', size=12)
In [ ]:
## functions to calculate the pmt positions in the top and bottom arrays
# adapted from the XENON1T MC:
# G4ThreeVector Xenon1tDetectorConstruction::GetPMTsPositionTopArray(G4int iPMTNb)
# and
# G4ThreeVector Xenon1tDetectorConstruction::GetPMTsPositionBottomArray(G4int iPMTNb)
# Some constants taken from the XENON1T MC
PMT_distance_top = 7.95 # cm
PMT_distance_bottom = 8.0 # cm
PMTOuterRingRadius = 3.875 # cm
def get_pmt_positions_top(number):
array = [i*6 for i in range(7)]
array[0] = 1
radius = [i*PMT_distance_top for i in range(7)]
index1 = 0
iTotal = array[0]
while number > iTotal:
index1 += 1
iTotal += array[index1]
index2 = number + array[index1] - iTotal
x = radius[index1] * np.cos(index2*np.pi*2 / array[index1])
y = radius[index1] * np.sin(index2*np.pi*2 / array[index1])
return x, y
def get_pmt_positions_bottom(number):
row_distance = np.sqrt(3.)/2. * PMT_distance_bottom
n_rows = 13;
n_pmts_top = 127
array = [5, 8, 9, 10, 11, 12, 11, 12, 11, 10, 9, 8, 5]
PMTsRowOffset = []
for i in range(n_rows):
PMTsRowOffset.append(-0.5*(array[i]-1)*PMT_distance_bottom)
index1 = 0
iTotal = array[0]
while number > n_pmts_top+iTotal:
index1 += 1
iTotal += array[index1]
index2 = number + array[index1] - iTotal -(n_pmts_top+1)
x = PMTsRowOffset[index1] + (index2 * PMT_distance_bottom)
y = ((0.5*(n_rows-1)-index1) * row_distance);
return x, y
# rotate tuple over certain angle
def rotate(pos, angle):
return (pos[0]*np.cos(angle) -pos[1]*np.sin(angle), pos[0]*np.sin(angle) + pos[1]*np.cos(angle))
In [ ]:
positions_top = np.array([get_pmt_positions_top(i) for i in range(1, 128)])
# The rotation made is one quarter plus 1.5 PMT (so that pmts 1 and 2 are horizontal and pmts 10 and 11 are vertical)
rotation_angle_top = np.pi/2 + (3/72)*2*np.pi # Is this the correct rotation?
positions_top = np.array([rotate(pos, rotation_angle_top) for pos in positions_top])
xs_top = positions_top[:,0]
ys_top = positions_top[:,1]
In [ ]:
positions_bottom = np.array([get_pmt_positions_bottom(i) for i in range(128, 121+127+1)])
rotation_angle_bottom = np.pi/8 # Is this the correct rotation?
positions_bottom = np.array([rotate(pos, rotation_angle_bottom) for pos in positions_bottom])
xs_bottom = positions_bottom[:,0]
ys_bottom = positions_bottom[:,1]
In [ ]:
plt.figure(figsize=(10,10))
plt.scatter(xs_top, ys_top, s=900, facecolors='none', edgecolors='r')
for i in range(127):
# NOTE that the indices are in reverse
plt.annotate(str(126-i), xy=(xs_top[i]-1.5, ys_top[i]-0.8))
plt.show()
# circle sizes are only an indication
In [ ]:
plt.figure(figsize=(10,10))
plt.scatter(xs_bottom, ys_bottom, s=900, facecolors='none', edgecolors='r')
for i in range(121):
plt.annotate(str(127+i), xy=(xs_bottom[i]-1.5, ys_bottom[i]-0.8))
plt.show()
# circle sizes are only an indication
In [ ]:
# make the final list
# 127 top pmts + 121 bottom pmts
# print(len(positions_top))
# print(len(positions_bottom))
pmt_locations = []
for i in range(127):
pmt_locations.append({'x': xs_top[127-1-i], 'y': ys_top[127-1-i]})
for i in range(121):
pmt_locations.append({'x': xs_bottom[i], 'y': ys_bottom[i]})
In [ ]:
len(pmt_locations)
In [ ]:
# double check once more by plot and add correct size PMT (3 inch diameter)
top_channels = list(range(0, 127))
bottom_channels = list(range(127, 247+1))
plot_radius = 60
plt.figure(figsize=(10,10))
plt.xlim((-plot_radius, plot_radius))
plt.ylim((-plot_radius, plot_radius))
for ch in top_channels:
plt.gca().add_artist(plt.Circle((pmt_locations[ch]['x'],pmt_locations[ch]['y']),
PMTOuterRingRadius,
edgecolor='red',
fill=None))
plt.annotate(str(ch), xy=(pmt_locations[ch]['x']-1.4,pmt_locations[ch]['y']-0.8))
plt.xlabel('x [cm]')
plt.ylabel('y [cm]')
plt.title('XENON1T Top PMT array')
plt.annotate(' WT Door', fontsize=15, xy=(40, 58), xytext=(40, 45),
arrowprops=dict(facecolor='black', shrink=0.2))
plt.annotate(' Building', fontsize=15, xy=(40, -58), xytext=(40, -45),
arrowprops=dict(facecolor='black', shrink=0.2))
plt.text(-55, 55, 'As seen from above', fontsize=15)
#plt.savefig('XENON1T_Top.png', format='png', dpi=300)
plt.show()
plt.figure(figsize=(10,10))
plt.xlim((-plot_radius, plot_radius))
plt.ylim((-plot_radius, plot_radius))
for ch in bottom_channels:
plt.gca().add_artist(plt.Circle((pmt_locations[ch]['x'],pmt_locations[ch]['y']),
PMTOuterRingRadius,
edgecolor='red',
fill=None))
plt.annotate(str(ch), xy=(pmt_locations[ch]['x']-1.7,pmt_locations[ch]['y']-0.8))
plt.xlabel('x [cm]')
plt.ylabel('y [cm]')
plt.title('XENON1T Bottom PMT array')
plt.annotate(' WT Door', fontsize=15, xy=(40, 58), xytext=(40, 45),
arrowprops=dict(facecolor='black', shrink=0.2))
plt.annotate(' Building', fontsize=15, xy=(40, -58), xytext=(40, -45),
arrowprops=dict(facecolor='black', shrink=0.2))
plt.text(-55, 55, 'As seen from above', fontsize=15)
#plt.savefig('XENON1T_Bottom.png', format='png', dpi=300)
plt.show()
In [ ]:
pmt_locations
In [ ]: