From 0cafce4b728978b800833f4b4b33ea4336bcb56d Mon Sep 17 00:00:00 2001 From: LiarGC Date: Thu, 7 Sep 2023 09:49:16 +0800 Subject: [PATCH] Some changes in mad_parser.py and teapot.py Firstly, an improvement for function readMad() was made. Now, Madx lines like 'Q01:QUADRUPOLE,L=1.0,K1:=kQD1;' could be read correctly. Secondly, an attempt for using 'fint' and 'hgap' was made, but the correctness of this attempt could not be guaranteed. --- py/orbit/parsers/mad_parser.py | 19 +++++++++++++++++++ py/orbit/teapot/teapot.py | 31 +++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/py/orbit/parsers/mad_parser.py b/py/orbit/parsers/mad_parser.py index 0fa958da..7862ed95 100755 --- a/py/orbit/parsers/mad_parser.py +++ b/py/orbit/parsers/mad_parser.py @@ -654,6 +654,7 @@ def parse(self,MADfileName): for var in self.__accValues: accVarDict[var.getName()] = var localValDict = {} + IgnoredElementDict = {} doNotStop = True while(doNotStop): doNotStop = False @@ -664,6 +665,14 @@ def parse(self,MADfileName): res,val = StringFunctions.calculateString(str_in.lower(),localValDict) if(res): localValDict[name.lower()] = val + + # In _init_string(), the line would be divided into 5 types by _findLineType(). + # However, lines like "Q01:QUADRUPOLE,L=1.0,K1:=kQD1;"(kQD1=0.2) would be recognised as "variables" type. + # In fact, these lines should be "elements" type, as a result, they are ignored by self.__accElements. + # So here, the IgnoredElementDict is recorded, whose format is {'Q01:QUADRUPOLE,L=1.0,K1' : 0.2, ...} + if re.search(r':[^=]', name.replace(" ", "")): # lines of "variables" type would have ':=' but not single ':' + IgnoredElementDict[name] = val + var.setValue(val) del accVarDict[name] else: @@ -675,6 +684,14 @@ def parse(self,MADfileName): print "=========== MAD File Problem ===============" print "=================STOP=======================" sys.exit(1) + + # As mentioned before, these ignored lines should be appended into self.__accElements. + for i in range(len(IgnoredElementDict)): + str0 = '%s=%.10f'%(IgnoredElementDict.keys()[i],IgnoredElementDict.values()[i]) # {'Q01:QUADRUPOLE,L=1.0,K1' : 0.2} will become 'Q01:QUADRUPOLE,L=1.0,K1=0.2000000000'. + elem = _element() + elem.parseLine(str0) + self.__accElements.append(elem) + #------------------------------------------- # Now calculate all parameters in key,string_value # for accelerator elements @@ -794,6 +811,8 @@ def _init_string(self,str0): # 4 - call another nested MAD file #Delete spaces str0=re.sub(r'[ ]',"",str0) + # Someone would use tab'\t' for alignments in writing. + str0 = str0.replace('\t','') tp = self._findLineType(str0) if tp == 0: #print "StrType =0 :",str0 diff --git a/py/orbit/teapot/teapot.py b/py/orbit/teapot/teapot.py index 67874a98..70b8827c 100755 --- a/py/orbit/teapot/teapot.py +++ b/py/orbit/teapot/teapot.py @@ -233,6 +233,20 @@ def getElements(self, madElem): ea1 = ea1 + theta/2.0 ea2 = ea2 + theta/2.0 + # fint and hgap are used to describe the difference between the horizontal fringe field, e_x, and the vertical one, e_y + # More details could be found in the userguide of Madx + fint = 0. + if(params.has_key("fint")): + fint = params["fint"] + hgap = 0. + if(params.has_key("hgap")): + hgap = params["hgap"] + ea1_y = (ea1 - 2*hgap*fint*theta/length*(1+math.sin(ea1)**2)) + ea2_y = (ea2 - 2*hgap*fint*theta/length*(1+math.sin(ea2)**2)) + elem.addParam("ea1_y",ea1_y) + elem.addParam("ea2_y",ea2_y) + # end + elem.addParam("theta",theta) elem.addParam("ea1",ea1) elem.addParam("ea2",ea2) @@ -1010,7 +1024,12 @@ def fringeIN(node,paramsDict): TPB.wedgedrift(bunch,e,inout) if(usageIN): frinout = 0 - TPB.wedgerotate(bunch, e, frinout) + # TPB.wedgerotate(bunch, e, frinout) + # In fact, I do not know what TPB.wedgerotate() does + # I am not sure if this code reall works, even though I have got correct TWISS. + e_y = node.getParam("ea1_y") + TPB.wedgerotate(bunch, e_y, frinout) + TPB.bendfringeIN(bunch, rho) if(length != 0.): for i in xrange(len(poleArr)): @@ -1019,7 +1038,8 @@ def fringeIN(node,paramsDict): skew = skewArr[i] TPB.multpfringeIN(bunch,pole,kl,skew,useCharge) frinout = 1 - TPB.wedgerotate(bunch, e, frinout) + # TPB.wedgerotate(bunch, e, frinout) + TPB.wedgerotate(bunch, e_y, frinout) TPB.wedgebendCF(bunch, e, inout, rho, len(poleArr), poleArr, klArr, skewArr, nParts - 1, useCharge) else: if(usageIN): @@ -1048,7 +1068,9 @@ def fringeOUT(node,paramsDict): TPB.wedgebendCF(bunch, e, inout, rho, len(poleArr), poleArr, klArr, skewArr, nParts - 1, useCharge) if(usageOUT): frinout = 0 - TPB.wedgerotate(bunch, -e, frinout) + # TPB.wedgerotate(bunch, -e, frinout) + e_y = node.getParam("ea2_y") + TPB.wedgerotate(bunch, -e_y, frinout) TPB.bendfringeOUT(bunch, rho) if(length != 0.): for i in xrange(len(poleArr)): @@ -1057,7 +1079,8 @@ def fringeOUT(node,paramsDict): skew = skewArr[i] TPB.multpfringeOUT(bunch,pole,kl,skew,useCharge) frinout = 1 - TPB.wedgerotate(bunch, -e, frinout) + # TPB.wedgerotate(bunch, -e, frinout) + TPB.wedgerotate(bunch, -e_y, frinout) TPB.wedgedrift(bunch,e,inout) else: if(usageOUT):