# -*- coding: iso-8859-1 -*-

TXEnableDelay = 2e-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(): # drives four experiments in a row: saturation-recovery, solid echo, spin-alignment, and Zeeman-order

    # experiments on/off: 
    satrec2_flag = True     # toggle for saturation-recovery
    solidecho_flag = True   # toggle for solid-echo
    spinal_flag = True      # toggle for spin-alignment
    zeeman_flag = False     # toggle for Zeeman-order


# ------------------ Saturation-recovery experiment settings ----------------------
    
    if satrec2_flag == True:  
      # set up acquisition parameters:
        pars = {}
        pars['P90'] = 2.0e-6	# 90-degree pulse length (s)
        pars['SF'] = 46.7e6	# spectrometer frequency (Hz)
        pars['O1'] = -60e3	# offset from SF (Hz)
        pars['SW'] = 10e6	# spectral window (Hz)
        pars['SI'] = 1*512	# number of acquisition points
        pars['NS'] = 8		# number of scans
        pars['DS'] = 0		# number of dummy scans
        pars['TAU'] = 1		# delay for recovery (s)
        pars['D3'] = 20e-6	# echo delay (s)
        pars['D4'] = 0		# echo pre-aquisition delay (s)
        pars['PHA'] = 0		# receiver phase (degree)
         # -*- these ain't variable: -*-
        pars['NECH'] = 40       # number of saturation pulses
        pars['D1'] = 100e-3	# starting interval in saturation sequence (s) 
        pars['D2'] = 1e-4	# end interval in saturation sequence (s) 
        pars['DATADIR'] = '/home/fprak/Students/'	# data directory
        pars['OUTFILE'] = None			# output file name

      # specify a variable parameter (optional):
        pars['VAR_PAR'] = 'TAU'	# variable parameter name (a string)   
        start = 1e-3		# starting value
        stop = 1		# end value
        steps = 12		# number of values
        log_scale = True	# 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']%8 != 0:
            pars['NS'] = int(round(pars['NS'] / 8) + 1) * 8 
            print 'Number of scans changed to ',pars['NS'],' due to phase cycling'

        if pars['D1'] < pars['D2']:
            raise Exception("D1 must be greater than D2!")

        sat_length = sum(log_range(pars['D1'],pars['D2'],pars['NECH']))
        if sat_length > 1.:
            raise Exception("saturation sequence too long!!!")   

        # 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 == 'TAU':
                seconds = ((sat_length + pars['D3']*2) * steps + sum(array)) * (pars['NS'] + pars['DS'])
            elif var_key == 'D3':
                seconds = ((sat_length + pars['TAU']) * steps + sum(array)*2) * (pars['NS'] + pars['DS'])
            else:
                seconds = (sat_length + pars['TAU'] + pars['D3']*2) * steps * (pars['NS']+ pars['DS']) 
            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 saturation-recovery experiment for '+var_key+': run = '+str(index+1)+\
                                 ' out of '+str(array.size)+': value = '+str(pars[var_key])
                # loop for accumulation:
                for run in xrange(pars['NS']+pars['DS']):
                    yield satrec2_experiment(pars, run) 
                synchronize()
        else:
           # estimate the experiment time:
            seconds = (sat_length + pars['TAU'] + pars['D3']*2) * (pars['NS']+ pars['DS']) 
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            print '%s%02d:%02d:%02d' % ('Experiment time estimated: ', h, m, s)

            # loop for accumulation:
            for run in xrange(pars['NS']+pars['DS']):
                yield satrec2_experiment(pars, run)

# ------------------ Solid-echo experiment settings ----------------------
    
    if solidecho_flag == True: 
      # set up acquisition parameters:
        pars = {}
        pars['P90'] = 2.0e-6	# 90-degree pulse length (s)
        pars['SF'] = 46.7e6	# spectrometer frequency (Hz)
        pars['O1'] = -60e3 	# offset from SF (Hz)
        pars['SW'] = 500e3	# spectral window (Hz)
        pars['SI'] = 1*1024	# number of acquisition points
        pars['NS'] = 8		# number of scans
        pars['DS'] = 0		# number of dummy scans
        pars['RD'] = 1		# delay between scans (s)
        pars['TAU'] = 20e-6	# echo delay (s)
        pars['D4'] = 0e-6	# echo pre-acquisition delay (s)
        pars['PHA'] = 0 	# receiver phase (degree)
        pars['DATADIR'] = '/home/fprak/Students/'	# data directory
        pars['OUTFILE'] = None                  	# output file name

      # specify a variable parameter (optional):
        pars['VAR_PAR'] = None	# variable parameter name (a string)   
        start = 10e-6		# starting value
        stop = 30e-6		# end value
        steps = 5		# 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']%8 != 0:
            pars['NS'] = int(round(pars['NS'] / 8) + 1) * 8 
            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 == 'TAU':
                seconds = (sum(array)*2 + pars['RD'] * steps) * (pars['NS'] + pars['DS'])
            elif var_key == 'RD':
                seconds = (sum(array) + pars['TAU']*2 * steps) * (pars['NS'] + pars['DS'])
            else:
                seconds = (pars['TAU']*2 + pars['RD']) * steps * (pars['NS']+ pars['DS'])
            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 solid-echo experiment for '+var_key+': run = '+str(index+1)+\
                                 ' out of '+str(array.size)+': value = '+str(pars[var_key])
                # loop for accumulation:
                for run in xrange(pars['NS']+pars['DS']):
                    yield solidecho_experiment(pars, run)
                synchronize()
        else:
           # estimate the experiment time:
            seconds = (pars['TAU']*2 + pars['RD']) * (pars['NS']+ pars['DS'])
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            print '%s%02d:%02d:%02d' % ('Experiment time estimated: ', h, m, s)

            # loop for accumulation:
            for run in xrange(pars['NS']+pars['DS']):
                yield solidecho_experiment(pars, run)       


# ---------------- Spin-alignment experiment settings ------------------

    if spinal_flag == True:   
      # set up acquisition parameters:         
        pars = {}
        pars['P90'] = 2.0e-6	# 90-degree pulse length (s)
        pars['SF'] = 46.7e6	# spectrometer frequency (Hz)
        pars['O1'] = -60e3 	# offset from SF (Hz)
        pars['SW'] = 10e6    	# spectral window (Hz)
        pars['SI'] = 1*512  	# number of acquisition points
        pars['NS'] = 8		# number of scans
        pars['DS'] = 0		# number of dummy scans
        pars['RD'] = 1		# delay between scans (s)
        pars['D1'] = 30e-6	# delay after first pulse, or tp (s)
        pars['D2'] = 100e-6	# delay after second pulse, or tm (s)
        pars['PHA'] = -36	# receiver phase (degree)
        pars['DATADIR'] = '/home/fprak/Students/'	# data directory
        pars['OUTFILE'] = None			# output file name
    
      # specify a variable parameter (optional):
        pars['VAR_PAR'] = 'D2'	# variable parameter name (a string)   
        start = 30e-6		# starting value
        stop = 1e-3		# end value
        steps = 12		# number of values
        log_scale = True	# 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']%8 != 0:
            pars['NS'] = int(round(pars['NS'] / 8) + 1) * 8 
            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 == 'D1':
                seconds = (sum(array)*2 + (pars['D2'] + pars['RD']) * steps) * (pars['NS'] + pars['DS'])
            elif var_key == 'D2':
                seconds = (sum(array) + (pars['D1']*2 + pars['RD']) * steps) * (pars['NS'] + pars['DS'])
            elif var_key == 'RD':
                seconds = (sum(array) + (pars['D1']*2 + pars['D2']) * steps) * (pars['NS'] + pars['DS'])
            else:
                seconds = (pars['D1']*2 + pars['D2'] + pars['RD']) * steps * (pars['NS']+ pars['DS'])
            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 spin-alignment experiment for '+var_key+': run = '+str(index+1)+\
                                 ' out of '+str(array.size)+': value = '+str(pars[var_key])
                # loop for accumulation:
                for run in xrange(pars['NS']+pars['DS']):
                    yield spinal_experiment(pars, run)
                synchronize()

        else:
           # estimate the experiment time:
            seconds = (pars['D1']*2 + pars['D2'] + pars['RD']) * (pars['NS']+ pars['DS'])
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            print '%s%02d:%02d:%02d' % ('Experiment time estimated: ', h, m, s)

           # loop for accumulation:
            for run in xrange(pars['NS']+pars['DS']):
                yield spinal_experiment(pars, run)

# ------------------ Zeeman-order experiment settings ----------------------

    if zeeman_flag == True:
        # set up acquisition parameters:         
        pars = {}
        pars['P90'] = 2.0e-6	# 90-degree pulse length (s)
        pars['SF'] = 46.7e6 	# spectrometer frequency (Hz)
        pars['O1'] = -60e3	# offset from SF (Hz)
        pars['SW'] = 10e6	# spectral window (Hz)
        pars['SI'] = 1*512	# number of acquisition points
        pars['NS'] = 8		# number of scans
        pars['DS'] = 0		# number of dummy scans
        pars['RD'] = 1		# delay between scans (s)
        pars['D1'] = 30e-6	# delay after first pulse, or 'short tau' (s)
        pars['D2'] = 100e-6	# delay after second pulse, or 'long tau' (s)
        pars['PHA'] = 0 	# receiver phase (degree)
        pars['DATADIR'] = '/home/fprak/Students/'	# data directory
        pars['OUTFILE'] = None                  	# output file name

        # specify a variable parameter (optional):
        pars['VAR_PAR'] = 'D2'	# variable parameter name (a string)
        start = 30e-6		# starting value
        stop = 1e-3		# end value
        steps = 12		# number of values
        log_scale = True	# 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']%8 != 0:
            pars['NS'] = int(round(pars['NS'] / 8) + 1) * 8 
            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 == 'D1':
                seconds = (sum(array)*2 + (pars['D2'] + pars['RD']) * steps) * (pars['NS'] + pars['DS'])
            elif var_key == 'D2':
                seconds = (sum(array) + (pars['D1']*2 + pars['RD']) * steps) * (pars['NS'] + pars['DS'])
            elif var_key == 'RD':
                seconds = (sum(array) + (pars['D1']*2 + pars['D2']) * steps) * (pars['NS'] + pars['DS'])
            else:
                seconds = (pars['D1']*2 + pars['D2'] + pars['RD']) * steps * (pars['NS']+ pars['DS'])
            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 Zeeman-order experiment for '+var_key+': run = '+str(index+1)+\
                                 ' out of '+str(array.size)+': value = '+str(pars[var_key])
                # loop for accumulation:
                for run in xrange(pars['NS']+pars['DS']):
                    yield zeeman_experiment(pars, run) 
                synchronize()
        else:
            # estimate the experiment time:
            seconds = (pars['D1']*2 + pars['D2'] + pars['RD']) * (pars['NS']+ pars['DS'])
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            print '%s%02d:%02d:%02d' % ('Experiment time estimated: ', h, m, s)

            # loop for accumulation:
            for run in xrange(pars['NS']+pars['DS']):
                yield zeeman_experiment(pars, run)
			
# the pulse programs:

def satrec2_experiment(pars, run):
    e=Experiment()

    dummy_scans = pars.get('DS')
    if dummy_scans:
        run -= dummy_scans
    
    pars['PROG'] = 'satrec2_experiment'
    
    # phase lists:
    pars['PH1'] = [  0] 					# saturation pulses
    pars['PH3'] = [ 0, 180,   0, 180, 90, 270,  90, 270]	# 1st 90-degree pulse
    pars['PH4'] = [90,  90, 270, 270,  0,   0, 180, 180]	# 2nd 90-degree pulse
    pars['PH2'] = [ 0, 180,   0, 180, 90, 270,  90, 270]	# receiver

    # read in variables:
    P90 = pars['P90']
    SF =  pars['SF']
    O1 =  pars['O1']
    NECH = pars['NECH']
    D1 =  pars['D1']
    D2 =  pars['D2']
    D3 =  pars['D3']
    D4 =  pars['D4']
    TAU = pars['TAU']
    PH1 = pars['PH1'][run%len(pars['PH1'])]
    PH3 = pars['PH3'][run%len(pars['PH3'])]
    PH4 = pars['PH4'][run%len(pars['PH4'])]
    PH2 = pars['PH2'][run%len(pars['PH2'])]
    PHA = pars['PHA']

    # set variable delay list for saturation pulses: 
    vdlist = log_range(D2, D1, NECH-1)

    # set sampling parameters:
    SI = pars['SI']
    SW = pars['SW']
    while SW <= 10e6 and SI < 256*1024:
        SI *= 2
        SW *= 2

    # the pulse sequence: 

    # saturation:
    e.set_frequency(SF+O1, phase=PH1)			# set frequency and phase for saturation pulses
    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)	# enable RF amplifier
    e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue)	# apply 90-degree pulse
    for delay in vdlist[::-1]:
        e.wait(delay-P90-TXEnableDelay)			# wait for next saturation pulse
        e.ttl_pulse(TXEnableDelay, value=TXEnableValue)	# enable RF amplifier
        e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue) # apply 90-degree pulse

    # recovery:
    e.wait(TAU)						# wait for tau
    e.set_phase(PH3)					# set phase for next pulse
     
    # echo detection:
    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)	# enable RF amplifier
    e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue)	# apply 90-degree pulse
    e.wait(D3-P90/2-TXEnableDelay)			# echo delay
    e.set_phase(PH4)					# set phase for next pulse
    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)	# enable RF amplifier
    e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue)	# apply 90-degree pulse 
    e.set_phase(PHA)					# set phase for receiver
    e.wait(D3-P90/2+D4)					# echo delay    
    e.record(SI, SW, sensitivity=ADCSensitivity)	# acquisition

    # write experiment attributes:  
    for key in pars.keys():
        e.set_description(key, pars[key])	# pulse sequence parameters
    e.set_description('run', run)		# current scan
    e.set_description('rec_phase', -PH2)	# current receiver phase

    return e    
        

def solidecho_experiment(pars, run): 
    e=Experiment()

    dummy_scans = pars.get('DS')
    if dummy_scans:
        run -= dummy_scans

    pars['PROG'] = 'solidecho_experiment'

    # phase lists [from Tecmag's pulse sequence]:
    pars['PH1'] = [ 0, 180,   0, 180, 90, 270,  90, 270]	# 1st 90-degree pulse
    pars['PH3'] = [90,  90, 270, 270,  0,   0, 180, 180]	# 2nd 90-degree pulse
    pars['PH2'] = [ 0, 180,   0, 180, 90, 270,  90, 270]	# receiver


    # read in variables:
    P90 = pars['P90']
    SF = pars['SF']
    O1 = pars['O1'] 
    RD =  pars['RD']
    TAU = pars['TAU']
    D4 = pars['D4']
    PH1 = pars['PH1'][run%len(pars['PH1'])]
    PH3 = pars['PH3'][run%len(pars['PH3'])]
    PH2 = pars['PH2'][run%len(pars['PH2'])]
    PHA = pars['PHA']

    # set sampling parameters:
    SI = pars['SI']
    SW = pars['SW']
    while SW <= 10e6 and SI < 256*1024:
        SI *= 2
        SW *= 2

    # run the pulse sequence: 
    e.wait(RD)						# delay between scans
    e.set_frequency(SF+O1, phase=PH1)			# set frequency and phase for 1st RF pulse
    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)	# enable RF amplifier
    e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue)	# apply 1st 90-degree pulse
    e.wait(TAU-P90/2-TXEnableDelay)			# wait for TAU
    e.set_phase(PH3)					# set phase for 2nd 90-degree pulse
    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)	# enalble RF amplifier
    e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue)	# apply 2nd 90-degree pulse
    e.set_phase(PHA)					# set phase for receiver
    e.wait(TAU-P90/2+D4)				# wait for TAU       
    e.record(SI, SW, sensitivity=ADCSensitivity)	# acquire echo points

    # write the experiment parameters:  
    for key in pars.keys():
        e.set_description(key, pars[key])	# pulse sequence parameters
    e.set_description('run', run)		# current scan
    e.set_description('rec_phase', -PH2)	# current receiver phase

    return e
    
def spinal_experiment(pars, run):
    e=Experiment()

    dummy_scans = pars.get('DS')
    if dummy_scans:
        run -= dummy_scans
                       
    pars['PROG'] = 'spinal_experiment'                       
                       
   # 8-step phase cycle (1-14 modifided to deal with T1-recovery and extended for Re/Im imbalance)
    pars['PH1'] = [0, 270,   0, 270,     90,  90, 180, 180 ] # 1st (90-degree) pulse
    pars['PH3'] = [90,180,  90, 180,    180, 180,  90,  90 ] # 2nd (45-degree) pulse
    pars['PH4'] = [90, 90, 270, 270,    180,   0,   0, 180 ] # 3rd (45-degree) pulse
    pars['PH2'] = [0, 180, 180,   0,     90, 270,  90, 270 ] # receiver
        
   # read in variables:
    P90 = pars['P90']
    P45 = pars['P90']*0.5
    P1  = pars['P90']*0.5
    SF =  pars['SF']
    O1 =  pars['O1']    
    RD =  pars['RD']
    D1 =  pars['D1']
    D2 =  pars['D2']
    PH1 = pars['PH1'][run%len(pars['PH1'])]
    PH3 = pars['PH3'][run%len(pars['PH3'])]
    PH4 = pars['PH4'][run%len(pars['PH4'])]
    PH2 = pars['PH2'][run%len(pars['PH2'])]
    PHA = pars['PHA']

   # set sampling parameters:
    SI = pars['SI']
    SW = pars['SW']
    while SW <= 10e6 and SI < 256*1024:
        SI *= 2
        SW *= 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-degree pulse 

    e.wait(D1-P90/2-TXEnableDelay)			# 'short tau'
    e.set_phase(PH3)

    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)
    e.ttl_pulse(P45, value=TXEnableValue|TXPulseValue)	# 45-degree pulse 

    e.wait(D2-P45/2-TXEnableDelay)			# 'long tau'
    e.set_phase(PH4)

    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)
    e.ttl_pulse(P1, value=TXEnableValue|TXPulseValue)	# 45-degree pulse

    e.wait(TXEnableDelay)
    e.set_phase(PHA)
    e.wait(5e-6)#D1-P45/2-TXEnableDelay)    	                # 'short tau'
    e.record(SI, SW, 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

def zeeman_experiment(pars, run):
    e=Experiment()

    dummy_scans = pars.get('DS')
    if dummy_scans:
        run -= dummy_scans
        
    pars['PROG'] = 'zeeman_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 (90-degree) pulse
    pars['PH3'] = [0,  90,   0,  90,     0,  90,   0, 90] # 2nd (90-degree) pulse
    pars['PH4'] = [0,   0, 180, 180,   270, 270,  90, 90]  # 3rd (90-degree) pulse
    pars['PH2'] = [0, 180, 180,   0,    90, 270, 270, 90]  # receiver

   # read in variables:
    P90 = pars['P90']
    SF =  pars['SF']
    O1 =  pars['O1']    
    RD =  pars['RD']
    D1 =  pars['D1']
    D2 =  pars['D2']
    PH1 = pars['PH1'][run%len(pars['PH1'])]
    PH3 = pars['PH3'][run%len(pars['PH3'])]
    PH4 = pars['PH4'][run%len(pars['PH4'])]
    PH2 = pars['PH2'][run%len(pars['PH2'])]
    PHA = pars['PHA']

   # set sampling parameters:
    SI = pars['SI']
    SW = pars['SW']
    while SW <= 10e6 and SI < 256*1024:
        SI *= 2
        SW *= 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-degree pulse

    e.wait(D1-P90/2-TXEnableDelay)			# 'short tau'

    e.set_phase(PH3)
    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)
    e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue)	# 90-degree pulse 

    e.wait(D2-P90/2-TXEnableDelay)			# 'long tau'

    e.set_phase(PH4)
    e.ttl_pulse(TXEnableDelay, value=TXEnableValue)
    e.ttl_pulse(P90, value=TXEnableValue|TXPulseValue)	# 90-degree pulse

    e.wait(TXEnableDelay)
    e.set_phase(PHA)
    e.wait(D1-P90/2-TXEnableDelay)			# 'short tau'
    e.record(SI, SW, 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