def DecSafely(B1, amp, B1max, B1upper, aMax, units): """ B1 = input decoupling field amp = Decoupling Dict key B1max= Soft limit B1upper=Hard limit aMax = Soft limit ampl input must be in dB """ adjust = 20 * (math.log10(float(B1) / B1max)) if float(B1) > B1upper: if units == "W": MaxAmp = dBtoW(aMax) if units == "dB": MaxAmp = aMax TopCmds.MSG("<html><p style='text-align: center;'><font size=28><font color=\'DF013A\'>"+\ "WARNING !!!</p></font><br>"+\ "\n\nThe decoupling field ("+\ pul.pulDict[amp]+") exceeds "+str('%.3f' %(float(B1upper)/1000.))+" kHz maximum\n\n"+\ pul.pulDict[amp]+" will be set to "+str(MaxAmp)+units+" ("+str('%.3f' %(float(B1max)/1000.))+" kHz)</font>") Damp = aMax elif float(B1) > B1max: TopCmds.MSG("<html><p style='text-align: center;'><font size=28><font color=\'DF013A\'>"+\ "WARNING !!!</p></font><br>"+\ "\n\nThe desired decoupling field ("+\ pul.pulDict[amp]+") is "+ str('%.3f' %(float(B1)/1000.))+" kHz\n\n The hard pulse maximum field is "+\ str('%.3f' %(float(B1max)/1000.))+"\n"+" kHz</html>") Damp = aMax - adjust else: Damp = aMax - adjust return Damp
def Merger(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "Merging Help</p></font><br>"+\ "\n\nMerge Parameters Between Experiments"+\ "Requirements: Previous Experiments\n"+\ "\n"+\ "Arguments:\n"+\ "-dB : interact with db instead of watts (TS3+)\n"+\ "-f : open and close files instead of switching windows\n"+\ "-EXPNO ##: grab from experiment number ## (default to n-1)\n"+\ "-qt : quiet all interaction- \n\n"+\ "By default, the pulse program name is used to determine parameter\n"+\ "To Specify Parameters input the elements separately or in a string.\n"+\ " Specify Hard pulses separately (hNCA H C)\n"+\ " H C N : Update hard pulses \n"+\ " HC HN NCO NCA NH CH hhC : Specified CP parameters\n"+\ " CX: PDSD/DARR \n"+\ " HDec: H-Dec\n"+\ " ph : Phasing \n"+\ "\nPath : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/\n"+\ "modules: Merge, MergeGet, MergePut\n"+\ "wrappers: MrMerger \n"+\ "\n"+\ "Failures: Incorrect dict keys\n"+\ "")
def HDec(): Stuff = [] p90H = float(TopCmds.GETPAR("P 3")) ampH = float(TopCmds.GETPAR("PLdB 2")) MaxB1H = 1000000. / 4. / p90H CPD = TopCmds.GETPAR2("CPDPRG 2") if CPD == "mlev" or CPD == "None": TopCmds.XCMD("cpdprg2") CPD = (TopCmds.GETPAR2("CPDPRG 2")) #TopCmds.MSG(str(CPD)) Stuff = CPDtools.CPDparse(CPD, "1H") TopCmds.MSG(str(Stuff)) amp0 = CPDtools.Find_old_pl(Stuff[0]) decpw0 = CPDtools.Find_old_pw(Stuff[1], "1H") B1_0 = MaxB1H * (math.pow(10, (ampH - amp0) / 20.)) / 1000. if B1_0 > 1.: B1out = '% .1f' % B1_0 if B1_0 <= 1.: B1out = '75.0' index = TopCmds.INPUT_DIALOG("Mr Setup Input", "Decoupling Window", \ ["Desired 1H Decoupling Amplitude","File"],\ [B1out,CPD],["kHz",""],["1","1",],\ ["Accept","Close"], ['a','c'], 10) TopCmds.PUTPAR("CPDPRG 2", index[1]) #print(index[0], MaxB1H) adjust = 20 * (math.log10(1000. * float(index[0]) / MaxB1H)) Hamp = ampH - adjust decpwH = (MaxB1H / 1000. / float(index[0])) * (170. / 180.) * 2 * p90H wattsH = dBtoW(Hamp) value = TopCmds.SELECT("Adjusting the H decoupling parameters:",\ "This will set\n 1H power ("+ Stuff[0] +") to: "+ str('%.2f' %wattsH)+ " W\n \ Pulse width (" + Stuff[1] +") to: " +str('%3.2f' %decpwH) + " us",["Update", "Keep Previous"]) if value != 1: if Stuff[0] == 'pl12': TopCmds.PUTPAR("PLdB 12", str('%3.2f' % Hamp)) elif Stuff[0] == 'pl13': TopCmds.PUTPAR("PLdB 13", str('%3.2f' % Hamp)) elif Stuff[0] == 'pl14': TopCmds.PUTPAR("PLdB 14", str('%3.2f' % Hamp)) if Stuff[1] == 'pcpd': TopCmds.PUTPAR("PCPD 2", str('%3.2f' % decpwH)) elif Stuff[1] == 'p31': TopCmds.PUTPAR("P 31", str('%3.2f' % decpwH)) TopCmds.PUTPAR("P 30", str('%3.2f' % decpwH)) elif Stuff[1] == 'p62': TopCmds.PUTPAR("P 61", str('%3.2f' % decpwH)) TopCmds.PUTPAR("P 62", str('%3.2f' % decpwH))
def Find_PWdec(Text): while i < len(Text): about = '' if Text[i].find("pcpd") >= 0: type = "PCPD" elif Text[i].find("p31") >= 0: type = "P 31" elif Text[i].find("p63") >= 0: type = "P 63" elif Text[i].find("p62") >= 0: type = "P 62" else: TopCmds.MSG("File for Decoupling not found; Exiting") TopCmds.EXIT()
def find_match(input): import math NomRF = 1000 * float(input[0]) MAS = float(input[1]) Ioffs = 1000 * float(input[6]) Soffs = 1000 * float(input[7]) m = 1 Match = m * MAS - Ioffs - Soffs if Match < 0: m = 2 Match = m * MAS - Ioffs - Soffs if Match < 0: TopCmds.MSG("Cannot find match conditions, spinning too slowly") TopCmds.EXIT() found = 0 for n in range(10000): WIeff = math.sqrt(Ioffs * Ioffs + float(n * n)) WSeff = math.sqrt(Soffs * Soffs + float(n * n)) Match = (m * MAS) - WIeff - WSeff #mm is the amplitude in Hz if Match > 0.0: mm = n if Match < 0.0: found = 1 if found == 0: TopCmds.MSG("Match condition not found within 10kHz, aborting") TopCmds.EXIT() YorN = TopCmds.SELECT( "Scaling", "The match condition is around %i Hz \n\n Which scaling should be used?" % mm, ["Calibration", "0.5", "None(1.0)"]) # CONFIRM("Scale Shape Pulse for Match","The amplitude should be approximately %i Hz \n \nUse scaling?" % Match) if YorN < 0: Scale = 1.0 if YorN == 0: Scale = float(Match) / NomRF if YorN == 1: Scale = 0.5 if YorN == 2: Scale = 1.0 return Scale
def PPparse(pp): Dirs = get_dir() Name = find_file(Dirs, pp) #TopCmds.MSG(str(Dirs)) #TopCmds.MSG(str(Name)) # There is a problem if the files don't exist. if os.path.exists(Name) == 1: f = open(Name, 'r') text = f.readlines() f.close() else: while os.path.exists(Name) != 1: TopCmds.XCMD('edpul') pp = TopCmds.GETPAR("PULPROG") Name = find_file(Dirs, pp) if os.path.exists(Name) == 1: f = open(Name, 'r') text = f.readlines() f.close() kkl = CPDtools.devide_into_lines(text) TopCmds.MSG(str(kkl)) for line in kkl: lines = line.rstrip() TopCmds.MSG(lines) #lines.append=CPDtools.devide_into_lines(lines) TopCmds.MSG(str(lines)) for line in text: lines = line.rstrip() return text
def get_cpd_plnam(Text, Nuc): pl_nam = '' if Nuc == "1H": key = "cpds2", "cpd2", "cw" if Nuc == "2H": key = "cpds5", "cpd5", "cw" if Nuc == "13C": key = "cpds4", "cpd4", "cw" if Nuc == "15N": key = "cpds3", "cpd3", "cw" j = 1 for i in range(len(Text)): if Text[i].find(key[0]) >=0 or Text[i].find(key[1]) >=0\ or Text[i].find(key[2]) >=0: j = i - 5 for i in range(j, len(Text)): if Nuc == "1H": if Text[i].find("pl12:f2") >= 0: pl_nam = 'pl12' if Text[i].find("pl13:f2") >= 0: pl_nam = 'pl13' if Text[i].find("pl14:f2") >= 0: pl_nam = 'pl14' if Text[i].find("pl12:H") >= 0: pl_nam = 'pl12' if Text[i].find("pl13:H") >= 0: pl_nam = 'pl13' if Text[i].find("pl14:H") >= 0: pl_nam = 'pl14' if Text[i].find("pl12):H") >= 0: pl_nam = 'pl12' if Text[i].find("pl13):H") >= 0: pl_nam = 'pl13' if Text[i].find("pl14):H") >= 0: pl_nam = 'pl14' if Nuc == "2H": if Text[i].find("pl25:f3") >= 0: pl_nam = 'pl25' if Text[i].find("pl25:f4") >= 0: pl_nam = 'pl25' if Text[i].find("pl25:D") >= 0: pl_nam = 'pl25' if Nuc == "13C": if Text[i].find("pl4:f1") >= 0: pl_nam = 'pl4' if Text[i].find("pl4:C") >= 0: pl_nam = 'pl4' if Nuc == "15N": if Text[i].find("pl3:f2") >= 0: pl_nam = 'pl3' if Text[i].find("pl3:f3") >= 0: pl_nam = 'pl3' if Text[i].find("pl3:N") >= 0: pl_nam = 'pl3' if pl_nam == '': TopCmds.MSG( 'Using default decoupling name \n H=pl12 \n N=pl3 \n C=pl4 \D=pl25\ /n/n The decoupling power was not deduced from either the CPDPRG or PULSEPROGRAM\n\ PLEASE CONFIRM !!!') pl_nam = 'default' #TopCmds.MSG("I have finished the CPD parse!") return pl_nam
def Sym(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "Symmetry-based Recoupling Setup Help</p></font><br>"+\ "\n\nCalculate match amplitude for C and R sequences\n"+\ "Hard pulse power and duration are needed\n"+\ "\n"+\ "Arguments:\n"+\ "-dB : interact with db instead of watts (TS3+)\n"+\ "-qt : Quiet the initial Hard-pulse input\n"+\ "-help: This Window\n"+\ "\n"+\ "Can be used for experiments that can be descrbed by symmetry numbers\n"+\ "Gives warnings if the field is higher than the hard pulse field,\n"+\ "And will not set powers greater than hard pulse field\n"+\ "\n"+\ "Path : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/Setup.py\n"+\ "modules: CalcSym \n"+\ "wrapper: C72, SPC5_2, DARR, etc.\n"+\ "Limitations: One channel + CW Decoupler only")
def XhhC(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "XhhC Setup Help</p></font><br>"+\ "\n\nCopy CP amplitudes, adjust conditions for ramps\n"+\ "Hard pulse power, duration, and shapes are needed\n"+\ "\n"+\ "Arguments:\n"+\ "-dB : interact with db instead of watts (TS3+)\n"+\ "-help: This Window\n"+\ "\n"+\ "Adjusts amplitude for shaped pulses\n"+\ "Copies HX match condition from previous set-ups\n"+\ "\n"+\ "Path : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/XhhC.py\n"+\ "modules: copyCP\n"+\ "wrappers: CH,NH,HC \n"+\ "\n"+\ "Failures:\n"+\ "Shape is not specified (dialog pops up) or does not exist.")
def TAN(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "Tan Ramp Calculator Help</p></font><br>"+\ "\n\nComputes a TANGENT pulse shape with defined Start and End"+\ "Requirements: \n"+\ "\n"+\ "Arguments:\n"+\ "-sp:shaped pulse name\n"+\ "-d : delta (+/- d%)\n"+\ "-b : beta (curvature)\n"+\ "-p : number of points (default 1000)\n"+\ "-np: number of points\n"+\ "-sc: number of points\n"+\ "-name : specify name\n"+\ "\n"+\ "Path : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/TAN.py\n"+\ "modules: TAN.py\n"+\ "wrappers: none \n"+\ "\n"+\ "Failures:\n"+\ "")
def find_file(dirs, name): found = 0 i = 0 path = '' while i <= (len(dirs) - 1): #print (dirs[i], found ) if found == 0: search = str(dirs[i]) + '/' + str(name) """ TopCmds.MSG("This is here to remind you that the os package is removed") found=1 path=search """ if os.path.exists(search) == 1: found = 1 path = search i = i + 1 if found == 0: TopCmds.MSG("File named " + name + " not found\n Exiting") TopCmds.EXIT() return path
def LG(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "LG Setup Help</p></font><br>"+\ "\n\nComputes Various Lee-Goldburg conditions"+\ "Requirements: Hard pulse power, duration, and possibly shapes are needed\n"+\ "\n"+\ "Arguments:\n"+\ "-dB : interact with db instead of watts (TS3+)\n"+\ "-qt : Quiet the initial Hard-pulse input\n"+\ "-help: This Window\n"+\ "\n"+\ "-SW : Determine LG parameters given a set sweep width \n"+\ "-Fld : Determine LG parameters given a set B1eff field \n"+\ "-pul : Determine LG parameters given a set FSLG 90 pulse \n"+\ "Default is to set a B1 field \n"+\ "\n"+\ "Path : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/LeeGoldburg.py\n"+\ "modules: LeeGoldburg, Setup.CalcCP\n"+\ "wrappers: none \n"+\ "\n"+\ "Failures:\n"+\ "")
def load_templt(templt, expname, stan_dir): """ Load Topspin parameter set from stand_dir and creates a new dataset. Args: templt: Name of topspin parameter set expname: Name of the new dataset stand_dir: Directory from where Topspin stores new data set """ try: TC.NEWDATASET([expname, '1', '1', stan_dir]) TC.RE([expname, '1', '1', stan_dir], 'y') TC.XCMD('rpar %s all' % templt) except: TC.MSG( '''You need to define the parameter set "%s" defining the correct routing to continue. First define the correct routing using edasp. Then save the parmeterset using: wpar %s all ''' % (templt, templt)) TC.EXIT()
def SelPul(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "Soft Pulse Setup Help</p></font><br>"+\ "\n\nCalculate amplitude for Soft Pulses\n"+\ "Requirements: Hard Pulse Parameters, Soft Pulse Shape\n"+\ "\n"+\ "Arguments:\n"+\ "-dB : interact with db instead of watts (TS3+)\n"+\ "-help: This Window\n"+\ "\n"+\ "Adjusts amplitude for shaped pulses\n"+\ "Suggests an Tau_R*(N+1/2) pulse time if not already set.\n"+\ "\n"+\ "Path : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/SelPul.py\n"+\ "modules: CalSP\n"+\ "wrappers: CAexc, CAref, COexc, COref\n"+\ "Faults:\n"+\ "May guess timing to be too short.\n"+\ "Failures:\n"+\ "If shape is not specified (dialog pops up) or does not exist.\n"+\ "if the shape exists, the next calculation will be successful.")
def Dec(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "Decoupling Setup Help</p></font><br>"+\ "\n\nCalculate amplitude for CPD Decoupling\n"+\ "Hard pulse power, duration, and cpdprg are needed\n"+\ "\n"+\ "Arguments:\n"+\ "-dB : interact with db instead of watts (TS3+)\n"+\ "-qt : Quiet the initial Hard-pulse input\n"+\ "-help: This Window\n"+\ "\n"+\ "Determines previous decoupling field for first suggestion,\n"+\ "Gives warnings if the field is higher than the hard pulse field,\n"+\ "It will not set conditions higher than a defined level\n"+\ "\n"+\ "Path : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/Setup.py\n"+\ "modules: CalDec, DecSafely\n"+\ "wrappers: HDec, Cdec, NDec\n"+\ "Defaults are defined in wrappers\n"+\ "Faults:\n"+\ "The decoupling tip angle is pre-assumed; it may be wrong for your cpdprg \n"+\ "Channel specific parameter definitions in wrappers")
def CalS6purge(): p90C=float(TopCmds.GETPAR("P 1")) ampC=float(TopCmds.GETPAR("PLdB 1")) MaxB1 = 1000000./4./p90C p90sC=float(TopCmds.GETPAR("P 6")) SPname=(TopCmds.GETPAR("SPNAM6")) if p90sC == 0: p90sC = 1500000./MAS SP=SPname if SP == "gauss" : SP = "3pi2SINC.wtf" offs = float(TopCmds.GETPAR("SPOFFS 6")) index = TopCmds.INPUT_DIALOG("OFF-resonance 90 purge", "S6 soft 90", \ ["Duration","Offset","Pulse Name (3pi/2 Sinc)"],\ [str(p90sC),str(offs),SP],\ ["us","Hz",""],\ ["1","1","1"],\ ["Accept","Close"], ['a','c'], 10) p90sC=float(index[0]) offs=float(index[1]) SP=index[2] #TopCmds.MSG(str(p90sC)+' p90sC') AvgAmp=IntShape.Integrate(SP)/100. adjust=20*math.log10(p90C/p90sC/AvgAmp) TopCmds.MSG(str(adjust)+'adjust') Power=ampC-adjust #TopCmds.MSG(str(Power)) TopCmds.PUTPAR("PLdB 26",str('%3.2f' %Power)) TopCmds.PUTPAR("SPNAM6",SP) TopCmds.PUTPAR("SPOFFS 6",str('%8.2f' %offs)) TopCmds.PUTPAR("P 6",str('%3.2f' %p90sC))
def CP(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "Cross-Polarization Setup Help</p></font><br>"+\ "\n\nCalculate Amplitudes for CP Match Conditions\n"+\ "Hard pulse power, duration, and shapes are needed\n"+\ "\n"+\ "Arguments:\n"+\ "-dB : interact with db instead of watts (TS3+)\n"+\ "-qt : Quiet the initial Hard-pulse input\n"+\ "-help: This Window\n"+\ "\n"+\ "Adjusts amplitude for shaped pulses\n"+\ "Suggests an appropriate match condition for your MAS Rate\n"+\ "Suggests an appropriate decoupling field if warranted\n"+\ "\n"+\ "Path : "+str(root.UtilPath.getTopspinHome())+ "/exp/stan/nmr/py/BioPY/modules/Setup.py\n"+\ "modules: CalCP\n"+\ "wrappers:HC, HN, NCA, NCO, NH, CH, see also LG \n"+\ "\n"+\ "Faults:\n"+\ "May guess too low by one rotor frequency.\n"+\ "Failures:\n"+\ "Shape is not specified (dialog pops up) or does not exist.")
def DDec(units): Stuff = [] p90 = float(TopCmds.GETPAR("P 32")) amp = float(TopCmds.GETPAR("PLdB 31")) MaxB1 = 1000000. / 4. / p90 CPD = TopCmds.GETPAR2("CPDPRG 5") if CPD == "mlev" or CPD == "None": TopCmds.XCMD("cpdprg5") CPD = (TopCmds.GETPAR2("CPDPRG 5")) Stuff = CPDtools.CPDparse(CPD, "2D") TopCmds.MSG(str(Stuff)) amp0 = CPDtools.Find_old_pl(Stuff[0]) decpw0 = CPDtools.Find_old_pw(Stuff[1], "2D") B1_0 = MaxB1 * (math.pow(10, (amp - amp0) / 20.)) / 1000. if B1_0 > 1.: B1out = '% .1f' % B1_0 if B1_0 <= 1.: B1out = '5.0' index = TopCmds.INPUT_DIALOG("Mr Setup Input", "Decoupling Window", \ ["Desired 2H Decoupling Amplitude","File"],\ [B1out,CPD],["kHz",""],["1","1",],\ ["Accept","Close"], ['a','c'], 10) TopCmds.PUTPAR("CPDPRG 5", index[1]) adjust = 20 * (math.log10(1000. * float(index[0]) / MaxB1)) ampli = amp - adjust decpw = (MaxB1 / 1000. / float(index[0])) * 2 * p90 if units == "W": ampli = dBtoW(ampli) value = TopCmds.SELECT("Adjusting the D decoupling parameters:",\ "This will set\n 2H power ("+ Stuff[0] +") to: "+ str('%3.2f' %ampli)+" "+ units+"\n \ Pulse width (" + Stuff[1] +"= 180deg) to: " +str('%3.2f' %decpw) + " us",["Update", "Keep Previous"]) if value != 1: if Stuff[0] == '': TopCmds.PUTPAR("PL" + units + " 25", str('%3.2f' % ampli)) elif Stuff[0] == 'pl25': TopCmds.PUTPAR("PL" + units + " 25", str('%3.2f' % ampli)) elif Stuff[0] == 'pl12': TopCmds.MSG( "You are using pl12 for 2H decouling. It is usually reserved for 1H \n Please verify" ) #TopCmds.PUTPAR("PLdB 12",str('%3.2f' %ampli)) elif Stuff[0] == 'pl13': TopCmds.MSG( "You are using pl13 for 2H decouling. It is usually reserved for 1H \n Please verify" ) #TopCmds.PUTPAR("PLdB 13",str('%3.2f' %ampli)) elif Stuff[0] == 'pl14': TopCmds.MSG( "You are using pl14 for 2H decouling. It is usually reserved for 1H \n Please verify" ) #TopCmds.PUTPAR("PLdB 14",str('%3.2f' %ampli)) if Stuff[1] == 'pcpd': TopCmds.PUTPAR("PCPD 5", str('%3.2f' % decpw)) elif Stuff[1] == 'p31': TopCmds.PUTPAR("P 31", str('%3.2f' % decpw)) TopCmds.PUTPAR("P 30", str('%3.2f' % decpw)) elif Stuff[1] == 'p62': TopCmds.PUTPAR("P 61", str('%3.2f' % decpw)) TopCmds.PUTPAR("P 62", str('%3.2f' % decpw))
def CMatch(): #Nuc is a string such as 1H or 13C Nucs=NUC.list() for i in range(len(Nucs)): if Nucs[i]=='13C':Frq=fq.fq(Nucs[i],i+1) p90 =pul.GetPar('pC90',"") MAS =pul.GetPar('MAS',"") NomRF = 1000000./4./p90 nomatch=[] Af=[] Bf=[] Ap=[] Bp=[] Condition=[] mfaa=[] #message=[] aa, Ap, Bp = Nucl() hits=0 mm=1 SPOFF=pul.GetPar('oCdrm',"")-Frq.offs #TopCmds.MSG(str(SPOFF)) for i in range(len(aa)): Af.append(Frq.ppm2offs(Ap[i])-SPOFF) Bf.append(Frq.ppm2offs(Bp[i])-SPOFF) m=1 Match=m*MAS-math.fabs(Af[i])-(math.fabs(Bf[i])) #if Match < 0 : # m=2; mm=2 # Match=m*MAS-(math.fabs(Af[i]))-(math.fabs(Bf[i])) if Match < 0: nomatch.append(aa[i]) if Match >= 0: hits=hits+1 if len(nomatch) > 0 : TopCmds.MSG("Cannot find match conditions for:\n "\ + str(nomatch)+ "\n at this carrier or spinning frequency") if hits == 0: TopCmds.MSG("Cannot find any match conditions, please consider changing frequencies") TopCmds.EXIT() Upper=0 Lower=MAS*2 NotCount=len(nomatch) #Determine if we want to skip for i in range(len(aa)): skip=0 found=0 for j in range(NotCount): if nomatch[j] == aa[i]: skip=1 if not skip: for n in range(int(MAS*2)): if not found : WAeff = math.sqrt(Af[i]*Af[i]+float(n*n)) WBeff = math.sqrt(Bf[i]*Bf[i]+float(n*n)) Match=(mm*MAS)-WAeff-WBeff #mm is the match multiplier if Match <= 0.0: found=1 mfaa.append(aa[i]) Condition.append(n) if n > Upper : Upper=n if n < Lower : Lower=n if not found: nomatch.append(aa[i]) #Condition.append('N/A') #TopCmds.MSG(str(nomatch)) #TopCmds.MSG(aa[i]+ " " + str(Ap[i]) + " " +str(Bp[i]) + " " + str(Upper) + " " +str(Lower)) if len(nomatch) > 0 : TopCmds.MSG("Cannot find match conditions for:\n "\ + str(nomatch)+ "\n at this carrier or spinning frequency") # Report average, deviation and the extremes, # Offer a detailed report after a dialog. # These numbers are used to generate a wave file Avg=0.0 Dev=0.0 for i in range(len(Condition)): Avg=Avg+float(Condition[i]) Avg=Avg/float(len(Condition)) for i in range(len(Condition)): Dev=Dev+(float(Condition[i])-Avg)**2 Dev=math.sqrt(Dev/float(len(Condition)-1)) Continue=TopCmds.SELECT("Scaling",\ "The mean match is %.2f Hz" % Avg \ + " \n With a deviation of %.2f Hz" % Dev \ + "\n with a maximum at %i Hz " % Upper\ + "\n and a minimum at %i Hz " % Lower\ ,["Details","Proceed"]) #0,1 #TopCmds.MSG(str(SeeMore)) if not Continue: for i in range(int(math.ceil(len(mfaa)/20.))): message="Here is set #"+str(i+1)+" of the match conditions alphabetically by nucleus\n\n" for j in range(i*20,min((i+1)*20,len(mfaa))): message=message+str(mfaa[j])+": "+ str(Condition[j]) + "Hz\n " TopCmds.MSG(message) # Now I want to sort into order by increasing match for i in range(len(aa)): for j in range(len(aa)): if Condition[j] > Condition[i]: Condition[j], Condition[i] = Condition[i], Condition[j] mfaa[j], mfaa[i] = mfaa[i], mfaa[j] for i in range(int(math.ceil(len(mfaa)/20.))): message="Here is set #"+str(i+1)+" of the match conditions by match\n\n" for j in range(i*20,min((i+1)*20,len(mfaa))): message=message + str(Condition[j]) + " Hz : "+str(mfaa[j])+"\n " TopCmds.MSG(message) #TopCmds.MSG(str(NomRF)) # Finally I'm going to pass the result back # It is best to do this as a percentage to suggest a pulse shape. # I need a delta, beta, and scale. #TopCmds.MSG(str(Avg)) AvgPC =100.*Avg/NomRF DeltaPC=100.*(Upper-Lower)/NomRF BetaPC =100.*Dev/NomRF #return AvgPC, DeltaPC, BetaPC return Avg, Upper-Lower, Dev
def setPar(parName, value, unit) : TopSpinName = pulDict[parName] j=TopSpinName.find(" ") TopCmds.MSG(TopSpinName[:j]+unit+TopSpinName[j:],str(value))
def Dream(): TopCmds.MSG("<html><p style='text-align: center;'><font size=14><font color=\'0000FF\'>"+\ "DREAM Setup Help</p></font><br>"+\ "\n\nThere is nothing here")
def CMatch(): #Nuc is a string such as 1H or 13C Nucs = NUC.list() if Nucs[0] == "13C": Frq = fq.O1() elif Nucs[1] == "13C": Frq = fq.O2() elif Nucs[2] == "13C": Frq = fq.O3() p90 = float(TopCmds.GETPAR("P 1")) MAS = float(TopCmds.GETPAR("CNST 31")) NomRF = 1000000. / 4. / p90 nomatch = [] Af = [] Bf = [] Ap = [] Bp = [] Condition = [] mfaa = [] #message=[] # It should default to CA-CB matching for DREAM, and CA-CO for R2T # I'm not sure the best way to select these but I'm putting it in as a dialog aa, Ap, Bp = Nucl() #TopCmds.MSG(str(aa)) #TopCmds.MSG(str(Ap)) #TopCmds.MSG(str(Bp)) # Now we'll convert the ppm averages from above into frequencies hits = 0 mm = 1 SPOFF = float(TopCmds.GETPAR("SPOFFS 5")) for i in range(len(aa)): Af.append(SPOFF + Frq.ppm2offs(Ap[i])) Bf.append(SPOFF + Frq.ppm2offs(Bp[i])) # The offsets should be less than 1/2 (or 1*) the MAS frequency, or we can't match. # We will store a list for those aa's that we can't match. m = 1 Match = m * MAS - math.fabs(Af[i]) - (math.fabs(Bf[i])) if Match < 0: m = 2 mm = 2 Match = m * MAS - (math.fabs(Af[i])) - (math.fabs(Bf[i])) #TopCmds.MSG(str(Match)+" "+str(math.fabs(Af[i]))+" "+str(math.fabs(Bf[i]))) if Match < 0: nomatch.append(aa[i]) if Match >= 0: hits = hits + 1 #TopCmds.MSG(str(len(nomatch))) if len(nomatch) > 0: TopCmds.MSG("Cannot find match conditions for:\n "\ + str(nomatch)+ "\n at this carrier or spinning frequency") if hits == 0: TopCmds.MSG( "Cannot find any match conditions, please consider changing frequencies" ) TopCmds.EXIT() # Now, we want to determine the matches and store the results and extrema, # but not for things we know can't be matched Upper = 0 Lower = MAS * 2 NotCount = len(nomatch) #Determine if we want to skip for i in range(len(aa)): skip = 0 found = 0 for j in range(NotCount): if nomatch[j] == aa[i]: skip = 1 if not skip: for n in range(MAS * 2): if not found: WAeff = math.sqrt(Af[i] * Af[i] + float(n * n)) WBeff = math.sqrt(Bf[i] * Bf[i] + float(n * n)) Match = (mm * MAS) - WAeff - WBeff #mm is the match multiplier if Match <= 0.0: found = 1 mfaa.append(aa[i]) Condition.append(n) if n > Upper: Upper = n if n < Lower: Lower = n if not found: nomatch.append(aa[i]) #Condition.append('N/A') #TopCmds.MSG(str(nomatch)) #TopCmds.MSG(aa[i]+ " " + str(Ap[i]) + " " +str(Bp[i]) + " " + str(Upper) + " " +str(Lower)) if len(nomatch) > 0: TopCmds.MSG("Cannot find match conditions for:\n "\ + str(nomatch)+ "\n at this carrier or spinning frequency") # Now I want to report what we've found. I'll start with an average, deviation and the extremes, # And offer a detailed report after a dialog. # I guess these numbers could be used to generate a wave file Avg = 0.0 Dev = 0.0 for i in range(len(Condition)): Avg = Avg + float(Condition[i]) Avg = Avg / float(len(Condition)) for i in range(len(Condition)): Dev = Dev + (float(Condition[i]) - Avg)**2 Dev = math.sqrt(Dev / float(len(Condition) - 1)) #TopCmds.MSG("DEV(DONE): " + str(Dev)) #TopCmds.MSG(str(Avg)+":Average \n"+str(Dev) +":StDev") Continue=TopCmds.SELECT("Scaling",\ "The mean match is %.2f Hz" % Avg \ + " \n With a deviation of %.2f Hz" % Dev \ + "\n with a maximum at %i Hz " % Upper\ + "\n and a minimum at %i Hz " % Lower\ ,["Details","Proceed"]) #0,1 #TopCmds.MSG(str(SeeMore)) if not Continue: for i in range(math.ceil(len(mfaa) / 20.)): message = "Here is set #" + str( i + 1) + " of the match conditions alphabetically by nucleus\n\n" for j in range(i * 20, min((i + 1) * 20, len(mfaa))): message = message + str(mfaa[j]) + ": " + str( Condition[j]) + "Hz\n " TopCmds.MSG(message) # Now I want to sort into order by increasing match for i in range(len(aa)): for j in range(len(aa)): if Condition[j] > Condition[i]: Condition[j], Condition[i] = Condition[i], Condition[j] mfaa[j], mfaa[i] = mfaa[i], mfaa[j] for i in range(math.ceil(len(mfaa) / 20.)): message = "Here is set #" + str( i + 1) + " of the match conditions by match\n\n" for j in range(i * 20, min((i + 1) * 20, len(mfaa))): message = message + str(Condition[j]) + " Hz : " + str( mfaa[j]) + "\n " TopCmds.MSG(message) #TopCmds.MSG(str(NomRF)) # Finally I'm going to pass the result back # It is best to do this as a percentage to suggest a pulse shape. # I need a delta, beta, and scale. #TopCmds.MSG(str(Avg)) AvgPC = 100. * Avg / NomRF DeltaPC = 100. * (Upper - Lower) / NomRF BetaPC = 100. * Dev / NomRF return AvgPC, DeltaPC, BetaPC
def DecError(PL, Nuc): TopCmds.MSG( "You are using " + PL + " for " + Nuc + " decouling.\n It is usually reserved for 1H \n Please verify")
def HDec(units): Stuff = [] p90 = pul.GetPar('pH90', "") amp = pul.GetPar('aH', units) CPD = pul.GetPar('prgHDec', "") MaxB1 = 1000000. / 4. / p90 if CPD == "mlev" or CPD == "None": pul.SetPar('prgHDec', "tppm15", "") TopCmds.XCMD(pul.xcmd_name(pul.pulDict['prgHDec'])) CPD = pul.GetPar('prgHDec', "") TopCmds.MSG(str(CPD) + " CPD") Stuff = CPDtools.CPDparse(CPD, "1H") TopCmds.MSG(str(Stuff) + " Stuff") amp0 = CPDtools.Find_old_pl(Stuff[0], units) TopCmds.MSG(str(amp0) + " amp0") if units == "W": amp = WtodB(amp) amp0 = WtodB(amp0) decpw0 = CPDtools.Find_old_pw(Stuff[1], "1H") B1_0 = MaxB1 * (math.pow(10, (amp - amp0) / 20.)) / 1000. if B1_0 > 1.: B1out = '% .1f' % B1_0 if B1_0 > MaxB1 / 1000.: B1out = '75.0' if B1_0 <= 1.: B1out = '75.0' index = TopCmds.INPUT_DIALOG("Mr Setup Input", "Decoupling Window", \ ["Desired 1H Decoupling Amplitude","File"],\ [B1out,CPD],["kHz",""],["1","1",],\ ["Accept","Close"], ['a','c'], 10) pul.SetPar('prgHDec', index[1], "") adjust = 20 * (math.log10(1000. * float(index[0]) / MaxB1)) Hamp = amp - adjust decpwH = (MaxB1 / 1000. / float(index[0])) * (170. / 180.) * 2 * p90 if units == "W": Hamp = dBtoW(Hamp) value = TopCmds.SELECT("Adjusting the H decoupling parameters:",\ "This will set\n 1H power ("+ Stuff[0] +") to: "+ str('%.2f' %Hamp)+" "+ units+"\n \ Pulse width (" + Stuff[1] +") to: " +str('%3.2f' %decpwH)+" us",["Update", "Keep Previous"]) if value != 1: pl = "" if Stuff[0] != "": pl = pul.pp_2_xcmd(Stuff[0], "") if pl == pul.pulDict['aHdec']: pul.SetPar('aHdec', Hamp, units) elif pl == pul.pulDict['aHdec2']: pul.SetPar('aHdec2', Hamp, units) elif pl == pul.pulDict['aHdec3']: pul.SetPar('aHdec3', Hamp, units) if Stuff[1] == 'pcpd': pul.SetPar("PCPD 2", decpwH, "") elif Stuff[1] == 'p31': pul.SetPar("P31", decpwH, "") pul.SetPar("P30", decpwH, "") elif Stuff[1] == 'p62': pul.SetPar("P61", decpwH, "") pul.SetPar("P62", decpwH, "")
def PPDIM(): ppdim = 1 aqseq = "" ph2D = "" ph3D = "" ph4D = "" Nucl1D = "" Nucl2D = "" Nucl3D = "" Nucl4D = "" #Acquisition dimension from acq file Nucl1D = "".join(letter for letter in Nuc.list()[0] if letter.isalpha()) #TopCmds.MSG(Nucl1D) pp = TopCmds.GETPAR("PULPROG") dir = get_dir("PP_DIRS") Name = find_file(dir, pp) #TopCmds.MSG(Name) if os.path.exists(Name) == 1: f = open(Name, 'r') text = f.readlines() f.close() else: TopCmds.MSG("Pulse Program not found: Exiting") TopCmds.EXIT() # Determine pulse sequence dimension and TPPI phases for line in text: lines = line.rstrip() if lines.find("aqseq") >= 0: #Check for comments if lines.find(";") < 0: aqseq = "".join(letter for letter in lines if letter.isdigit()) elif lines.find(";") > lines.find("aqseq"): aqseq = "".join(letter for letter in lines if letter.isdigit()) if lines.find("F1PH") >= 0 or lines.find("F1EA") >= 0: if lines.find("F1PH") >= 0: search = "F1PH" if lines.find("F1EA") >= 0: search = "F1EA" #Check for comments if lines.find(";") < 0: if ppdim < 2: ppdim = 2 ph2D = find_phase(lines, search) ph2Dp = ph2D + ")" ph2D = ph2D + " " elif lines.find(";") > lines.find(search): if ppdim < 2: ppdim = 2 ph2D = find_phase(lines, search) ph2Dp = ph2D + ")" ph2D = ph2D + " " if lines.find("F1QF") >= 0: #Check for comments if lines.find(";") < 0: if ppdim < 2: ppdim = 2 Nucl2D = "_" elif lines.find(";") > lines.find("F1QF"): if ppdim < 2: ppdim = 2 Nucl2D = "_" if lines.find("F2PH") >= 0 or lines.find("F2EA") >= 0: if lines.find("F2PH") >= 0: search = "F2PH" if lines.find("F2EA") >= 0: search = "F2EA" #Check for comments if lines.find(";") < 0: if ppdim < 3: ppdim = 3 ph3D = find_phase(lines, search) ph3Dp = ph3D + ")" ph3D = ph3D + " " elif lines.find(";") > lines.find(search): if ppdim < 3: ppdim = 3 ph3D = find_phase(lines, search) ph3Dp = ph3D + ")" ph3D = ph3D + " " if lines.find("F2QF") >= 0: #Check for comments if lines.find(";") < 0: if ppdim < 3: ppdim = 3 Nucl3D = "_" elif lines.find(";") > lines.find("F2QF"): if ppdim < 3: ppdim = 3 Nucl3D = "_" if lines.find("F3PH") >= 0 or lines.find("F3EA") >= 0: if lines.find("F3PH") >= 0: search = "F3PH" if lines.find("F3EA") >= 0: search = "F3EA" #Check for comments if lines.find(";") < 0: if ppdim < 4: ppdim = 4 ph4D = find_phase(lines, search) ph4Dp = ph4D + ")" ph4D = ph4D + " " elif lines.find(";") > lines.find("F3PH"): if ppdim < 4: ppdim = 4 ph4D = find_phase(lines, search) ph4Dp = ph4D + ")" ph4D = ph4D + " " if lines.find("F3QF") >= 0: #Check for comments if lines.find(";") < 0: if ppdim < 4: ppdim = 4 Nucl4D = "_" elif lines.find(";") > lines.find("F3QF"): if ppdim < 4: ppdim = 4 Nucl4D = "_" #TopCmds.MSG(ph2D+":2D\n"+ph3D+": 3D\n"+ph4D+": 4D") #TopCmds.MSG(str(ppdim)+" ppdim\n"+str(ph2D)+" ph2D") # From TPPI phases make a string corresponding to pulse nucleus for line in text: lines = line.rstrip() if ppdim >= 2: if lines.find(ph2D) >= 0 and Nucl2D == "": #TopCmds.MSG(lines) Nucl2D = find_nuc(lines, ph2D) #TopCmds.MSG(Nucl2D) elif lines.find(ph2Dp) >= 0 and Nucl2D == "": #TopCmds.MSG(lines) Nucl2D = find_nuc(lines, ph2Dp) #TopCmds.MSG(Nucl2D) if ppdim >= 3: if lines.find(ph3D) >= 0 and Nucl3D == "": #TopCmds.MSG(lines) Nucl3D = find_nuc(lines, ph3D) #TopCmds.MSG(Nucl3D) elif lines.find(ph3Dp) >= 0 and Nucl3D == "": #TopCmds.MSG(lines) Nucl3D = find_nuc(lines, ph3Dp) #TopCmds.MSG(Nucl3D) if ppdim >= 4: if lines.find(ph4D) >= 0 and Nucl4D == "": #TopCmds.MSG(lines) Nucl4D = find_nuc(lines, ph4D) elif lines.find(ph4Dp) >= 0 and Nucl4D == "": #TopCmds.MSG(lines) Nucl4D = find_nuc(lines, ph4Dp) #TopCmds.MSG(str(ppdim)+" :ppdim\n"+Nucl2D+" :Nucl2D\n"+Nucl3D+" :Nucl3D\n"+Nucl4D+" :Nucl4D\n") # Translate, Concatenate and return the Nucls if ppdim >= 4 and Nucl4D.isdigit(): Nucl4D = "".join(letter for letter in Nuc.list()[int(Nucl4D) - 1] if letter.isalpha()) if ppdim >= 3 and Nucl3D.isdigit(): Nucl3D = "".join(letter for letter in Nuc.list()[int(Nucl3D) - 1] if letter.isalpha()) if ppdim >= 2 and Nucl2D.isdigit(): Nucl2D = "".join(letter for letter in Nuc.list()[int(Nucl2D) - 1] if letter.isalpha()) #TopCmds.MSG(Nucl1D+" :Nucl1D\n"+Nucl2D+" :Nucl2D\n"+Nucl3D+" :Nucl3D\n"+Nucl4D+" :Nucl4D\n") if ppdim == 4: EXP = Nucl4D + Nucl3D + Nucl2D aqseq = "4321" if ppdim == 3: if aqseq == "321": EXP = Nucl3D + Nucl2D if aqseq == "312": EXP = Nucl2D + Nucl3D if aqseq == "": EXP = Nucl3D + Nucl2D aqseq = "321" if ppdim == 2: EXP = Nucl2D aqseq = "21" return ppdim, aqseq, Nucl1D + EXP
def CalcSym(CorR, N, n, v, mult, p90, amp, Wave, time, dfltT, nuc, dec, units): """ CorR : Symmetry Element N : Step Number n : Space Winding Number v : Spin Winding Number (not used here, yet) mult : Mulitplier for Composite Pulses p90 : Dict key for Hard Pulse of Nucleus amp : Dict key for recoupling Amplitude Wave : Shaped pulse (None or Unused) nuc : Recoupled Nucleus dec : Dict key for Decoupler Nucleus dfltT : Default Time or Loop """ value = 0 if pul.pulDict[time].find("D") >= 0: lblT = "Delay", "s" elif pul.pulDict[time].find("L") >= 0: lblT = "Loop", "cycles" elif pul.pulDict[time].find("P") >= 0: lblT = "Pulse", "us" #Use Dictionary Definitions to find hard pulse powers if p90.find('H') >= 0: Amp = pul.GetPar('aH', "dB") if p90.find('C') >= 0: Amp = pul.GetPar('aC', "dB") if p90.find('N') >= 0: Amp = pul.GetPar('aN', "dB") #Assume 1H decoupling if neccessary P90 = pul.GetPar(p90, "") P90D = pul.GetPar('pH90', "") MAS = pul.GetPar('MAS', "") Tau_r = 1. / float(MAS) MaxB1 = 1000000. / 4. / P90 MaxB1D = 1000000. / 4. / P90D #Calculate the RF field if CorR == "C": Cond = mult * 1. * N * MAS / n if CorR == "R": Cond = mult * 2. * N * MAS / n #Set Decoupler if Appropriate if dec != "None": AmpD = pul.GetPar('aH', "dB") AmpD0 = pul.GetPar(dec, "dB") B1_0 = MaxB1D * (math.pow(10, (AmpD - AmpD0) / 20.)) if B1_0 > 100.: Dcond = B1_0 if B1_0 > MaxB1D: Dcond = 85000.0 if B1_0 <= 100.: Dcond = 85000.0 if Cond > MaxB1: TopCmds.MSG("The match condition for " + CorR+str(N)+unb+str(n)+crt+str(v)+" is "+\ str('%.3f' %(Cond/1000.))+" kHz \n\nIt is greater than the Max B1 ("+ str('%.3f' %(MaxB1/1000.))+" kHz)\n\n"+\ pul.pulDict[amp]+" will NOT be set ") TopCmds.EXIT() else: if dec == "None": Title = "Adjusting " + nuc + " Power for Symmetry-Based Recoupling" Subtit = CorR + str(N) + unb + str(n) + crt + str( v) + "Symmetry Match" Label = [nuc + " Amplitude", lblT[0] + " " + pul.pulDict[time]] Values = [str('%.3f' % (Cond / 1000.)), str(dfltT)] Units = ["kHz", lblT[1]] Types = ["1", "1"] Buttons = ["Accept", "Cancel"] ShortCuts = [spc, ret] columns = 10 else: Title = "Adjusting " + nuc + " Power for Symmetry-Based Recoupling" Subtit = CorR + str(N) + unb + str(n) + crt + str( v) + " Symmetry Match" Label = [nuc+" Amplitude",lblT[0]+" "+pul.pulDict[time],\ "1H decoupling field"] temp1 = Cond / 1000. temp2 = Dcond / 1000. Values = [str('%.3f' % temp1), str(dfltT), str('%.3f' % temp2)] Units = ["kHz", lblT[1], "kHz"] Types = ["1", "1", "1"] Buttons = ["Accept", "Cancel"] ShortCuts = [spc, ret] columns = 10 index = TopCmds.INPUT_DIALOG(Title, Subtit, Label, Values, Units, Types, Buttons, ShortCuts, columns) if index == None: TopCmds.EXIT() if index != None: Cond = float(index[0]) * 1000. Time = str(index[1]) if dec != "None": #Safety Damp = DecSafely(1000. * float(index[2]), dec, MaxB1D, 150000., AmpD, units) #Calculate the power adjust = 20 * (math.log10(Cond / MaxB1)) Condition = Amp - adjust #Calculate the Integration if shaped pulses are used if Wave != "None" and Wave != "Unused": if pul.GetPar(Wave,"") == "gauss" or pul.GetPar(Wave,"") == "None" or \ pul.GetPar(Wave,"") == "" or pul.GetPar(Wave,"") == "0" : pul.SetPar(Wave, "square.100", "") TopCmds.XCMD(pul.xcmd_name(pul.pulDict[Wave])) SP = pul.GetPar(Wave, "") AvgAmp = IntShape.Integrate(SP) / 100. adjust = 20 * (math.log10(1. / AvgAmp)) Condition = Condition - adjust if units == "W": Condition = dBtoW(Condition) if dec != "None": Damp = dBtoW(Damp) if dec == "None": Confirm = nuc + " Power for " + CorR + str(N) + "_" + str( n) + "^" + str(v) + "Symmetry Match" Power ="Set\n "+ pul.pulDict[amp]+" to: "+str('%3.2f' %Condition)+" "+ units+"\n"+\ pul.pulDict[time]+" "+lblT[1]+" to: "+index[1] else: Confirm = "Adjusting " + nuc + " and 1H Power for " + CorR + str( N) + "_" + str(n) + "^" + str(v) + "Symmetry Match" Power ="Set\n "+ pul.pulDict[amp]+" to: "+str('%3.2f' %Condition)+" "+ units+"\n"+\ pul.pulDict[dec]+" (Dec) power to: "+str('%3.2f' %Damp)+" "+ units+"\n"+\ pul.pulDict[time]+" "+lblT[1]+" to: "+index[1] if Confirm == "None": value = 1 else: value = TopCmds.SELECT(Confirm, Power, ["Update", "Keep Previous"], [spc, ret]) if value != 1: pul.SetPar(amp, Condition, units) pul.SetPar(time, index[1], "") if dec != "None": pul.SetPar(dec, Damp, units)