def getOneTurnMatrix(self, teapot_lattice): self.matrixArr = self.getTransportMatrixArray(teapot_lattice) final_matrix = Matrix(6, 6) final_matrix.unit() for (s0, s1, matrix) in self.matrixArr: final_matrix = matrix.mult(final_matrix) return final_matrix
def getOneTurnMatrix(self,teapot_lattice): self.matrixArr = self.getTransportMatrixArray(teapot_lattice) final_matrix = Matrix(6,6) final_matrix.unit() for (s0,s1,matrix) in self.matrixArr: final_matrix = matrix.mult(final_matrix) return final_matrix
def trackDispersionData(self, momentum, mass, disp, disp_p, direction="x"): """ Returns the tuple ([(position, disp),...],[(position,disp_p),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if (direction.lower() != "x" and direction.lower() != "y"): orbitFinalize( "Class orbit.matrix_lattice.MATRIX_Lattice, method trackDispersionData(...): direction should be x or y." ) #track dispersion eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if (direction.lower() == "y"): dir_ind = 2 track_m = Matrix(3, 3) track_m.unit() track_m.set(2, 0, 0.) track_m.set(2, 1, 0.) track_m.set(2, 2, 1.) track_v = PhaseVector(3) #kinematics coefficient calculation Etotal = math.sqrt(momentum**2 + mass**2) beta = momentum / Etotal gamma = Etotal / mass Ekin = Etotal - mass m_coeff = momentum * momentum / (mass + Ekin) track_v.set(0, disp) track_v.set(1, disp_p) track_v.set(2, 1.) position = 0. pos_arr = [] disp_arr = [] disp_p_arr = [] #put in array the initial dispersions #count = 0 pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) for matrixNode in self.getNodes(): if (isinstance(matrixNode, BaseMATRIX) == True): mt = matrixNode.getMatrix() ind0 = 0 + dir_ind ind1 = 1 + dir_ind track_m.set(0, 0, mt.get(ind0, ind0)) track_m.set(0, 1, mt.get(ind0, ind1)) track_m.set(1, 0, mt.get(ind1, ind0)) track_m.set(1, 1, mt.get(ind1, ind1)) track_m.set(0, 2, mt.get(ind0, 5) * m_coeff) track_m.set(1, 2, mt.get(ind1, 5) * m_coeff) track_v = track_m.mult(track_v) position = position + matrixNode.getLength() #only the main nodes are used, the or-cases deal with markers with zero length if (isinstance(matrixNode, BaseMATRIX) == True): pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) #pack the resulting tuple graph_disp_arr = [] graph_disp_p_arr = [] for i in range(len(pos_arr)): graph_disp_arr.append((pos_arr[i], disp_arr[i])) graph_disp_p_arr.append((pos_arr[i], disp_p_arr[i])) return (graph_disp_arr, graph_disp_p_arr)
class MATRIX_Lattice(AccLattice): """ The subclass of the AccLattice class. Shell class for the BaseMATRIX nodes collection. In the beginning the lattcie is empty. """ def __init__(self, name=None): AccLattice.__init__(self, name) self.oneTurnMatrix = Matrix(7, 7) self.oneTurnMatrix.unit() self.Matrix = Matrix(7, 7) self.Matrix.unit() def initialize(self): """ Method. Initializes the matrix lattice, child node structures, and calculates the one turn matrix. """ AccLattice.initialize(self) self.makeOneTurnMatrix() def makeOneTurnMatrix(self): """ Calculates the one turn matrix. """ self.oneTurnMatrix.unit() eps_length = 0.00001 # 10^-6 meter position = 0.0 position_old = position for matrixNode in self.getNodes(): if (isinstance(matrixNode, BaseMATRIX) == True): self.oneTurnMatrix = matrixNode.getMatrix().mult( self.oneTurnMatrix) """ if(abs(position_old-position) > eps_length): print position, self.oneTurnMatrix.get(0,6) position_old = position position = position + matrixNode.getLength() """ return self.oneTurnMatrix def makeMatrix(self, pos): """ Calculates the one turn matrix. """ self.Matrix.unit() position = 0.0 for matrixNode in self.getNodes(): if (isinstance(matrixNode, BaseMATRIX) == True and position < pos): self.Matrix = matrixNode.getMatrix().mult(self.Matrix) position = position + matrixNode.getLength() #print position, self.Matrix.get(0,6) return self.Matrix def getOneTurnMatrix(self): """ Returns the one turn matrix. """ return self.oneTurnMatrix def getRingParametersDict(self, momentum, mass): """ Returns the dictionary with different ring parametrs calculated from the one turn transport matrix. """ res_dict = {} Etotal = math.sqrt(momentum**2 + mass**2) beta = momentum / Etotal gamma = Etotal / mass Ekin = Etotal - mass res_dict["momentum [GeV/c]"] = momentum res_dict["mass [GeV]"] = mass res_dict["Ekin [GeV]"] = Ekin #longitudinal params c = 2.99792458e+8 ring_length = self.getLength() T = ring_length / (beta * c) res_dict["period [sec]"] = T res_dict["frequency [Hz]"] = 1. / T #transverse twiss parameters mt = self.oneTurnMatrix res_dict["fractional tune x"] = None res_dict["fractional tune y"] = None res_dict["alpha x"] = None res_dict["alpha y"] = None res_dict["beta x [m]"] = None res_dict["beta y [m]"] = None res_dict["gamma x [m^-1]"] = None res_dict["gamma y [m^-1]"] = None res_dict["dispersion x [m]"] = None res_dict["dispersion y [m]"] = None res_dict["dispersion prime x"] = None res_dict["dispersion prime y"] = None cos_phi_x = (mt.get(0, 0) + mt.get(1, 1)) / 2.0 cos_phi_y = (mt.get(2, 2) + mt.get(3, 3)) / 2.0 if (abs(cos_phi_x) >= 1.0 or abs(cos_phi_x) >= 1.0): return res_dict sign_x = +1.0 if (abs(mt.get(0, 1)) != 0.): sign_x = mt.get(0, 1) / abs(mt.get(0, 1)) sign_y = +1.0 if (abs(mt.get(2, 3)) != 0.): sign_y = mt.get(2, 3) / abs(mt.get(2, 3)) sin_phi_x = math.sqrt(1. - cos_phi_x * cos_phi_x) * sign_x sin_phi_y = math.sqrt(1. - cos_phi_y * cos_phi_y) * sign_y nux = math.acos(cos_phi_x) / (2 * math.pi) * sign_x nuy = math.acos(cos_phi_y) / (2 * math.pi) * sign_y res_dict["fractional tune x"] = nux res_dict["fractional tune y"] = nuy # alpha, beta, gamma beta_x = mt.get(0, 1) / sin_phi_x beta_y = mt.get(2, 3) / sin_phi_y alpha_x = (mt.get(0, 0) - mt.get(1, 1)) / (2 * sin_phi_x) alpha_y = (mt.get(2, 2) - mt.get(3, 3)) / (2 * sin_phi_y) gamma_x = -mt.get(1, 0) / sin_phi_x gamma_y = -mt.get(3, 2) / sin_phi_y # dispersion and dispersion prime m_coeff = momentum * momentum / Etotal disp_x = m_coeff * (mt.get(0, 5) * (1 - mt.get(1, 1)) + mt.get(0, 1) * mt.get(1, 5)) / (2 - mt.get(0, 0) - mt.get(1, 1)) disp_y = m_coeff * (mt.get(2, 5) * (1 - mt.get(3, 3)) + mt.get(2, 3) * mt.get(3, 5)) / (2 - mt.get(2, 2) - mt.get(3, 3)) disp_pr_x = m_coeff * (mt.get(1, 0) * mt.get(0, 5) + mt.get(1, 5) * (1 - mt.get(0, 0))) / (2 - mt.get(0, 0) - mt.get(1, 1)) disp_pr_y = m_coeff * (mt.get(3, 2) * mt.get(2, 5) + mt.get(3, 5) * (1 - mt.get(2, 2))) / (2 - mt.get(2, 2) - mt.get(3, 3)) res_dict["alpha x"] = alpha_x res_dict["alpha y"] = alpha_y res_dict["beta x [m]"] = beta_x res_dict["beta y [m]"] = beta_y res_dict["gamma x [m^-1]"] = gamma_x res_dict["gamma y [m^-1]"] = gamma_y res_dict["dispersion x [m]"] = disp_x res_dict["dispersion y [m]"] = disp_y res_dict["dispersion prime x"] = disp_pr_x res_dict["dispersion prime y"] = disp_pr_y #more longitudinal params termx = mt.get(4, 0) * disp_x termxp = mt.get(4, 1) * disp_pr_x termy = mt.get(4, 2) * disp_y termyp = mt.get(4, 3) * disp_pr_y termdE = mt.get(4, 5) * beta * beta * Etotal eta_ring = -(termx + termxp + termy + termyp + termdE)\ / ring_length res_dict["eta"] = eta_ring alpha_p = eta_ring + 1. / (gamma * gamma) sqarg = alpha_p if (alpha_p < 0.): sqarg = -alpha_p gamma_trans = 1.0 / math.sqrt(sqarg) res_dict["gamma transition"] = gamma_trans res_dict["transition energy [GeV]"] = (gamma_trans - 1.0) * mass res_dict["momentum compaction"] = alpha_p return res_dict def getRingTwissDataX(self, momentum, mass): """ Returns the tuple ([(position, phase advanceX)/2/pi,...],[(position, alphaX),...],[(position,betaX),...] ). """ res_dict = self.getRingParametersDict(momentum, mass) alpha_x = res_dict["alpha x"] beta_x = res_dict["beta x [m]"] return self.trackTwissData(alpha_x, beta_x, "x") def getRingTwissDataY(self, momentum, mass): """ Returns the tuple ([(position, phase advanceY/2/pi),...],[(position, alphaY),...],[(position,betaY),...] ). """ res_dict = self.getRingParametersDict(momentum, mass) alpha_y = res_dict["alpha y"] beta_y = res_dict["beta y [m]"] return self.trackTwissData(alpha_y, beta_y, "y") def trackTwissData(self, alpha, beta, direction="x"): """ Returns the tuple ([(position, phase advance/2/pi),...], [(position, alpha),...],[(position,beta),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if (direction.lower() != "x" and direction.lower() != "y"): orbitFinalize( "Class orbit.matrix_lattice.MATRIX_Lattice, method trackTwissData(...): direction should be x or y." ) #track twiss eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if (direction.lower() == "y"): dir_ind = 2 gamma = (1.0 + alpha * alpha) / beta track_m = Matrix(3, 3) track_m.unit() track_v = PhaseVector(3) track_v.set(0, alpha) track_v.set(1, beta) track_v.set(2, gamma) position = 0. pos_arr = [] alpha_arr = [] beta_arr = [] #phi is for tune accumulation phi = 0. #phase advance mu_arr = [] #count = 0 pos_arr.append(position) mu_arr.append(phi) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) for matrixNode in self.getNodes(): mt = matrixNode.getMatrix() ind0 = 0 + dir_ind ind1 = 1 + dir_ind track_m.set( 0, 0, mt.get(ind0, ind0) * mt.get(ind1, ind1) + mt.get(ind0, ind1) * mt.get(ind1, ind0)) track_m.set(0, 1, -mt.get(ind0, ind0) * mt.get(ind1, ind0)) track_m.set(0, 2, -mt.get(ind0, ind1) * mt.get(ind1, ind1)) track_m.set(1, 0, -2 * mt.get(ind0, ind0) * mt.get(ind0, ind1)) track_m.set(1, 1, mt.get(ind0, ind0) * mt.get(ind0, ind0)) track_m.set(1, 2, mt.get(ind0, ind1) * mt.get(ind0, ind1)) track_m.set(2, 0, -2 * mt.get(ind1, ind0) * mt.get(ind1, ind1)) track_m.set(2, 1, mt.get(ind1, ind0) * mt.get(ind1, ind0)) track_m.set(2, 2, mt.get(ind1, ind1) * mt.get(ind1, ind1)) alpha_0 = track_v.get(0) beta_0 = track_v.get(1) delta_phi = math.atan( mt.get(ind0, ind1) / (beta_0 * mt.get(ind0, ind0) - alpha_0 * mt.get(ind0, ind1))) phi = phi + delta_phi track_v = track_m.mult(track_v) position = position + matrixNode.getLength() if (isinstance(matrixNode, BaseMATRIX) == True): #only the main nodes are used, the or-cases deal with markers with zero length #print position, matrixNode.getParam("matrix_parent_node_active_index") == 1 #print position, matrixNode.getName(), track_v.get(1) if matrixNode.getLength() > 0: #print position, matrixNode.getName(), track_v.get(1) pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi / (2 * math.pi)) #count = count + 1 #pack the resulting tuple tune = phi / (2 * math.pi) graph_alpha_arr = [] graph_beta_arr = [] graph_mu_arr = [] #print count, len(pos_arr) for i in range(len(pos_arr)): graph_mu_arr.append((pos_arr[i], mu_arr[i])) graph_alpha_arr.append((pos_arr[i], alpha_arr[i])) graph_beta_arr.append((pos_arr[i], beta_arr[i])) return (graph_mu_arr, graph_alpha_arr, graph_beta_arr) def getRingDispersionDataX(self, momentum, mass): """ Returns the tuple ([(position, dispX),...],[(position,disp_pX),...] ). """ res_dict = self.getRingParametersDict(momentum, mass) disp = res_dict["dispersion x [m]"] disp_p = res_dict["dispersion prime x"] return self.trackDispersionData(momentum, mass, disp, disp_p, "x") def getRingDispersionDataY(self, momentum, mass): """ Returns the tuple ([(position, dispY),...],[(position,disp_pY),...] ). """ res_dict = self.getRingParametersDict(momentum, mass) disp = res_dict["dispersion y [m]"] disp_p = res_dict["dispersion prime y"] return self.trackDispersionData(momentum, mass, disp, disp_p, "y") def trackDispersionData(self, momentum, mass, disp, disp_p, direction="x"): """ Returns the tuple ([(position, disp),...],[(position,disp_p),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if (direction.lower() != "x" and direction.lower() != "y"): orbitFinalize( "Class orbit.matrix_lattice.MATRIX_Lattice, method trackDispersionData(...): direction should be x or y." ) #track dispersion eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if (direction.lower() == "y"): dir_ind = 2 track_m = Matrix(3, 3) track_m.unit() track_m.set(2, 0, 0.) track_m.set(2, 1, 0.) track_m.set(2, 2, 1.) track_v = PhaseVector(3) #kinematics coefficient calculation Etotal = math.sqrt(momentum**2 + mass**2) beta = momentum / Etotal gamma = Etotal / mass Ekin = Etotal - mass m_coeff = momentum * momentum / (mass + Ekin) track_v.set(0, disp) track_v.set(1, disp_p) track_v.set(2, 1.) position = 0. pos_arr = [] disp_arr = [] disp_p_arr = [] #put in array the initial dispersions #count = 0 pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) for matrixNode in self.getNodes(): if (isinstance(matrixNode, BaseMATRIX) == True): mt = matrixNode.getMatrix() ind0 = 0 + dir_ind ind1 = 1 + dir_ind track_m.set(0, 0, mt.get(ind0, ind0)) track_m.set(0, 1, mt.get(ind0, ind1)) track_m.set(1, 0, mt.get(ind1, ind0)) track_m.set(1, 1, mt.get(ind1, ind1)) track_m.set(0, 2, mt.get(ind0, 5) * m_coeff) track_m.set(1, 2, mt.get(ind1, 5) * m_coeff) track_v = track_m.mult(track_v) position = position + matrixNode.getLength() #only the main nodes are used, the or-cases deal with markers with zero length if (isinstance(matrixNode, BaseMATRIX) == True): pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) #pack the resulting tuple graph_disp_arr = [] graph_disp_p_arr = [] for i in range(len(pos_arr)): graph_disp_arr.append((pos_arr[i], disp_arr[i])) graph_disp_p_arr.append((pos_arr[i], disp_p_arr[i])) return (graph_disp_arr, graph_disp_p_arr) def getRingOrbit(self, z0): """ Returns the tuple ([(position, x] ). """ return self.trackOrbit(z0) def trackOrbit(self, z0): """ Returns the tuple ([(position, x),...], [(position, y),...] ). The tracking starts from the values specified as the initial parameters. z0 fulfill: z0 = Mz0 with M as one turn matrix """ eps_length = 0.00001 # 10^-6 meter pos_arr = [] orbitX_arr = [] orbitY_arr = [] orbitXP_arr = [] orbitYP_arr = [] position = 0. pos_arr.append(position) track_o = Matrix(6, 6) track_ov = PhaseVector(6) track_ov.set(0, z0[0]) track_ov.set(1, z0[1]) track_ov.set(2, z0[2]) track_ov.set(3, z0[3]) track_ov.set(4, z0[4]) track_ov.set(5, z0[5]) orbitX_arr.append(track_ov.get(0)) orbitY_arr.append(track_ov.get(2)) orbitXP_arr.append(track_ov.get(1)) orbitYP_arr.append(track_ov.get(3)) position_old = position for matrixNode in self.getNodes(): if (isinstance(matrixNode, BaseMATRIX) == True): if (abs(position_old - position) > eps_length): pos_arr.append(position) orbitX_arr.append(track_ov.get(0)) orbitY_arr.append(track_ov.get(2)) orbitXP_arr.append(track_ov.get(1)) orbitYP_arr.append(track_ov.get(3)) mt = matrixNode.getMatrix() for i in range(6): for j in range(6): track_o.set(i, j, mt.get(i, j)) track_ov = track_o.mult(track_ov) for i in range(6): tmp = track_ov.get(i) track_ov.set(i, tmp + mt.get(i, 6)) position_old = position position = position + matrixNode.getLength() pos_arr.append(position) orbitX_arr.append(track_ov.get(0)) orbitY_arr.append(track_ov.get(2)) orbitXP_arr.append(track_ov.get(1)) orbitYP_arr.append(track_ov.get(3)) #pack the resulting tuple graph_orbitX_arr = [] graph_orbitY_arr = [] for i in range(len(pos_arr)): graph_orbitX_arr.append( (pos_arr[i], orbitX_arr[i], orbitXP_arr[i])) graph_orbitY_arr.append( (pos_arr[i], orbitY_arr[i], orbitYP_arr[i])) return (graph_orbitX_arr, graph_orbitY_arr) def getSubLattice( self, index_start=-1, index_stop=-1, ): """ It returns the new MATRIX_Lattice with children with indexes between index_start and index_stop inclusive """ return self._getSubLattice(MATRIX_Lattice(), index_start, index_stop) def trackBunch(self, bunch, paramsDict={}, actionContainer=None): """ It tracks the bunch through the lattice. """ if (actionContainer == None): actionContainer = AccActionsContainer("Bunch Tracking") paramsDict["bunch"] = bunch def track(paramsDict): node = paramsDict["node"] node.track(paramsDict) actionContainer.addAction(track, AccActionsContainer.BODY) self.trackActions(actionContainer, paramsDict) actionContainer.removeAction(track, AccActionsContainer.BODY)
def trackTwissData(self, alpha, beta, direction="x"): """ Returns the tuple ([(position, phase advance/2/pi),...], [(position, alpha),...],[(position,beta),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if (direction.lower() != "x" and direction.lower() != "y"): orbitFinalize( "Class orbit.matrix_lattice.MATRIX_Lattice, method trackTwissData(...): direction should be x or y." ) #track twiss eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if (direction.lower() == "y"): dir_ind = 2 gamma = (1.0 + alpha * alpha) / beta track_m = Matrix(3, 3) track_m.unit() track_v = PhaseVector(3) track_v.set(0, alpha) track_v.set(1, beta) track_v.set(2, gamma) position = 0. pos_arr = [] alpha_arr = [] beta_arr = [] #phi is for tune accumulation phi = 0. #phase advance mu_arr = [] #count = 0 pos_arr.append(position) mu_arr.append(phi) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) for matrixNode in self.getNodes(): mt = matrixNode.getMatrix() ind0 = 0 + dir_ind ind1 = 1 + dir_ind track_m.set( 0, 0, mt.get(ind0, ind0) * mt.get(ind1, ind1) + mt.get(ind0, ind1) * mt.get(ind1, ind0)) track_m.set(0, 1, -mt.get(ind0, ind0) * mt.get(ind1, ind0)) track_m.set(0, 2, -mt.get(ind0, ind1) * mt.get(ind1, ind1)) track_m.set(1, 0, -2 * mt.get(ind0, ind0) * mt.get(ind0, ind1)) track_m.set(1, 1, mt.get(ind0, ind0) * mt.get(ind0, ind0)) track_m.set(1, 2, mt.get(ind0, ind1) * mt.get(ind0, ind1)) track_m.set(2, 0, -2 * mt.get(ind1, ind0) * mt.get(ind1, ind1)) track_m.set(2, 1, mt.get(ind1, ind0) * mt.get(ind1, ind0)) track_m.set(2, 2, mt.get(ind1, ind1) * mt.get(ind1, ind1)) alpha_0 = track_v.get(0) beta_0 = track_v.get(1) delta_phi = math.atan( mt.get(ind0, ind1) / (beta_0 * mt.get(ind0, ind0) - alpha_0 * mt.get(ind0, ind1))) phi = phi + delta_phi track_v = track_m.mult(track_v) position = position + matrixNode.getLength() if (isinstance(matrixNode, BaseMATRIX) == True): #only the main nodes are used, the or-cases deal with markers with zero length #print position, matrixNode.getParam("matrix_parent_node_active_index") == 1 #print position, matrixNode.getName(), track_v.get(1) if matrixNode.getLength() > 0: #print position, matrixNode.getName(), track_v.get(1) pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi / (2 * math.pi)) #count = count + 1 #pack the resulting tuple tune = phi / (2 * math.pi) graph_alpha_arr = [] graph_beta_arr = [] graph_mu_arr = [] #print count, len(pos_arr) for i in range(len(pos_arr)): graph_mu_arr.append((pos_arr[i], mu_arr[i])) graph_alpha_arr.append((pos_arr[i], alpha_arr[i])) graph_beta_arr.append((pos_arr[i], beta_arr[i])) return (graph_mu_arr, graph_alpha_arr, graph_beta_arr)
#=====trackBunch method for the whole lattice approach============ print "============= Matrix for the whole lattice ==========" transp_matrix = Matrix(6,6) matrixGenerator = MatrixGenerator() matrixGenerator.initBunch(matrixTracker.b) teapot_latt.trackBunch(matrixTracker.b) matrixGenerator.calculateMatrix(matrixTracker.b,transp_matrix) transormToMAD(transp_matrix,momentum,beta) printM(transp_matrix) #=====trackBunch method for each TEAPOT element approach============ print "Total number of TEAPOT Base Nodes=",len(teapot_latt.getNodes()) printNames = [] res_matrix = Matrix(6,6) res_matrix.unit() n_max = len(teapot_latt.getNodes()) #n_max = 74 length = 0. for i in range(n_max): node = teapot_latt.getNodes()[i] print "i=",i," name =",node.getName()," L=",length m = Matrix(6,6) matrixGenerator.initBunch(matrixTracker.b) node.trackBunch(matrixTracker.b) matrixGenerator.calculateMatrix(matrixTracker.b,m) #m_prt0 = m.copy() #transormToMAD(m_prt0,momentum,beta) #printM(m_prt0) res_matrix = m.mult(res_matrix) length = length + node.getLength()
print "Start." n = Nll() k = .01 b = Bunch() b.addParticle(1., 2., 3., 4., 5., 6.) b.dumpBunch() m = Matrix(6, 6) m.unit() m.set(0, 0, math.cos(k)) m.set(0, 1, math.sin(k)) m.set(1, 0, -math.sin(k)) m.set(1, 1, math.cos(k)) m.set(2, 2, math.cos(k)) m.set(2, 3, math.sin(k)) m.set(3, 2, -math.sin(k)) m.set(3, 3, math.cos(k)) printM(m) for i in range(20000): m.track(b) n.TRACK_EXT(b) plotx.append([b.x(0), b.y(0)])
"QH04")][1] qv01_pos_start = accLattice.getNodePositionsDict()[accLattice.getNodeForName( "QV01")][0] qh02_pos_start = accLattice.getNodePositionsDict()[accLattice.getNodeForName( "QH02")][0] qv03_pos_start = accLattice.getNodePositionsDict()[accLattice.getNodeForName( "QV03")][0] qh04_pos_start = accLattice.getNodePositionsDict()[accLattice.getNodeForName( "QH04")][0] qv01_pos_center = (qv01_pos_start + qv01_pos_end) / 2.0 #---- qv01_3d coordinate transformation from the lattice system transfCoordsMatrix = Matrix(4, 4) transfCoordsMatrix.unit() dist_from_qv01_center = 0. transfCoordsMatrix.set(2, 3, -dist_from_qv01_center) qv01_3d.transormfMatrix(transfCoordsMatrix) #---- qh02_3d coordinate transformation from the lattice system transfCoordsMatrix = Matrix(4, 4) transfCoordsMatrix.unit() dist_from_qv01_center = qh02_pos_end - qv01_pos_end transfCoordsMatrix.set(2, 3, -dist_from_qv01_center) qh02_3d.transormfMatrix(transfCoordsMatrix) #---- qv03_3d coordinate transformation from the lattice system transfCoordsMatrix = Matrix(4, 4) transfCoordsMatrix.unit() dist_from_qv01_center = qv03_pos_end - qv01_pos_end
class LinacTrMatrixGenNode(MarkerLinacNode): """ Linac Accelerator Nodes for Transport Matrices generation. These nodes are using thethe Initial Coordinates particles Attrubutes. Each node (if it is not the first one) calculates the transport matrix between the previous node and itself. The matrix is a 7x7 matrix that transforms the initial particles coordinates to the final ones that are in the bu """ def __init__(self, trMatricesController, name="TrMatrixGen"): if (name == "TrMatrixGen"): name += name + ":" + str(trMatricesController.getCount()) MarkerLinacNode.__init__(self, name) self.trMatricesController = trMatricesController self.trMtrxNode_ind = trMatricesController.getCount() self.use_twiss_weight_x = 0 self.use_twiss_weight_y = 0 self.use_twiss_weight_z = 0 self.relativistic_beta = 0. self.relativistic_gamma = 0. #-------------------------------------- self.trMtrx = Matrix(7, 7) #-------------------------------------- self.trMatricesController.addNode(self) def setInternalIndex(self, ind): """ Sets the index of the TrMatrxGenNode in the controller """ self.trMtrxNode_ind = ind def getTrMatricesController(self): """ Returns the LinacTrMatricesContrioller that keeps the references to the TrMatrxGenNodes. """ return self.trMatricesController def getTwissWeightUse(self): """ Returns (use_x,use,use_z) tuple where use_{} == 1 means the Twiss weights will be used. """ res_arr = [True, True, True] if (self.use_twiss_weight_x == 0): res_arr[0] = False if (self.use_twiss_weight_y == 0): res_arr[1] = False if (self.use_twiss_weight_z == 0): res_arr[2] = False return tuple(res_arr) def setTwissWeightUse(self, use_twiss_weight_x, use_twiss_weight_y, use_twiss_weight_z): """ Sets (use_x,use,use_z) tuple where use_{} == 1 means the Twiss weights will be used. """ self.use_twiss_weight_x = 0 self.use_twiss_weight_y = 0 self.use_twiss_weight_z = 0 if (use_twiss_weight_x == True): self.use_twiss_weight_x = 1 if (use_twiss_weight_y == True): self.use_twiss_weight_y = 1 if (use_twiss_weight_z == True): self.use_twiss_weight_z = 1 def track(self, paramsDict): bunch = paramsDict["bunch"] self.relativistic_beta = bunch.getSyncParticle().beta() self.relativistic_gamma = bunch.getSyncParticle().gamma() if (self.trMtrxNode_ind == 0): self.trMtrx.unit() copyCoordsToInitCoordsAttr(bunch) else: transportMtrxFromInitCoords(bunch, self.trMtrx, self.use_twiss_weight_x, self.use_twiss_weight_y, self.use_twiss_weight_z) def trackDesign(self, paramsDict): """ This method does nothing for the aperture case. """ pass def getBeta(self): """ Returns relativistic beta at this node. """ return self.relativistic_beta def getGamma(self): """ Returns relativistic gamma at this node. """ return self.relativistic_gamma def getTransportMatrix(self): """ Return transport matrix (7x7). """ return self.trMtrx def getDetXYZ(self, trMtrx=None): """ Returns the determinants of the transformations in (x,y,z) directions. """ if (trMtrx == None): trMtrx = self.trMtrx det_x = trMtrx.get(0, 0) * trMtrx.get(1, 1) - trMtrx.get( 1, 0) * trMtrx.get(0, 1) det_y = trMtrx.get(0 + 2, 0 + 2) * trMtrx.get( 1 + 2, 1 + 2) - trMtrx.get(1 + 2, 0 + 2) * trMtrx.get( 0 + 2, 1 + 2) det_z = trMtrx.get(0 + 4, 0 + 4) * trMtrx.get( 1 + 4, 1 + 4) - trMtrx.get(1 + 4, 0 + 4) * trMtrx.get( 0 + 4, 1 + 4) return (det_x, det_y, det_z) def getNormDetXYZ(self): """ Returns the normalized determinants of the transformations in (x,y,z) directions. """ (node0, node1) = self.getTwoNodes() beta_in = node0.getBeta() beta_out = node1.getBeta() gamma_in = node0.getGamma() gamma_out = node1.getGamma() gb_in = beta_in * gamma_in gb_out = beta_out * gamma_out (det_x, det_y, det_z) = self.getDetXYZ(self.trMtrx) return ((gb_out / gb_in) * det_x, (gb_out / gb_in) * det_y, (beta_in / beta_out) * det_z) def getTwoNodes(self): """ Returns two LinacTrMatrixGenNode nodes. The transport matrix is between these nodes. """ node0 = self if (self.trMtrxNode_ind > 0): node0 = self.trMatricesController.getNode(0) node1 = self.trMatricesController.getNode(self.trMtrxNode_ind) return (node0, node1) def printMatrix(self): """ Print the matrix. """ name0 = "None" if (self.trMtrxNode_ind > 0): name0 = self.trMatricesController.getNode(self.trMtrxNode_ind - 1).getName() name1 = self.trMatricesController.getNode( self.trMtrxNode_ind).getName() print "----Transport matrix--- from name0=", name0, " to name1=", name1 m = self.trMtrx for i in xrange(m.size()[0]): for j in xrange(m.size()[1]): print("m(" + str(i) + "," + str(j) + ")=" + "%12.5g" % m.get(i, j) + " "), print ""
for i in range(6): res_arr = s_arr[i+2].split() for j in range(6): matrix.set(i,j, float(res_arr[j])) #printM(matrix) lattice_arr.append((name,matrix)) for it in range(stack_size-1): s_arr[it] = s_arr[it+1] s_arr[stack_size-1] = s #print "debug s=",s s = inF.readline() inF.close() mad_matrix = Matrix(6,6) mad_matrix.unit() n_max = len(lattice_arr) #n_max = 74 for i in range(n_max): (name,matrix) = lattice_arr[i] #print "i=",i," name =",name #printM(mad_matrix) mad_matrix = matrix.mult(mad_matrix) #printM(matrix) #printM(mad_matrix) print "=========One turn MAD matrix======== MAD n_elements=",n_max printM(mad_matrix) print "Stop."
#=====trackBunch method for the whole lattice approach============ print "============= Matrix for the whole lattice ==========" transp_matrix = Matrix(6, 6) matrixGenerator = MatrixGenerator() matrixGenerator.initBunch(matrixTracker.b) teapot_latt.trackBunch(matrixTracker.b) matrixGenerator.calculateMatrix(matrixTracker.b, transp_matrix) transormToMAD(transp_matrix, momentum, beta) printM(transp_matrix) #=====trackBunch method for each TEAPOT element approach============ print "Total number of TEAPOT Base Nodes=", len(teapot_latt.getNodes()) printNames = [] res_matrix = Matrix(6, 6) res_matrix.unit() n_max = len(teapot_latt.getNodes()) #n_max = 74 length = 0. for i in range(n_max): node = teapot_latt.getNodes()[i] print "i=", i, " name =", node.getName(), " L=", length m = Matrix(6, 6) matrixGenerator.initBunch(matrixTracker.b) node.trackBunch(matrixTracker.b) matrixGenerator.calculateMatrix(matrixTracker.b, m) #m_prt0 = m.copy() #transormToMAD(m_prt0,momentum,beta) #printM(m_prt0) res_matrix = m.mult(res_matrix) length = length + node.getLength()
class MATRIX_Lattice(AccLattice): """ The subclass of the AccLattice class. Shell class for the BaseMATRIX nodes collection. In the beginning the lattcie is empty. """ def __init__(self, name = None): AccLattice.__init__(self,name) self.oneTurmMatrix = Matrix(7,7) self.oneTurmMatrix.unit() def initialize(self): """ Method. Initializes the matrix lattice, child node structures, and calculates the one turn matrix. """ AccLattice.initialize(self) self.makeOneTurnMatrix() def makeOneTurnMatrix(self): """ Calculates the one turn matrix. """ self.oneTurmMatrix.unit() for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): self.oneTurmMatrix = matrixNode.getMatrix().mult(self.oneTurmMatrix) return self.oneTurmMatrix def getOneTurnMatrix(self): """ Returns the one turn matrix. """ return self.oneTurmMatrix def getRingParametersDict(self,momentum,mass): """ Returns the dictionary with different ring parametrs calculated from the one turn transport matrix. """ res_dict = {} Etotal = math.sqrt(momentum**2 + mass**2) beta = momentum/Etotal gamma = Etotal/mass Ekin = Etotal - mass res_dict["momentum [GeV/c]"] = momentum res_dict["mass [GeV]"] = mass res_dict["Ekin [GeV]"] = Ekin #longitudinal params c = 2.99792458e+8 ring_length = self.getLength() T = ring_length/(beta*c) res_dict["period [sec]"] = T res_dict["frequency [Hz]"] = 1./T #transverse twiss parameters mt = self.oneTurmMatrix res_dict["fractional tune x"] = None res_dict["fractional tune y"] = None res_dict["alpha x"] = None res_dict["alpha y"] = None res_dict["beta x [m]"] = None res_dict["beta y [m]"] = None res_dict["gamma x [m^-1]"] = None res_dict["gamma y [m^-1]"] = None res_dict["dispersion x [m]"] = None res_dict["dispersion y [m]"] = None res_dict["dispersion prime x"] = None res_dict["dispersion prime y"] = None cos_phi_x = (mt.get(0,0)+mt.get(1,1))/2.0 cos_phi_y = (mt.get(2,2)+mt.get(3,3))/2.0 if(abs(cos_phi_x) >= 1.0 or abs(cos_phi_x) >= 1.0): return res_dict sign_x = +1.0 if(abs(mt.get(0,1)) != 0.): sign_x = mt.get(0,1)/abs(mt.get(0,1)) sign_y = +1.0 if(abs(mt.get(2,3)) != 0.): sign_y = mt.get(2,3)/abs(mt.get(2,3)) sin_phi_x = math.sqrt(1. - cos_phi_x*cos_phi_x)*sign_x sin_phi_y = math.sqrt(1. - cos_phi_y*cos_phi_y)*sign_y nux = math.acos(cos_phi_x)/(2*math.pi)*sign_x nuy = math.acos(cos_phi_y)/(2*math.pi) *sign_y res_dict["fractional tune x"] = nux res_dict["fractional tune y"] = nuy # alpha, beta, gamma beta_x = mt.get(0,1)/sin_phi_x beta_y = mt.get(2,3)/sin_phi_y alpha_x = (mt.get(0,0) - mt.get(1,1))/(2*sin_phi_x) alpha_y = (mt.get(2,2) - mt.get(3,3))/(2*sin_phi_y) gamma_x = -mt.get(1,0)/sin_phi_x gamma_y = -mt.get(3,2)/sin_phi_y # dispersion and dispersion prime m_coeff = momentum * momentum / Etotal disp_x = m_coeff*(mt.get(0,5)*(1-mt.get(1,1))+mt.get(0,1)*mt.get(1,5))/(2-mt.get(0,0)-mt.get(1,1)) disp_y = m_coeff*(mt.get(2,5)*(1-mt.get(3,3))+mt.get(2,3)*mt.get(3,5))/(2-mt.get(2,2)-mt.get(3,3)) disp_pr_x = m_coeff*(mt.get(1,0)*mt.get(0,5)+mt.get(1,5)*(1-mt.get(0,0)))/(2-mt.get(0,0)-mt.get(1,1)) disp_pr_y = m_coeff*(mt.get(3,2)*mt.get(2,5)+mt.get(3,5)*(1-mt.get(2,2)))/(2-mt.get(2,2)-mt.get(3,3)) res_dict["alpha x"] = alpha_x res_dict["alpha y"] = alpha_y res_dict["beta x [m]"] = beta_x res_dict["beta y [m]"] = beta_y res_dict["gamma x [m^-1]"] = gamma_x res_dict["gamma y [m^-1]"] = gamma_y res_dict["dispersion x [m]"] = disp_x res_dict["dispersion y [m]"] = disp_y res_dict["dispersion prime x"] = disp_pr_x res_dict["dispersion prime y"] = disp_pr_y #more longitudinal params termx = mt.get(4,0) * disp_x termxp = mt.get(4,1) * disp_pr_x termy = mt.get(4,2) * disp_y termyp = mt.get(4,3) * disp_pr_y termdE = mt.get(4,5) * beta * beta * Etotal eta_ring = -(termx + termxp + termy + termyp + termdE)\ / ring_length res_dict["eta"] = eta_ring alpha_p = eta_ring + 1. / (gamma * gamma) sqarg = alpha_p if(alpha_p < 0.): sqarg = -alpha_p gamma_trans = 1.0 / math.sqrt(sqarg) res_dict["gamma transition"] = gamma_trans res_dict["transition energy [GeV]"] = (gamma_trans - 1.0)*mass res_dict["momentum compaction"] = alpha_p return res_dict def getRingTwissDataX(self,momentum,mass): """ Returns the tuple ([(position, phase advanceX)/2/pi,...],[(position, alphaX),...],[(position,betaX),...] ). """ res_dict = self.getRingParametersDict(momentum,mass) alpha_x = res_dict["alpha x"] beta_x = res_dict["beta x [m]"] return self.trackTwissData(alpha_x,beta_x,"x") def getRingTwissDataY(self,momentum,mass): """ Returns the tuple ([(position, phase advanceY/2/pi),...],[(position, alphaY),...],[(position,betaY),...] ). """ res_dict = self.getRingParametersDict(momentum,mass) alpha_y = res_dict["alpha y"] beta_y = res_dict["beta y [m]"] return self.trackTwissData(alpha_y,beta_y,"y") def trackTwissData(self, alpha, beta, direction = "x"): """ Returns the tuple ([(position, phase advance/2/pi),...], [(position, alpha),...],[(position,beta),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if(direction.lower() != "x" and direction.lower() != "y"): orbitFinalize("Class orbit.matrix_lattice.MATRIX_Lattice, method trackTwissData(...): direction should be x or y.") #track twiss eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if(direction.lower() == "y"): dir_ind = 2 gamma = (1.0+alpha*alpha)/beta track_m = Matrix(3,3) track_m.unit() track_v = PhaseVector(3) track_v.set(0,alpha) track_v.set(1,beta) track_v.set(2,gamma) position = 0. pos_arr = [] alpha_arr = [] beta_arr = [] #phi is for tune accumulation phi = 0. #phase advance mu_arr = [] #put in array the initial twiss pos_arr.append(position) mu_arr.append(phi) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) position_old = position beta_old = beta #count = 0 for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): beta = track_v.get(1) if(abs(position_old-position) > eps_length or abs(beta_old - beta) > eps_length): pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi/(2*math.pi)) mt = matrixNode.getMatrix() ind0 = 0+dir_ind ind1 = 1+dir_ind track_m.set(0,0,mt.get(ind0,ind0)*mt.get(ind1,ind1)+mt.get(ind0,ind1)*mt.get(ind1,ind0)) track_m.set(0,1,-mt.get(ind0,ind0)*mt.get(ind1,ind0)) track_m.set(0,2,-mt.get(ind0,ind1)*mt.get(ind1,ind1)) track_m.set(1,0,-2*mt.get(ind0,ind0)*mt.get(ind0,ind1)) track_m.set(1,1,mt.get(ind0,ind0)*mt.get(ind0,ind0)) track_m.set(1,2,mt.get(ind0,ind1)*mt.get(ind0,ind1)) track_m.set(2,0,-2*mt.get(ind1,ind0)*mt.get(ind1,ind1)) track_m.set(2,1,mt.get(ind1,ind0)*mt.get(ind1,ind0)) track_m.set(2,2,mt.get(ind1,ind1)*mt.get(ind1,ind1)) alpha_0 = track_v.get(0) beta_0 = track_v.get(1) delta_phi = math.atan( mt.get(ind0,ind1)/( beta_0*mt.get(ind0,ind0) - alpha_0*mt.get(ind0,ind1))) phi = phi + delta_phi track_v = track_m.mult(track_v) position_old = position beta_old = beta_0 position = position + matrixNode.getLength() #count = count + 1 pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi/(2*math.pi)) #pack the resulting tuple tune = phi/(2*math.pi) graph_alpha_arr = [] graph_beta_arr = [] graph_mu_arr = [] for i in range(len(pos_arr)): graph_mu_arr.append((pos_arr[i], mu_arr[i])) graph_alpha_arr.append((pos_arr[i],alpha_arr[i])) graph_beta_arr.append((pos_arr[i],beta_arr[i])) return (graph_mu_arr,graph_alpha_arr,graph_beta_arr) def getRingDispersionDataX(self,momentum,mass): """ Returns the tuple ([(position, dispX),...],[(position,disp_pX),...] ). """ res_dict = self.getRingParametersDict(momentum,mass) disp = res_dict["dispersion x [m]"] disp_p = res_dict["dispersion prime x"] return self.trackDispersionData(momentum,mass,disp, disp_p,"x") def getRingDispersionDataY(self,momentum,mass): """ Returns the tuple ([(position, dispY),...],[(position,disp_pY),...] ). """ res_dict = self.getRingParametersDict(momentum,mass) disp = res_dict["dispersion y [m]"] disp_p = res_dict["dispersion prime y"] return self.trackDispersionData(momentum,mass,disp, disp_p,"y") def trackDispersionData(self,momentum,mass, disp, disp_p, direction = "x"): """ Returns the tuple ([(position, disp),...],[(position,disp_p),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if(direction.lower() != "x" and direction.lower() != "y"): orbitFinalize("Class orbit.matrix_lattice.MATRIX_Lattice, method trackDispersionData(...): direction should be x or y.") #track dispersion eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if(direction.lower() == "y"): dir_ind = 2 track_m = Matrix(3,3) track_m.unit() track_m.set(2,0,0.) track_m.set(2,1,0.) track_m.set(2,2,1.) track_v = PhaseVector(3) #kinematics coefficient calculation Etotal = math.sqrt(momentum**2 + mass**2) beta = momentum/Etotal gamma = Etotal/mass Ekin = Etotal - mass m_coeff = momentum*momentum/(mass + Ekin) track_v.set(0,disp) track_v.set(1,disp_p) track_v.set(2,1.) position = 0. pos_arr = [] disp_arr = [] disp_p_arr = [] #put in array the initial dispersions pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) position_old = position disp_old = disp #count = 0 for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): disp = track_v.get(0) if(abs(position_old-position) > eps_length or abs(disp_old - disp) > eps_length): pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) disp_old = disp position_old = position mt = matrixNode.getMatrix() ind0 = 0+dir_ind ind1 = 1+dir_ind track_m.set(0,0,mt.get(ind0,ind0)) track_m.set(0,1,mt.get(ind0,ind1)) track_m.set(1,0,mt.get(ind1,ind0)) track_m.set(1,1,mt.get(ind1,ind1)) track_m.set(0,2,mt.get(ind0,5)*m_coeff) track_m.set(1,2,mt.get(ind1,5)*m_coeff) track_v = track_m.mult(track_v) position = position + matrixNode.getLength() pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) #pack the resulting tuple graph_disp_arr = [] graph_disp_p_arr = [] for i in range(len(pos_arr)): graph_disp_arr.append((pos_arr[i],disp_arr[i])) graph_disp_p_arr.append((pos_arr[i],disp_p_arr[i])) return (graph_disp_arr,graph_disp_p_arr) def getSubLattice(self, index_start = -1, index_stop = -1,): """ It returns the new MATRIX_Lattice with children with indexes between index_start and index_stop inclusive """ return self._getSubLattice(MATRIX_Lattice(),index_start,index_stop) def trackBunch(self, bunch, paramsDict = {}, actionContainer = None): """ It tracks the bunch through the lattice. """ if(actionContainer == None): actionContainer = AccActionsContainer("Bunch Tracking") paramsDict["bunch"] = bunch def track(paramsDict): node = paramsDict["node"] node.track(paramsDict) actionContainer.addAction(track, AccActionsContainer.BODY) self.trackActions(actionContainer,paramsDict) actionContainer.removeAction(track, AccActionsContainer.BODY)
def trackDispersionData(self,momentum,mass, disp, disp_p, direction = "x"): """ Returns the tuple ([(position, disp),...],[(position,disp_p),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if(direction.lower() != "x" and direction.lower() != "y"): orbitFinalize("Class orbit.matrix_lattice.MATRIX_Lattice, method trackDispersionData(...): direction should be x or y.") #track dispersion eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if(direction.lower() == "y"): dir_ind = 2 track_m = Matrix(3,3) track_m.unit() track_m.set(2,0,0.) track_m.set(2,1,0.) track_m.set(2,2,1.) track_v = PhaseVector(3) #kinematics coefficient calculation Etotal = math.sqrt(momentum**2 + mass**2) beta = momentum/Etotal gamma = Etotal/mass Ekin = Etotal - mass m_coeff = momentum*momentum/(mass + Ekin) track_v.set(0,disp) track_v.set(1,disp_p) track_v.set(2,1.) position = 0. pos_arr = [] disp_arr = [] disp_p_arr = [] #put in array the initial dispersions pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) position_old = position disp_old = disp #count = 0 for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): disp = track_v.get(0) if(abs(position_old-position) > eps_length or abs(disp_old - disp) > eps_length): pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) disp_old = disp position_old = position mt = matrixNode.getMatrix() ind0 = 0+dir_ind ind1 = 1+dir_ind track_m.set(0,0,mt.get(ind0,ind0)) track_m.set(0,1,mt.get(ind0,ind1)) track_m.set(1,0,mt.get(ind1,ind0)) track_m.set(1,1,mt.get(ind1,ind1)) track_m.set(0,2,mt.get(ind0,5)*m_coeff) track_m.set(1,2,mt.get(ind1,5)*m_coeff) track_v = track_m.mult(track_v) position = position + matrixNode.getLength() pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) #pack the resulting tuple graph_disp_arr = [] graph_disp_p_arr = [] for i in range(len(pos_arr)): graph_disp_arr.append((pos_arr[i],disp_arr[i])) graph_disp_p_arr.append((pos_arr[i],disp_p_arr[i])) return (graph_disp_arr,graph_disp_p_arr)
def trackTwissData(self, alpha, beta, direction = "x"): """ Returns the tuple ([(position, phase advance/2/pi),...], [(position, alpha),...],[(position,beta),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if(direction.lower() != "x" and direction.lower() != "y"): orbitFinalize("Class orbit.matrix_lattice.MATRIX_Lattice, method trackTwissData(...): direction should be x or y.") #track twiss eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if(direction.lower() == "y"): dir_ind = 2 gamma = (1.0+alpha*alpha)/beta track_m = Matrix(3,3) track_m.unit() track_v = PhaseVector(3) track_v.set(0,alpha) track_v.set(1,beta) track_v.set(2,gamma) position = 0. pos_arr = [] alpha_arr = [] beta_arr = [] #phi is for tune accumulation phi = 0. #phase advance mu_arr = [] #put in array the initial twiss pos_arr.append(position) mu_arr.append(phi) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) position_old = position beta_old = beta #count = 0 for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): beta = track_v.get(1) if(abs(position_old-position) > eps_length or abs(beta_old - beta) > eps_length): pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi/(2*math.pi)) mt = matrixNode.getMatrix() ind0 = 0+dir_ind ind1 = 1+dir_ind track_m.set(0,0,mt.get(ind0,ind0)*mt.get(ind1,ind1)+mt.get(ind0,ind1)*mt.get(ind1,ind0)) track_m.set(0,1,-mt.get(ind0,ind0)*mt.get(ind1,ind0)) track_m.set(0,2,-mt.get(ind0,ind1)*mt.get(ind1,ind1)) track_m.set(1,0,-2*mt.get(ind0,ind0)*mt.get(ind0,ind1)) track_m.set(1,1,mt.get(ind0,ind0)*mt.get(ind0,ind0)) track_m.set(1,2,mt.get(ind0,ind1)*mt.get(ind0,ind1)) track_m.set(2,0,-2*mt.get(ind1,ind0)*mt.get(ind1,ind1)) track_m.set(2,1,mt.get(ind1,ind0)*mt.get(ind1,ind0)) track_m.set(2,2,mt.get(ind1,ind1)*mt.get(ind1,ind1)) alpha_0 = track_v.get(0) beta_0 = track_v.get(1) delta_phi = math.atan( mt.get(ind0,ind1)/( beta_0*mt.get(ind0,ind0) - alpha_0*mt.get(ind0,ind1))) phi = phi + delta_phi track_v = track_m.mult(track_v) position_old = position beta_old = beta_0 position = position + matrixNode.getLength() #count = count + 1 pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi/(2*math.pi)) #pack the resulting tuple tune = phi/(2*math.pi) graph_alpha_arr = [] graph_beta_arr = [] graph_mu_arr = [] for i in range(len(pos_arr)): graph_mu_arr.append((pos_arr[i], mu_arr[i])) graph_alpha_arr.append((pos_arr[i],alpha_arr[i])) graph_beta_arr.append((pos_arr[i],beta_arr[i])) return (graph_mu_arr,graph_alpha_arr,graph_beta_arr)