def getDisp2(self, nE, s, matrixnE): """ Calculates dispersion at location s in element nE. :param int nE: number of element of interest :param float s: location of interest within element nE :return: dct of DX, DPX, DY and DPY """ # Get initial dispersion values DX, DPX, DY, DPY from previous # element or start marker (if nE=0) if nE != 0: prevE = self.elems[nE - 1] else: prevE = self.markers[0] if s == 0: return dct([('DX', prevE.DX), ('DPX', prevE.DPX), ('DY', prevE.DY), ('DPY', prevE.DPY)]) # Set up initial "dispersion vector" such that multiplication by # transport matrix gives final dispersion function disp0 = mtrx([[prevE.DX], [prevE.DPX], [prevE.DY], [prevE.DPY], [1], [0]]) m = matrixnE # Calculate final values disp = m * disp0 return dct([('DX', disp.item(0)), ('DPX', disp.item(1)), ('DY', disp.item(2)), ('DPY', disp.item(3))])
def getBeta2(self, nE, s, matrixnE): """ Calculates beta, alpha, gamma at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of BETX, BETY, ALFX, ALFY, GAMX and GAMY """ # Gets initial beta, alpha, gamma from previous element or start # marker (if nE=0) if nE != 0: prevE = self.elems[nE - 1] else: prevE = self.markers[0] betX0 = prevE.BETX alfX0 = prevE.ALFX gamX0 = (1 + alfX0 * alfX0) / betX0 betY0 = prevE.BETY alfY0 = prevE.ALFY gamY0 = (1 + alfY0 * alfY0) / betY0 if s == 0: return dct([('BETX', betX0), ('ALFX', alfX0), ('GAMX', gamX0), ('BETY', betY0), ('ALFY', alfY0), ('GAMY', gamY0)]) paraX0 = mtrx([[betX0], [alfX0], [gamX0]]) paraY0 = mtrx([[betY0], [alfY0], [gamY0]]) paraInitial = [paraX0, paraY0] eTransport = matrixnE # Extract required elements from transport matrix to form transform matrix # i=0 for x-direction; i=1 for y-direction # a=C, b=S, c=C', d=S' according to standard notation para = [] for i in [0, 1]: j = 2 * i a = eTransport.item((j, j)) b = eTransport.item((j, j + 1)) c = eTransport.item((j + 1, j)) d = eTransport.item((j + 1, j + 1)) twissTransform = mtrx([[a**2, -2 * a * b, b**2], [-a * c, b * c + a * d, -b * d], [c**2, -2 * c * d, d**2]]) para.append(twissTransform * paraInitial[i]) # Calculate final values return dct([('BETX', para[0].item(0)), ('ALFX', para[0].item(1)), ('GAMX', para[0].item(2)), ('BETY', para[1].item(0)), ('ALFY', para[1].item(1)), ('GAMY', para[1].item(2))])
def getPhase(self, nE, s): """ Calculates phase at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of MUX and MUY """ # Get initial phase values MUX and MUY from previous element # or start marker (if nE=0) if nE != 0: prevE = self.elems[nE - 1] else: prevE = self.markers[0] if s == 0: return dct([('MUX', prevE.MUX), ('MUY', prevE.MUY)]) para = self.getBeta(nE, s) # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s m = matrixForElement(e, 6) # NOTE: Takes order 6 if m == None: e.KEYWORD = "DRIFT" m = matrixForElement(e, 6) m = m(d=0) # Calculate cos(delta Phi) and sin(delta Phi) in x and y planes xy = m.item((0, 1)) / math.sqrt(prevE.BETX * para.BETX) xx = (math.sqrt(prevE.BETX) * m.item( (0, 0)) / math.sqrt(para.BETX)) - (prevE.ALFX * xy) yy = m.item((2, 3)) / math.sqrt(prevE.BETY * para.BETY) yx = (math.sqrt(prevE.BETY) * m.item( (2, 2)) / math.sqrt(para.BETY)) - (prevE.ALFY * yy) thetaX = math.atan2(xy, xx) thetaY = math.atan2(yy, yx) if thetaX < 0: thetaX = +2 * math.pi if thetaY < 0: thetaY = +2 * math.pi return dct([('MUX', thetaX / (2 * math.pi) + prevE.MUX), ('MUY', thetaY / (2 * math.pi) + prevE.MUY)])
def getDisp(self, nE, s): """ Calculates dispersion at location s in element nE. :param int nE: number of element of interest :param float s: location of interest within element nE :return: dct of DX, DPX, DY and DPY """ # Get initial dispersion values DX, DPX, DY, DPY from previous # element or start marker (if nE=0) if nE != 0: prevE = self.elems[nE-1] else: prevE = self.markers[0] if s == 0: return dct([('DX', prevE.DX), ('DPX', prevE.DPX), ('DY', prevE.DY), ('DPY', prevE.DPY)]) # Set up initial "dispersion vector" such that multiplication by # transport matrix gives final dispersion function disp0 = mtrx([[prevE.DX], [prevE.DPX], [prevE.DY], [prevE.DPY], [1], [0]]) # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s m = matrixForElement(e, 6) # NOTE: Take order 6 if m == None: e.KEYWORD = "DRIFT" m = matrixForElement(e, 6) m = m(d=0) # Calculate final values disp = m * disp0 return dct([('DX', disp.item(0)), ('DPX', disp.item(1)), ('DY', disp.item(2)), ('DPY', disp.item(3))])
def getPhase(self,nE,s): """ Calculates phase at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of MUX and MUY """ # Get initial phase values MUX and MUY from previous element # or start marker (if nE=0) if nE != 0: prevE = self.elems[nE-1] else: prevE = self.markers[0] if s == 0: return dct([('MUX', prevE.MUX), ('MUY', prevE.MUY)]) para = self.getBeta(nE,s) # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s m = matrixForElement(e, 6) # NOTE: Takes order 6 if m == None: e.KEYWORD = "DRIFT" m = matrixForElement(e, 6) m = m(d=0) # Calculate cos(delta Phi) and sin(delta Phi) in x and y planes xy = m.item((0,1)) / math.sqrt(prevE.BETX * para.BETX) xx = (math.sqrt(prevE.BETX) * m.item((0,0)) / math.sqrt(para.BETX)) - (prevE.ALFX * xy) yy = m.item((2,3)) / math.sqrt(prevE.BETY * para.BETY) yx = (math.sqrt(prevE.BETY) * m.item((2,2)) / math.sqrt(para.BETY)) - (prevE.ALFY * yy) thetaX = math.atan2(xy,xx) thetaY = math.atan2(yy, yx) if thetaX < 0: thetaX =+ 2 * math.pi if thetaY < 0: thetaY =+ 2 * math.pi return dct([('MUX', thetaX / (2 * math.pi) + prevE.MUX), ('MUY', thetaY / (2 * math.pi) + prevE.MUY)])
def getDisp(self, nE, s): """ Calculates dispersion at location s in element nE. :param int nE: number of element of interest :param float s: location of interest within element nE :return: dct of DX, DPX, DY and DPY """ # Get initial dispersion values DX, DPX, DY, DPY from previous # element or start marker (if nE=0) if nE != 0: prevE = self.elems[nE - 1] else: prevE = self.markers[0] if s == 0: return dct([('DX', prevE.DX), ('DPX', prevE.DPX), ('DY', prevE.DY), ('DPY', prevE.DPY)]) # Set up initial "dispersion vector" such that multiplication by # transport matrix gives final dispersion function disp0 = mtrx([[prevE.DX], [prevE.DPX], [prevE.DY], [prevE.DPY], [1], [0]]) # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s m = matrixForElement(e, 6) # NOTE: Take order 6 if m == None: e.KEYWORD = "DRIFT" m = matrixForElement(e, 6) m = m(d=0) # Calculate final values disp = m * disp0 return dct([('DX', disp.item(0)), ('DPX', disp.item(1)), ('DY', disp.item(2)), ('DPY', disp.item(3))])
def getPhase2(self, nE, s, matrixnE): """ Calculates phase at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of MUX and MUY """ # Get initial phase values MUX and MUY from previous element # or start marker (if nE=0) if nE != 0: prevE = self.elems[nE - 1] else: prevE = self.markers[0] if s == 0: return dct([('MUX', prevE.MUX), ('MUY', prevE.MUY)]) para = self.getBeta(nE, s) m = matrixnE # Calculate cos(delta Phi) and sin(delta Phi) in x and y planes xy = m.item((0, 1)) / math.sqrt(prevE.BETX * para.BETX) xx = (math.sqrt(prevE.BETX) * m.item( (0, 0)) / math.sqrt(para.BETX)) - (prevE.ALFX * xy) yy = m.item((2, 3)) / math.sqrt(prevE.BETY * para.BETY) yx = (math.sqrt(prevE.BETY) * m.item( (2, 2)) / math.sqrt(para.BETY)) - (prevE.ALFY * yy) thetaX = math.atan2(xy, xx) thetaY = math.atan2(yy, yx) if thetaX < 0: thetaX = +2 * math.pi if thetaY < 0: thetaY = +2 * math.pi # print s, thetaX return dct([('MUX', thetaX / (2 * math.pi) + prevE.MUX), ('MUY', thetaY / (2 * math.pi) + prevE.MUY)])
def getPhase2(self,nE,s,matrixnE): """ Calculates phase at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of MUX and MUY """ # Get initial phase values MUX and MUY from previous element # or start marker (if nE=0) if nE != 0: prevE = self.elems[nE-1] else: prevE = self.markers[0] if s == 0: return dct([('MUX', prevE.MUX), ('MUY', prevE.MUY)]) para = self.getBeta(nE,s) m = matrixnE # Calculate cos(delta Phi) and sin(delta Phi) in x and y planes xy = m.item((0,1)) / math.sqrt(prevE.BETX * para.BETX) xx = (math.sqrt(prevE.BETX) * m.item((0,0)) / math.sqrt(para.BETX)) - (prevE.ALFX * xy) yy = m.item((2,3)) / math.sqrt(prevE.BETY * para.BETY) yx = (math.sqrt(prevE.BETY) * m.item((2,2)) / math.sqrt(para.BETY)) - (prevE.ALFY * yy) thetaX = math.atan2(xy,xx) thetaY = math.atan2(yy, yx) if thetaX < 0: thetaX =+ 2 * math.pi if thetaY < 0: thetaY =+ 2 * math.pi # print s, thetaX return dct([('MUX', thetaX / (2 * math.pi) + prevE.MUX), ('MUY', thetaY / (2 * math.pi) + prevE.MUY)])
def getDisp2(self, nE, s, matrixnE): """ Calculates dispersion at location s in element nE. :param int nE: number of element of interest :param float s: location of interest within element nE :return: dct of DX, DPX, DY and DPY """ # Get initial dispersion values DX, DPX, DY, DPY from previous # element or start marker (if nE=0) if nE != 0: prevE = self.elems[nE-1] else: prevE = self.markers[0] if s == 0: return dct([('DX', prevE.DX), ('DPX', prevE.DPX), ('DY', prevE.DY), ('DPY', prevE.DPY)]) # Set up initial "dispersion vector" such that multiplication by # transport matrix gives final dispersion function disp0 = mtrx([[prevE.DX], [prevE.DPX], [prevE.DY], [prevE.DPY], [1], [0]]) m = matrixnE # Calculate final values disp = m * disp0 return dct([('DX', disp.item(0)), ('DPX', disp.item(1)), ('DY', disp.item(2)), ('DPY', disp.item(3))])
def getH(self, nE, s): """ Returns H(s) function at location s in element nE :param int nE: number of element of interest :param float s: location of interest within element nE """ para = self.getBeta(nE, s) disp = self.getDisp(nE, s) HX = (para.GAMX * disp.DX**2) + (2 * para.ALFX * disp.DX * disp.DPX) + (para.BETX * disp.DPX**2) HY = (para.GAMY * disp.DY**2) + (2 * para.ALFY * disp.DY * disp.DPY) + (para.BETY * disp.DPY**2) return dct([('HX', HX), ('HY', HY)])
def matrixnE(self,nE,s): # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix if s == 0: return 0 e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s eTransport = matrixForElement(e, 6) # NOTE: Takes order 6 if eTransport == None: e.KEYWORD ="DRIFT" eTransport = matrixForElement(e, 6) eTransport = eTransport(d=0) return eTransport
def matrixnE(self, nE, s): # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix if s == 0: return 0 e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s eTransport = matrixForElement(e, 6) # NOTE: Takes order 6 if eTransport == None: e.KEYWORD = "DRIFT" eTransport = matrixForElement(e, 6) eTransport = eTransport(d=0) return eTransport
def getNatChrom(self, BetStarX=None, BetX0=None, BetStarY=None, BetY0=None): """ Returns the natural chromaticity of the beamline :param float BetStarX: design beta in x-direction :param float BetX0: initial beta in x-direction :param float BetStarY: design beta in y-direction :param float BetY0: initial beta in y-direction These parameters are optional and are otherwise read from the twiss markers """ newT = copy(self) newT.elems = [] # Strip higher order elements from current twiss and store in a # new one for e in self.elems: if e.KEYWORD in ['DRIFT', 'QUADRUPOLE', 'SBEND'] and e.L != 0: newT.elems.append(e) # Calculate the map of the new twiss m = mapclass.Map2(newT) # For Xy, 001010 and Xy, 000110 # Fr = gamma(1./2)*3 * gamma(3./2)**2 # C = 8*pow(pi,-2.5) # Fr * C = 1 if BetStarX is None: BetStarX = self.markers[1].BETX if BetX0 is None: BetX0 = self.markers[0].BETX if BetStarY is None: BetStarY = self.markers[1].BETY if BetY0 is None: BetY0 = self.markers[0].BETY #CHECK FOR X!!! JUST GUESSING return dct([ ('NChromX', (m['x'][(1, 0, 0, 0, 1, 0)]**2 * BetX0 / BetStarX + m['x'][(0, 1, 0, 0, 1, 0)]**2 / (BetX0 * BetStarX)).real), ('NChromY', (m['y'][(0, 0, 1, 0, 1, 0)]**2 * BetY0 / BetStarY + m['y'][(0, 0, 0, 1, 1, 0)]**2 / (BetY0 * BetStarY)).real) ])
def getChrom(self, s=None, s0=0, n=100): """ Calculates chromaticity using -1/4pi * integral (beta*K) ds :param float s: end location along beamline :param float s0: start location along beamline (optional) :param int n: number of intervals for integration (optional) :returns: chromaticity between s0 and s """ if s is None: s = self.markers[1].S ## CHECK: positive/negative signs on K for focus vs. defocus... ## Is this natural chromaticity also because it only considers quadrupoles? ## What about multipole quadrupoles? def fX(s): nE = self.findElem(s) e = self.elems[nE] ss = s - (e.S - e.L) bet = self.getBeta(nE, ss) if e.K1L != 0: return bet.BETX * -e.K1L / e.L # Correct to make negative? else: return 0 def fY(s): nE = self.findElem(s) e = self.elems[nE] ss = s - (e.S - e.L) bet = self.getBeta(nE, ss) if e.K1L != 0: return bet.BETY * e.K1L / e.L else: return 0 return dct([('ChromX', -simpson(fX, s0, s, n) / (4 * math.pi)), ('ChromY', -simpson(fY, s0, s, n) / (4 * math.pi))])
def getNatChrom(self, BetStarX=None, BetX0=None, BetStarY=None, BetY0=None): """ Returns the natural chromaticity of the beamline :param float BetStarX: design beta in x-direction :param float BetX0: initial beta in x-direction :param float BetStarY: design beta in y-direction :param float BetY0: initial beta in y-direction These parameters are optional and are otherwise read from the twiss markers """ newT = copy(self) newT.elems = [] # Strip higher order elements from current twiss and store in a # new one for e in self.elems: if e.KEYWORD in ['DRIFT', 'QUADRUPOLE', 'SBEND'] and e.L != 0: newT.elems.append(e) # Calculate the map of the new twiss m = mapclass.Map2(newT) # For Xy, 001010 and Xy, 000110 # Fr = gamma(1./2)*3 * gamma(3./2)**2 # C = 8*pow(pi,-2.5) # Fr * C = 1 if BetStarX is None: BetStarX = self.markers[1].BETX if BetX0 is None: BetX0 = self.markers[0].BETX if BetStarY is None: BetStarY = self.markers[1].BETY if BetY0 is None: BetY0 = self.markers[0].BETY #CHECK FOR X!!! JUST GUESSING return dct([('NChromX', (m['x'][(1,0,0,0,1,0)]**2 * BetX0 / BetStarX + m['x'][(0,1,0,0,1,0)]**2 / (BetX0 * BetStarX)).real), ('NChromY', (m['y'][(0,0,1,0,1,0)]**2 * BetY0 / BetStarY + m['y'][(0,0,0,1,1,0)]**2 / (BetY0 * BetStarY)).real)])
def getBeta(self, nE, s): """ Calculates beta, alpha, gamma at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of BETX, BETY, ALFX, ALFY, GAMX and GAMY """ # Gets initial beta, alpha, gamma from previous element or start # marker (if nE=0) if nE != 0: prevE = self.elems[nE-1] else: prevE = self.markers[0] betX0 = prevE.BETX alfX0 = prevE.ALFX gamX0 = (1 + alfX0**2) / betX0 betY0 = prevE.BETY alfY0 = prevE.ALFY gamY0 = (1 + alfY0**2) / betY0 if s == 0: return dct([('BETX', betX0), ('ALFX', alfX0), ('GAMX', gamX0), ('BETY', betY0), ('ALFY', alfY0), ('GAMY', gamY0)]) paraX0 = mtrx([[betX0], [alfX0], [gamX0]]) paraY0 = mtrx([[betY0], [alfY0], [gamY0]]) paraInitial = [paraX0, paraY0] # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s eTransport = matrixForElement(e, 6) # NOTE: Takes order 6 if eTransport == None: e.KEYWORD ="DRIFT" eTransport = matrixForElement(e, 6) eTransport = eTransport(d=0) # Extract required elements from transport matrix to form transform matrix # i=0 for x-direction; i=1 for y-direction # a=C, b=S, c=C', d=S' according to standard notation para = [] for i in [0, 1]: j = 2 * i a = eTransport.item((j, j)) b = eTransport.item((j, j+1)) c = eTransport.item((j+1, j)) d = eTransport.item((j+1, j+1)) twissTransform = mtrx([[a**2, -2*a*b, b**2], [-a*c, b*c + a*d, -b*d], [c**2, -2*c*d, d**2]]) para.append(twissTransform*paraInitial[i]) # Calculate final values return dct([('BETX', para[0].item(0)), ('ALFX', para[0].item(1)), ('GAMX', para[0].item(2)), ('BETY', para[1].item(0)), ('ALFY', para[1].item(1)), ('GAMY', para[1].item(2))])
def __init__(self, filename='twiss'): self.elems = [] # Markers (only takes 1st and last) self.markers = [] self.types_parameters = dct() f = open(filename, 'r') for line in f: # if ("@ " in line and "%le" in line) : # FIX to take DPP %s if "@ " not in line and "@" in line: line = replace(line, "@", "@ ") splt = line.split() if "@ " in line and "%" in line and "s" not in splt[2]: label = splt[1] try: self[label] = float(splt[3]) self.types_parameters[label] = "%le" except: print "Problem parsing:", line print "Going to be parsed as string" try: self[label] = splt[3].strip('"') self.types_parameters[label] = "%s" except: print "Problem persits, let's ignore it!" elif "@ " in line and "s" in splt[2]: label = splt[1].strip(":") self[label] = splt[3].strip('"') self.types_parameters[label] = "%s" if "* " in line or "*\t" in line: labels = splt[1:] if "$ " in line or "$\t" in line: types = splt[1:] self.types_parameters.update(dct(zip(labels, types))) if "@" not in line and "*" not in line and "%" not in line: vals = [] for j in range(0, len(labels)): if "%d" in types[j]: vals.append(int(splt[j])) if "%le" in types[j]: vals.append(float(splt[j])) if "s" in types[j]: vals.append(splt[j].strip('"')) e = dct(zip(labels, vals)) e.update(self) e['ACHROMAT'] = "F" self.types_parameters['ACHROMAT'] = "%s" del e['markers'] del e['elems'] del e['types_parameters'] if "$" in line: self.markers.append(e) else: self.elems.append(e) f.close() try: labels types except: print "From Metaclass: Bad format or empty file ", filename print "Leaving Metaclass" exit()
def __init__(self, filename='twiss'): self.elems = [] # Markers (only takes 1st and last) self.markers = [] self.types_parameters = dct() f = open(filename, 'r') for line in f: # if ("@ " in line and "%le" in line) : # FIX to take DPP %s if "@ " not in line and "@" in line: line = replace(line, "@", "@ ") splt = line.split() if "@ " in line and "%" in line and "s" not in splt[2]: label = splt[1] try: self[label] = float(splt[3]) self.types_parameters[label] = "%le" except: print "Problem parsing:", line print "Going to be parsed as string" try: self[label] = splt[3].strip('"') self.types_parameters[label] = "%s" except: print "Problem persits, let's ignore it!" elif "@ " in line and "s" in splt[2]: label = splt[1].strip(":") if label == "NAME": # recovering from bug: NAME has two uses label = "TNAME" # tableNAME and elementNAME! self[label] = splt[3].strip('"') self.types_parameters[label] = "%s" if "* " in line or "*\t" in line: labels = splt[1:] if "$ " in line or "$\t" in line: types = splt[1:] self.types_parameters.update(dct(zip(labels, types))) if "@" not in line and "*" not in line and "%" not in line: vals = [] for j in range(0, len(labels)): if "%d" in types[j]: vals.append(int(splt[j])) if "%le" in types[j]: vals.append(float(splt[j])) if "s" in types[j]: vals.append(splt[j].strip('"')) e = dct(zip(labels, vals)) e.update(self) e['ACHROMAT'] = "F" self.types_parameters['ACHROMAT'] = "%s" del e['markers'] del e['elems'] del e['types_parameters'] if "$" in line: self.markers.append(e) else: self.elems.append(e) f.close() try: labels types except: print "From Metaclass: Bad format or empty file ", filename print "Leaving Metaclass" exit()
def getBeta(self, nE, s): """ Calculates beta, alpha, gamma at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of BETX, BETY, ALFX, ALFY, GAMX and GAMY """ # Gets initial beta, alpha, gamma from previous element or start # marker (if nE=0) if nE != 0: prevE = self.elems[nE - 1] else: prevE = self.markers[0] betX0 = prevE.BETX alfX0 = prevE.ALFX gamX0 = (1 + alfX0**2) / betX0 betY0 = prevE.BETY alfY0 = prevE.ALFY gamY0 = (1 + alfY0**2) / betY0 if s == 0: return dct([('BETX', betX0), ('ALFX', alfX0), ('GAMX', gamX0), ('BETY', betY0), ('ALFY', alfY0), ('GAMY', gamY0)]) paraX0 = mtrx([[betX0], [alfX0], [gamX0]]) paraY0 = mtrx([[betY0], [alfY0], [gamY0]]) paraInitial = [paraX0, paraY0] # Copy element nE and change length to location of interest, s # Calculate transport matrix for this element assuming D=0 # If nE is not DRIFT, QUADRUPOLE or DIPOLE, change element to # DRIFT and recalculate transport matrix e = dct(self.elems[nE]) if e.L != 0: e.K1L = (e.K1L / e.L) * s e.ANGLE = (e.ANGLE / e.L) * s e.L = s eTransport = matrixForElement(e, 6) # NOTE: Takes order 6 if eTransport == None: e.KEYWORD = "DRIFT" eTransport = matrixForElement(e, 6) eTransport = eTransport(d=0) # Extract required elements from transport matrix to form transform matrix # i=0 for x-direction; i=1 for y-direction # a=C, b=S, c=C', d=S' according to standard notation para = [] for i in [0, 1]: j = 2 * i a = eTransport.item((j, j)) b = eTransport.item((j, j + 1)) c = eTransport.item((j + 1, j)) d = eTransport.item((j + 1, j + 1)) twissTransform = mtrx([[a**2, -2 * a * b, b**2], [-a * c, b * c + a * d, -b * d], [c**2, -2 * c * d, d**2]]) para.append(twissTransform * paraInitial[i]) # Calculate final values return dct([('BETX', para[0].item(0)), ('ALFX', para[0].item(1)), ('GAMX', para[0].item(2)), ('BETY', para[1].item(0)), ('ALFY', para[1].item(1)), ('GAMY', para[1].item(2))])
def getBeta2(self, nE, s, matrixnE): """ Calculates beta, alpha, gamma at location s in element nE. :param int nE: number of element of interest - where the first element is 0 :param float s: location of interest within element nE :return: dct of BETX, BETY, ALFX, ALFY, GAMX and GAMY """ # Gets initial beta, alpha, gamma from previous element or start # marker (if nE=0) if nE != 0: prevE = self.elems[nE-1] else: prevE = self.markers[0] betX0 = prevE.BETX alfX0 = prevE.ALFX gamX0 = (1 + alfX0*alfX0) / betX0 betY0 = prevE.BETY alfY0 = prevE.ALFY gamY0 = (1 + alfY0*alfY0) / betY0 if s == 0: return dct([('BETX', betX0), ('ALFX', alfX0), ('GAMX', gamX0), ('BETY', betY0), ('ALFY', alfY0), ('GAMY', gamY0)]) paraX0 = mtrx([[betX0], [alfX0], [gamX0]]) paraY0 = mtrx([[betY0], [alfY0], [gamY0]]) paraInitial = [paraX0, paraY0] eTransport = matrixnE # Extract required elements from transport matrix to form transform matrix # i=0 for x-direction; i=1 for y-direction # a=C, b=S, c=C', d=S' according to standard notation para = [] for i in [0, 1]: j = 2 * i a = eTransport.item((j, j)) b = eTransport.item((j, j+1)) c = eTransport.item((j+1, j)) d = eTransport.item((j+1, j+1)) twissTransform = mtrx([[a**2, -2*a*b, b**2], [-a*c, b*c + a*d, -b*d], [c**2, -2*c*d, d**2]]) para.append(twissTransform*paraInitial[i]) # Calculate final values return dct([('BETX', para[0].item(0)), ('ALFX', para[0].item(1)), ('GAMX', para[0].item(2)), ('BETY', para[1].item(0)), ('ALFY', para[1].item(1)), ('GAMY', para[1].item(2))])