def HexArray(Separation = 14.6, hexNum = 11, SplitCore = False, NineWaySplitCore = False, SplitCoreOutriggers = False, JoshsOutriggers = False, RedundantOutriggers = False, LoadHERAOutriggers = False, fiducialInriggers = False, redundantTriangleInriggers = False, redundantPairInriggers = False, redundantHexInriggers = False, halfCornerInriggers = False, fullCornerInriggers = False, **kwargs): precisionFactor = 1000000 #Calculating Positions: #Main Hex positions = []; for row in range(hexNum-1,-(hexNum)+SplitCore,-1): # for row in range(hexNum-1,-(hexNum),-1): for col in range(2*hexNum-abs(row)-1): xPos = ((-(2*hexNum-abs(row))+2)/2.0 + col)*Separation; yPos = row*Separation*3**.5/2; positions.append([xPos, yPos, 0]) nCore = len(positions) right = Separation*np.asarray([1,0,0]) up = Separation*np.asarray([0,1,0]) upRight = Separation*np.asarray([.5,3**.5/2,0]) upLeft = Separation*np.asarray([-.5,3**.5/2,0]) # #Split the core into 3 pieces if SplitCore: for i,pos in enumerate(positions): theta = np.arctan2(pos[1],pos[0]) if not (pos[0]==0 and pos[1]==0): if (theta > -np.pi/3 and theta < np.pi/3): positions[i] = np.asarray(pos) + (upRight + upLeft)/3 if (theta >= np.pi/3 and theta < np.pi): positions[i] = np.asarray(pos) +upLeft - (upRight + upLeft)/3 if NineWaySplitCore: from sympy.geometry import RegularPolygon, Point, Polygon distances = np.asarray([np.linalg.norm(pos) for pos in positions]) fullRadius = np.max(distances) interiorHex = RegularPolygon(Point(0, 0), 1.001*3**-.5*fullRadius, 6) interiorHex.spin(np.pi/6) interiorHex = Polygon(*[Point(vert.x.evalf(), vert.y.evalf()) for vert in interiorHex.vertices]) positions.remove(positions[76]) isInterior = np.zeros(len(positions),dtype=bool) for i,pos in enumerate(positions): if distances[i] < fullRadius/2.0: isInterior[i] = True elif distances[i] <= 3**-.5*fullRadius and interiorHex.encloses_point(Point(pos[0],pos[1])): isInterior[i] = True v1 = (upRight + upLeft)/3 v2 = right/3 for i,pos in enumerate(positions): theta = np.arctan2(pos[1],pos[0]) if isInterior[i]: if not (pos[0]==0 and pos[1]==0): if (theta > -np.pi/3 and theta < np.pi/3): #right positions[i] = np.asarray(pos) +v1 if (theta >= np.pi/3 and theta < np.pi): #top left positions[i] = np.asarray(pos) +upLeft - v1 else: if (theta > -np.pi/6 and theta < np.pi/6): #right positions[i] = np.asarray(pos) + 2*v2 if (theta <= -5*np.pi/6 or theta >= 5*np.pi/6): #left positions[i] = np.asarray(pos) -v2 - right if (theta > -np.pi/2 and theta <= -np.pi/6): #bottom right positions[i] = np.asarray(pos) -v1 +v2 if (theta > -5*np.pi/6 and theta <= -np.pi/2): #bottom left positions[i] = np.asarray(pos) -v1-v2 if (theta >= np.pi/6 and theta < np.pi/2): #top right positions[i] = np.asarray(pos) + v1 + 2*v2 if (theta >= np.pi/2 and theta < 5*np.pi/6): #top left positions[i] = np.asarray(pos) +v1-2*v2 nCore = len(positions) #Aaron's fiducial inriggers if fiducialInriggers: print "adding Aaron's inriggers" if hexNum % 2 == 1: positions.append(upRight + ((hexNum-1)/2 + 1.0/3**.5/2.0) * (upLeft + upRight)) positions.append(right + ((hexNum-1)/2 + 1.0/3**.5/2.0) * (right + upRight)) positions.append(right + ((hexNum+1)/2 + 1.0/3**.5/2.0) * (-right + upLeft)) else: positions.append(((hexNum)/2 + 1.0/3**.5/2.0) * (upLeft + upRight)) positions.append(((hexNum)/2 + 1.0/3**.5/2.0) * (right + upRight)) positions.append(((hexNum)/2 + 1.0/3**.5/2.0) * (-right + upLeft)) #Redundant Inriggers if redundantTriangleInriggers or redundantPairInriggers or redundantHexInriggers: hexNumInrigger = 2 if hexNum % 2 == 1: inriggerCenters = [((hexNum-1)/2) * (upLeft + upRight) + upLeft + upLeft + right + (right + upRight)/3, #top -((hexNum-1)/2) * (upLeft + upRight) - upLeft - upLeft - 2*(right + upRight)/3, #bottom -(-(hexNum-1)/2 * (upRight + right) - upRight - right - (right + upRight)/3), #top right -((hexNum-1)/2 * (upRight + right) + upRight + 2*(right + upRight)/3), #bottom left (hexNum-1)/2 * (upLeft - right) + upLeft + upRight - right - 2*(right + upRight)/3, #top left -(hexNum-1)/2 * (upLeft - right) - upLeft + right + (right + upRight)/3] #top right else: inriggerCenters = [hexNum/2 * (upLeft + upRight) + upLeft + (right + upRight)/3, #top -hexNum/2 * (upLeft + upRight) - upLeft - 2*(right + upRight)/3, #bottom hexNum/2 * (upRight + right) + 2*(right + upRight)/3, #top right -hexNum/2 * (upRight + right) - right - (right + upRight)/3, #bottom left hexNum/2 * (upLeft - right) + upRight - right - 2*(right + upRight)/3, #top left -hexNum/2 * (upLeft - right) - upLeft + (right + upRight)/3] #top right for newCenter in inriggerCenters: for row in range(hexNumInrigger-1,-(hexNumInrigger),-1): for col in range(2*hexNumInrigger-abs(row)-1): xPos = ((-(2*hexNumInrigger-abs(row))+2)/2.0 + col)*Separation + newCenter[0] yPos = row*Separation*3**.5/2 + newCenter[1] if redundantHexInriggers: positions.append([xPos, yPos, 0]) elif redundantTriangleInriggers: if (xPos**2+yPos**2)**.5 < np.linalg.norm(newCenter) or np.array_equal(np.array([xPos, yPos, 0]), newCenter): positions.append([xPos, yPos, 0]) elif redundantPairInriggers: if (xPos**2+yPos**2)**.5 < np.linalg.norm(newCenter): positions.append([xPos, yPos, 0]) #Redundantly calibratable inriggers with full UV coverage if fullCornerInriggers or halfCornerInriggers: positions.append(hexNum * (upLeft) + (right + upRight)/3) positions.append(hexNum * (upLeft) - (right + upRight)/3) positions.append(hexNum * (upRight) + (-right + upLeft)/3) positions.append(hexNum * (upRight) - (-right + upLeft)/3) positions.append(hexNum * (right) + (upRight + upLeft)/3) positions.append(hexNum * (right) - (upRight + upLeft)/3) if fullCornerInriggers: positions.append(-(hexNum * (upLeft) + (right + upRight)/3)) positions.append(-(hexNum * (upLeft) - (right + upRight)/3)) positions.append(-(hexNum * (upRight) + (-right + upLeft)/3)) positions.append(-(hexNum * (upRight) - (-right + upLeft)/3)) positions.append(-(hexNum * (right) + (upRight + upLeft)/3)) positions.append(-(hexNum * (right) - (upRight + upLeft)/3)) #Half Wavelength Stuff # for i in range(1,14): # positions.append(i*(upLeft + upRight)/27) #%% #Outriggers if SplitCoreOutriggers: exteriorHexNum = 4 for row in range(exteriorHexNum-1,-(exteriorHexNum),-1): for col in range(2*exteriorHexNum-abs(row)-1): xPos = ((-(2*exteriorHexNum-abs(row))+2)/2.0 + col)*Separation*(hexNum-1) yPos = row*Separation*(hexNum-1)*3**.5/2 theta = np.arctan2(yPos,xPos) if ((xPos**2 + yPos**2)**.5 > Separation*(hexNum+1)): if (theta > -np.pi/3 and theta < np.pi/3): positions.append(np.asarray([xPos, yPos, 0]) + (upRight + upLeft)/3) elif (theta >= np.pi/3 and theta < np.pi): positions.append(np.asarray([xPos, yPos, 0]) +upLeft - (upRight + upLeft)/3) else: positions.append([xPos, yPos, 0]) if JoshsOutriggers: outriggerHexNum = 3 for row in range(outriggerHexNum-1,-(outriggerHexNum),-1): for col in range(2*outriggerHexNum-abs(row)-1): xPos = ((-(2*outriggerHexNum-abs(row))+2)/2.0 + col)*Separation*(np.floor(1.5*hexNum)); yPos = row*Separation*(np.floor(1.5*hexNum))*3**.5/2; if xPos != 0 or yPos != 0: positions.append([xPos, yPos, 0]) if RedundantOutriggers: outriggerHexNum = 3 for row in range(outriggerHexNum-1,-(outriggerHexNum),-1): for col in range(2*outriggerHexNum-abs(row)-1): yPos = ((-(2*outriggerHexNum-abs(row))+2)/2.0 + col)*Separation*(3**.5*(hexNum-1)); xPos = row*Separation*(3**.5*(hexNum-1))*3**.5/2; if xPos != 0 or yPos != 0: positions.append([xPos, yPos, 0]) if LoadHERAOutriggers: outriggerPositions = np.loadtxt(os.path.dirname(os.path.abspath(__file__)) + '/hexconfig352_outriggers_only.dat') for outrigger in outriggerPositions: positions.append(np.append(outrigger,0)) precisionFactor = 10000 #Calculating Baselines nAntennas = len(positions) baselines = [] baselinePairs = [] #print "WARNING: DOUBLING UNIQUE BASELINES!!!" for ant1 in range(nAntennas): for ant2 in range(ant1+1,nAntennas): deltax = int(np.round(precisionFactor*(positions[ant1][0]-positions[ant2][0]))) deltay = int(np.round(precisionFactor*(positions[ant1][1]-positions[ant2][1]))) deltaz = int(np.round(precisionFactor*(positions[ant1][2]-positions[ant2][2]))) if (deltax**2+deltay**2+deltaz**2 < precisionFactor**2*Separation**2): print "WARNING: antennas " + str(ant1) + " and " + str(ant2) + " are too close together!" if deltay > 0 or (deltay == 0 and deltax > 0): baselines.append((deltax, deltay, deltaz)) baselinePairs.append((ant1, ant2)) else: baselines.append((-deltax, -deltay, -deltaz)) baselinePairs.append((ant2, ant1)) #Calculating Unique Baselines baselineDict = {} for b in range(len(baselines)): if baselineDict.has_key(baselines[b]): baselineDict[baselines[b]].append(baselinePairs[b]) else: baselineDict[baselines[b]] = [baselinePairs[b]] print "With", len(positions), "antennas there are", len(baselineDict.items()), "unique baselines." #Saving results scriptDirectory = os.path.dirname(os.path.abspath(__file__)) np.savetxt(scriptDirectory + "/antenna_positions.dat",np.asarray(positions)) np.savetxt(scriptDirectory + "/all_baselines.dat",np.asarray(baselines)/(1.0*precisionFactor)) np.savetxt(scriptDirectory + "/all_baseline_pairs.dat",np.asarray(baselinePairs),fmt='%i') np.savetxt(scriptDirectory + "/unique_baselines.dat",np.asarray([uniqueBaseline[0] for uniqueBaseline in baselineDict.items()])/(1.0*precisionFactor)) np.savetxt(scriptDirectory + "/redundancy.dat",np.asarray([len(uniqueBaseline[1]) for uniqueBaseline in baselineDict.items()]),fmt='%i') antennaPairDict = {} for uniqueIndex in range(len(baselineDict.items())): allItems = baselineDict.items() for antennaPair in allItems[uniqueIndex][1]: antennaPairDict[antennaPair] = uniqueIndex pickle.dump(antennaPairDict, open(scriptDirectory + "/antennaPairUniqueBaselineIndexDict.p", 'w')) if __name__ == "__main__": from mpldatacursor import datacursor uniqueBaselines = np.asarray([uniqueBaseline[0] for uniqueBaseline in baselineDict.items()])/(1.0*precisionFactor) redundancy = np.asarray([len(uniqueBaseline[1]) for uniqueBaseline in baselineDict.items()]) uniqueBaselines = np.append(uniqueBaselines, -uniqueBaselines, axis=0) redundancy = np.append(redundancy, redundancy, axis=0) plt.figure(1) plt.clf() plt.scatter(np.asarray(positions)[:,0]/Separation,np.asarray(positions)[:,1]/Separation) plt.axis('equal') plt.figure(2) plt.clf() # plt.scatter(uniqueBaselines[:,0]/1.0/Separation, uniqueBaselines[:,1]/1.0/Separation,c=np.minimum(redundancy,100000),s=40) plt.scatter(uniqueBaselines[:,0]/1.0/1.5, uniqueBaselines[:,1]/1.0/1.5,c=np.minimum(redundancy,100000),s=40) plt.colorbar() plt.title('Baseline Redundancy') #datacursor(display='single',formatter="x={x:.4f}\ny={y:.4f}".format) plt.show() plt.axis('equal') return np.asarray(positions)