# -*- coding: iso-8859-1 -*- TXEnableDelay = 0.5e-6 TXEnableValue = 0b0001 # TTL line blanking RF amplifier (bit 0) TXPulseValue = 0b0010 # TTL line triggering RF pulses (bit 1) ADCSensitivity = 1 # voltage span for ADC def experiment(): # 2H Exchange Spectroscopy (2H EXSY) experiment [JMR 79, 269-290 (1988)] # Cosine and sine modulated signals are acquired sequentially by switching # between Zeeman order and spin-alignment phase lists. The signals are # processed into a pure absorption mode 2D spectrum according to scheme by # [Bluemich, Schmidt, and Spiess, JMR 79, 269-290 (1988)]. Prior to writing # in a file (Tecmag), the sine-modulated signal is rotated by 90°, thus # enabling 2D processing via a regular States algorithm with NMRnotebook # or like NMR software. # set up acquisition parameters: pars = {} pars['P90'] = 2.7e-6 # 90°-pulse length (s) pars['SF'] = 46.140e6 # spectrometer frequency (Hz) pars['O1'] = 1000 # offset from SF (Hz) pars['SW'] = 125e3 # spectral window (Hz) pars['SI1'] = 80 # number of (complex) data points in F1 (2nd dimension) pars['SI2'] = 1*256 # number of (complex) data points in F2 pars['D3'] = 10e-6 # position of refocusing 90°-pulse, Delta (s) pars['D4'] = 2e-6 # pre-aquisition delay (s) pars['D8'] = 3e-3 # mixing time, tm (s) pars['NS'] = 512 # number of scans pars['DS'] = 0 # number of dummy scans pars['RD'] = 0.2 # delay between scans (s) pars['PHA'] = 65 # receiver reference phase (degree) pars['DATADIR'] = '/home/mathilda/Desktop/Oleg/temp/' # data directory pars['OUTFILE'] = 'dso_320K' # output file name # specify a variable parameter (optional): pars['VAR_PAR'] = None # variable parameter's name (a string) start = 80 # starting value stop = 128 # end value steps = 2 # number of values log_scale = False # log scale flag stag_range = False # staggered range flag # check parameters for safety: if pars['PHA'] < 0: pars['PHA'] = 360 + pars['PHA'] if pars['P90'] > 20e-6: raise Exception("Pulse too long!!!") # check whether a variable parameter is named: var_key = pars.get('VAR_PAR') if var_key == 'P90' and (start > 20e-6 or stop > 20e-6): raise Exception("Pulse too long!!!") if pars['NS']%16 != 0: pars['NS'] = int(round(pars['NS'] / 32) + 1) * 32 print 'Number of scans changed to ', pars['NS'], ' due to phase cycling' # start the experiment: if var_key: # this is an arrayed experiment: if log_scale: array = log_range(start,stop,steps) else: array = lin_range(start,stop,steps) if stag_range: array = staggered_range(array, size = 2) # estimate the experiment time: if var_key == 'D8': seconds = (sum(array) + (.5*pars['SI1']/pars['SW'] + pars['RD']) * steps) * (pars['NS'] + pars['DS']) * 2*pars['SI1'] elif var_key == 'RD': seconds = (sum(array) + (.5*pars['SI1']/pars['SW'] + pars['D8']) * steps) * (pars['NS'] + pars['DS']) * 2*pars['SI1'] else: seconds = (.5*pars['SI1']/pars['SW'] + pars['D8'] + pars['RD']) * steps * (pars['NS']+ pars['DS']) * 2*pars['SI1'] m, s = divmod(seconds, 60) h, m = divmod(m, 60) print '%s%02d:%02d:%02d' % ('Experiment time estimated: ', h, m, s) # loop for a variable parameter: for index, pars[var_key] in enumerate(array): print 'Arrayed experiment for '+var_key+': run = '+str(index+1)+\ ' out of '+str(array.size)+': value = '+str(pars[var_key]) # loop for accumulation and sampling the indirect dimension F1: for run in xrange((pars['NS']+pars['DS'])*2*pars['SI1']): yield exsy2h_experiment(pars, run) synchronize() else: # estimate the experiment time: seconds = (.5*pars['SI1']/pars['SW'] + pars['D8'] + pars['RD']) * (pars['NS']+ pars['DS']) * 2*pars['SI1'] print 'sec ', seconds m, s = divmod(seconds, 60) h, m = divmod(m, 60) print '%s%02d:%02d:%02d' % ('Experiment time estimated: ', h, m, s) # loop for accumulation and sampling the indirect dimension F1: for run in xrange((pars['NS']+pars['DS'])*2*pars['SI1']): yield exsy2h_experiment(pars, run) # the pulse program: def exsy2h_experiment(pars, run): e=Experiment() dummy_scans = pars.get('DS') if dummy_scans: run -= dummy_scans pars['PROG'] = 'exsy2h_experiment' # 8-step phase cycle (1-21) modifided to deal with T1-recovery and extended for Re/Im imbalance) pars['PH1'] = [0, 270, 0, 270, 180, 90, 180, 90] # 1st pulse (90°) pars['PH3'] = [0, 90, 0, 90, 0, 90, 0, 90] # 2nd pulse (57.4°) pars['PH4'] = [0, 0, 180, 180, 270, 270, 90, 90] # 3rd pulse (57.4°) pars['PH5'] = [90, 90, 90, 90, 180, 180, 180, 180] # 4th pulse (90°) pars['PH2'] = [0, 180, 180, 0, 90, 270, 270, 90] # receiver # read in variables: P90 = pars['P90'] P1 = pars['P90']*(54.7/90) SF = pars['SF'] O1 = pars['O1'] RD = pars['RD'] D4 = pars['D4'] D8 = pars['D8'] D3 = pars['D3'] NS = pars['NS'] PH1 = pars['PH1'][run%len(pars['PH1'])] PH3 = pars['PH3'][run%len(pars['PH3'])] PH4 = pars['PH4'][run%len(pars['PH4'])] PH5 = pars['PH5'][run%len(pars['PH5'])] PH2 = pars['PH2'][run%len(pars['PH2'])] PHA = pars['PHA'] # this is a part of phase cycling: PH5 += (run/len(pars['PH5']))%2*180 PH1 += (run/len(pars['PH5']))%2*180 PH2 += (run/len(pars['PH5']))%2*180 # F1 sampling parameters: IN0 = 1./pars['SW'] # t1 increment # F1 sampling scheme: PH3+= (run/(1*NS))%4*90 # phases are upgraded after every NS scans PH4+= (run/(1*NS))%4*90 D0 = (run/(2*NS)) *IN0 # t1 is incremented after every 2*NS scans # F2 sampling parameters: SI2 = pars['SI2'] SW2 = pars['SW'] while SW2 <= 10e6 and SI2 < 256*1024: SI2 *= 2 SW2 *= 2 # run the pulse sequence: e.wait(RD) # relaxation delay between scans e.set_frequency(SF+O1, phase=PH1) e.ttl_pulse(TXEnableDelay, value=TXEnableValue) e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue) # 90°-pulse e.wait(D0) # incremented delay, t1 e.set_phase(PH3) e.ttl_pulse(TXEnableDelay, value=TXEnableValue) e.ttl_pulse(P1, value=TXEnableValue|TXPulseValue) # 54.7°-pulse e.wait(D8) # mixing time, tm e.set_phase(PH4) e.ttl_pulse(TXEnableDelay, value=TXEnableValue) e.ttl_pulse(P1, value=TXEnableValue|TXPulseValue) # 54.7°-pulse e.wait(D3) # refocusing delay, Delta e.set_phase(PH5) e.ttl_pulse(TXEnableDelay, value=TXEnableValue) e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue) # 90°-pulse e.wait(TXEnableDelay) e.set_phase(PHA) e.wait(D3+D4) # pre-aquisition delay e.record(SI2, SW2, sensitivity=ADCSensitivity) # acquisition # write experiment parameters: for key in pars.keys(): e.set_description(key, pars[key]) # acquisition parameters e.set_description('run', run) # current scan e.set_description('rec_phase', -PH2) # current receiver phase return e