# -*- coding: iso-8859-1 -*- from numpy import * from scipy.signal import * from scipy.optimize import * from os import path, rename def result(): measurement = MeasurementResult('Magnetization') suffix = '' # output file name's suffix and... counter = 1 # counter for arrayed experiments var_key = '' # variable parameter name # loop over the incoming results: for timesignal in results: if not isinstance(timesignal,ADC_Result): continue # read experiment parameters: pars = timesignal.get_description_dictionary() # rotate timesignal acording to current receiver's phase: timesignal.phase(pars['rec_phase']) # provide timesignal to the display tab: data['Current scan'] = timesignal # accumulate... if not locals().get('accu'): accu = Accumulation() # skip dummy scans, if any: if pars['run'] < 0: continue # add up: accu += timesignal # provide accumulation to the display tab: data['Accumulation'] = accu # check how many scans are done: if accu.n == pars['NS']: # accumulation is complete # get number of echoes: num_echoes = pars['NECH'] # downsize accu to one point per echo: echodecay = accu + 0 echodecay.x = resize(echodecay.x, int(num_echoes)) echodecay.y[0] = resize(echodecay.y[0], int(num_echoes)) echodecay.y[1] = resize(echodecay.y[1], int(num_echoes)) # find where first echo exceeds noise: # if not locals().get('noise'): # last_echo = accu.get_accu_by_index(num_echoes-1) # first_echo = accu.get_accu_by_index(0) # noise = 3*std(last_echo.y[1][:]) # samples = first_echo.y[0] > noise if not locals().get('noise'): echo = accu.get_accu_by_index(0) noise = 0.1*max(abs(echo.y[0])) samples = abs(echo.y[0]) > noise # set echo times and intensities: for i in range(num_echoes): # get ith echo: echo = accu.get_accu_by_index(i) # set echo time: echodecay.x[i] = i*2*pars['TAU'] # set echo value: echodecay.y[0][i] = sum(echo.y[0][samples]) # the sum of echo points that exceed noise... echodecay.y[1][i] = sum(echo.y[1][samples]) #echodecay.y[0][i] = sum(echo.y[0]) # or the sum of all echo points... #echodecay.y[1][i] = sum(echo.y[1]) #echodecay.y[0][i] = echo.y[0][echo.x.size/2] # or a middle echo point #echodecay.y[1][i] = echo.y[1][echo.x.size/2] #echodecay.y[0][i] = max(echo.y[0]) # or maximum echo point #echodecay.y[1][i] = max(echo.y[1]) # compute a signal's phase: phi0 = arctan2(echodecay.y[1][0], echodecay.y[0][0]) * 180 / pi if not locals().get('ref'): ref = phi0 print 'phi0 = ', phi0 # rotate signal to maximize Re (optional): #echodecay.phase(-phi0) # provide echo decay to the display tab: data['Echo Decay'] = echodecay # check whether it is an arrayed experiment: var_key = pars.get('VAR_PAR') if var_key: # get variable parameter's value: var_value = pars.get(var_key) # provide signal recorded with different var_value's to the display tab: data['Accumulation'+"/"+var_key+"=%e"%(var_value)] = accu data['Echo Decay'+"/"+var_key+"=%e"%(var_value)] = echodecay # measure signal intensity vs. var_value: # [amplitude, rate] = fitfunc(echodecay.x, echodecay.y[0]) # print '%s%02g' % ('Amplitude = ', amplitude) # print '%s%02g' % ('T2 [s] = ', 1./rate) # measurand[var_value] = amplitude measurement[var_value] = sum(echodecay.y[0]) # provide measurement to the display tab: data[measurement.get_title()] = measurement # save accu if required: outfile = pars.get('OUTFILE') if outfile: datadir = pars.get('DATADIR') # write raw data in Simpson format: filename = datadir+outfile+suffix+'.dat' if path.exists(filename): rename(filename, datadir+'~'+outfile+suffix+'.dat') accu.write_to_simpson(filename) # write raw data in Tecmag format: # filename = datadir+outfile+'.tnt' # accu.write_to_tecmag(filename, nrecords=20) # write parameters in a text file: filename = datadir+outfile+suffix+'.par' if path.exists(filename): rename(filename, datadir+'~'+outfile+suffix+'.par') fileobject = open(filename, 'w') for key in sorted(pars.iterkeys()): if key=='run': continue if key=='rec_phase': continue fileobject.write('%s%s%s'%(key,'=', pars[key])) fileobject.write('\n') fileobject.close() # reset accumulation: del accu if var_key == 'D2': # mono-exponential decay fit: xdata = measurement.get_xdata() ydata = measurement.get_ydata() [amplitude, rate] = fitfunc(xdata, ydata) print '%s%02g' % ('Amplitude = ', amplitude) print '%s%02g' % ('T2 [s] = ', 1./rate) # update display for the fit: measurement.y = func([amplitude, rate], xdata) data[measurement.get_title()] = measurement # the fitting procedure: def fitfunc(xdata, ydata): # initialize variable parameters: try: # solve Az = b: A = array((ones(xdata.size/2), xdata[0:xdata.size/2])) b = log(abs(ydata[0:xdata.size/2])) z = linalg.lstsq(transpose(A), b) amplitude = exp(z[0][0]) rate = -z[0][1] print amplitude, 1./rate except: amplitude = abs(ydata[0]) rate = 1./(xdata[-1] - xdata[0]) p0 = [amplitude, rate] # run least-squares optimization: plsq = leastsq(residuals, p0, args=(xdata, ydata)) return plsq[0] # best-fit parameters def residuals(p, xdata, ydata): return ydata - func(p, xdata) # here is the function to fit: def func(p, xdata): return p[0]*exp(-p[1]*xdata) pass