# -*- 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') measurement_range = [0.0, 10e-6] measurement_ranging = False 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() # ---------------- digital filter ------------------ # get actual sampling rate of timesignal: sampling_rate = timesignal.get_sampling_rate() # get user-defined spectrum width: spec_width = pars['SW'] # specify cutoff frequency, in relative units: cutoff = spec_width / sampling_rate if cutoff < 1: # no filter applied otherwise # number of filter's coefficients: numtaps = 29 # use firwin to create a lowpass FIR filter: fir_coeff = firwin(numtaps, cutoff) # downsize x according to user-defined spectral window: skip = int(sampling_rate / spec_width) timesignal.x = timesignal.x[::skip] for i in range(2): # apply the filter to ith channel: timesignal.y[i] = lfilter(fir_coeff, 1.0, timesignal.y[i]) # zeroize first N-1 "corrupted" samples: timesignal.y[i][:numtaps-1] = 0.0 # circular left shift of y: timesignal.y[i] = roll(timesignal.y[i], -(numtaps-1)) # downsize y to user-defined number of samples (SI): timesignal.y[i] = timesignal.y[i][::skip] # update the sampling_rate attribute of the signal's: timesignal.set_sampling_rate(spec_width) # ---------------------------------------------------- # rotate timesignal according 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 # make a copy: echo = accu + 0 # compute the initial phase of FID: phi0 = arctan2(echo.y[1][0], echo.y[0][0]) * 180 / pi if not 'ref' in locals(): ref = phi0 print 'phi0 = ', phi0 # rotate FID to maximize y[0][0]: #echo.phase(-phi0) # do FFT: echo.exp_window(line_broadening=10) spectrum = echo.fft(samples=2*pars['SI']) # try zero-order phase correction: spectrum.phase(-phi0) # provide spectrum to the display tab: data['Spectrum'] = spectrum # 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 this var_value to the display tab: data['Accumulation'+"/"+var_key+"=%e"%(var_value)] = accu # measure signal intensity vs. var_value: if measurement_ranging == True: [start, stop] = accu.get_sampling_rate() * array(measurement_range) measurement[var_value] = sum(accu.y[0][int(start):int(stop)]) else: measurement[var_value] = sum(accu.y[0][0:31]) # provide measurement to the display tab: data[measurement.get_title()] = measurement # update the file name suffix: suffix = '_' + str(counter) counter += 1 # 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': # KWW fit: xdata = measurement.get_xdata() ydata = measurement.get_ydata() [amplitude, rate, beta] = fitfunc(xdata, ydata) print '%s%02g' % ('Amplitude = ', amplitude) print '%s%02g' % ('T2 [s] = ', 1./rate) print '%s%02g' % ('Beta = ', beta) # update display for the fit: measurement.y = func([amplitude, rate, beta], 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] except: amplitude = abs(ydata[0]) rate = 1./(xdata[-1] - xdata[0]) beta = 1 p0 = [amplitude, rate, beta] # 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)**p[2]) pass