def findPeaks(spec, numberOfPeaks, verbose=False): #{{{ """ DEPRECIATED! Find the position of the peaks and valleys of the EPR spectrum given the number of peaks to look for. The function returns the total peak to peak width of the spectrum, given more than one peak, as well as the center field and linewidth. args: spec - an nddata set of the EPR spectrum. The EPR spectrum should be the data and the field values should be placed in an axis named 'field' numberOfPeaks - an integer. The number of peaks to find, for nitroxide this should be 3. """ print "'findPeaks()' DEPRECIATED use 'findPeaksSequential()'" peaks = [] valleys = [] hrf = linspace( spec.getaxis('field').min(), spec.getaxis('field').max(), 10000) smash = spec.copy().interp('field', hrf).runcopy( real ) # use an interpolated higher res spec to get a more accurate esitmate of linewidth hrs = smash.copy() #smash -= average(spec.data) for i in range(numberOfPeaks): peak = smash.data.argmax() peaks.append(peak) valley = smash.data.argmin() valleys.append(valley) # remove from peak #find the high bound notCrossed = True count = 0 dimSize = len(smash.data) while notCrossed: if peak + count <= 0: lowBound = peak + count notCrossed = False else: if float(smash['field', peak + count].data) <= 0.0: lowBound = peak + count notCrossed = False count -= 1 # find the low bound notCrossed = True count = 0 while notCrossed: if peak + count >= dimSize: # check to make sure you haven't wandered off the spectrum highBound = peak + count notCrossed = False else: if float(smash['field', peak + count].data) <= 0.0: highBound = peak + count notCrossed = False count += 1 smash['field', lowBound:highBound] = 0.0 # remove from valley #find the high bound notCrossed = True count = 0 while notCrossed: if valley + count <= 0: lowBound = valley + count notCrossed = False else: if float(smash['field', valley + count].data) >= 0.0: lowBound = valley + count notCrossed = False count -= 1 # find the low bound notCrossed = True count = 0 while notCrossed: if valley + count >= dimSize: # check to make sure you haven't wandered off the spectrum highBound = valley + count notCrossed = False else: if float(smash['field', valley + count].data) >= 0.0: highBound = valley + count notCrossed = False count += 1 smash['field', lowBound:highBound] = 0.0 if verbose: pys.plot(smash) peak = pys.nddata(hrs.data[peaks]).rename('value', 'field').labels( 'field', hrs.getaxis('field')[peaks]) valley = pys.nddata(hrs.data[valleys]).rename('value', 'field').labels( 'field', hrs.getaxis('field')[valleys]) # Calculate relevant parameters peak.sort('field') valley.sort('field') return peak, valley
currAmp = currTable.getaxis('amp')[currIndex[0]] waveSlice = saveTable.data[currIndex] ampList.append(currAmp) # calculate new amplitude and phase values print currPhase phaseList.append(currPhase) foundWaveform.append(waveSlice) print "Loop took %0.2f seconds"%(time.time()-start) foundWaveform = pys.nddata(array(foundWaveform)).rename('value','t').labels('t',waveform.getaxis('t')) phaseList = array(phaseList) ampList = array(ampList) figure() pys.plot(foundWaveform.runcopy(real),'b.',alpha=0.3,label='located') pys.plot(foundWaveform.runcopy(real),'b--',alpha=0.3) pys.plot(waveform.runcopy(real),'bo',alpha=0.3,label='target') pys.plot(foundWaveform.runcopy(imag),'r.',alpha=0.3) pys.plot(foundWaveform.runcopy(imag),'r--',alpha=0.3) pys.plot(waveform.runcopy(imag),'ro',alpha=0.3) legend() # track phase and amplitude figure() pys.image(lookupTable) plot(phaseList,ampList,'g.',alpha=0.3,markersize=10) plot(phaseList,ampList,'k--',alpha=0.5) ylim(ampList.min(),ampList.max()) xlim(phaseList.min(),phaseList.max())
def workupCwEpr(eprName, spectralWidthMultiplier=1.25, numPeaks=3, EPRCalFile=False, firstFigure=[]): #{{{ EPR Workup stuff """ This is a beast of a function... Perform the epr baseline correction and double integration. Args: eprName - string - full name of the EPR file without the file extension. spectralWidthMultiplier - a multiplier to determine the integration width based on the width of the spectrum (difference between lowField and highField peak) numPeaks - the number of peaks of the spectrum EPRCalFile - a calibration file in csv format firstFigure - a figure list instance (see fornotebook) Returns: spec - nddata - the EPR spectra with other info set to the EPR params dict. lineWidths - list - the EPR linewidths spectralWidth - double - the EPR peak to peak spectral width centerField - double - the centerfield doubleIntZC - nddata - the double integral spectrum doubleIntC3 - nddata - the double integral spectrum with cubic baseline correction diValue - float - the double integral value spinConc - float - the spin concentration from the double integral. Must have an EPRCalFile amplitudes - array - amplitude of each peak in the spectrum """ firstFigure.append( {'print_string': r'\subparagraph{EPR Spectra %s}' % eprName + '\n\n'}) eprFileName = eprName.split('\\')[-1] # Pull the specs, Find peaks, valleys, and calculate things with the EPR spectrum.#{{{ spec, normalized = returnEPRSpec(eprName, resample=True) peak, valley = findPeaks(spec, numPeaks) lineWidths = valley.getaxis('field') - peak.getaxis('field') amplitudes = peak.data - valley.data spectralWidth = peak.getaxis('field').max() - peak.getaxis('field').min() # determine the center field if numPeaks == 2: centerField = (peak.getaxis('field')[0] + lineWidths[0] / 2. + peak.getaxis('field')[1] + lineWidths[1] / 2.) / 2. elif numPeaks == 3: centerField = peak.getaxis('field')[1] + lineWidths[1] / 2. specStart = centerField - spectralWidthMultiplier * spectralWidth specStop = centerField + spectralWidthMultiplier * spectralWidth print "\nI calculate the spectral width to be: ", spectralWidth, " G \n" print "I calculate the center field to be: ", centerField, " G \n" print "I set spectral bounds of: ", specStart, " and ", specStop, " G \n" #}}} if normalized == 'bad': print "The spectra is not normalized by the receiver gain" # Baseline correct the spectrum #{{{ baseline1 = spec['field', lambda x: x < specStart].copy() baseline2 = spec['field', lambda x: x > specStop].copy() specBase = array(list(baseline1.data) + list(baseline2.data)) fieldBase = array( list(baseline1.getaxis('field')) + list(baseline2.getaxis('field'))) specBase = pys.nddata(specBase).rename('value', 'field').labels('field', fieldBase) ### Calculate 0th, 1st, and 3rd order baselines baseline = average(specBase.data) spec.data -= baseline # zeroth order correct the spectrum # Plot the results firstFigure = pys.nextfigure(firstFigure, 'EPRSpectra') pys.plot(spec, 'm', alpha=0.6) pys.plot(peak, 'ro', markersize=10) pys.plot(valley, 'ro', markersize=10) pys.plot(spec['field', lambda x: logical_and(x > specStart, x < specStop)], 'b') pys.title('Integration Window') pys.ylabel('Spectral Intensity') pys.xlabel('Field (G)') pys.giveSpace(spaceVal=0.001) #}}} ### Take the first integral #{{{ absorption = spec.copy().integrate('field') #}}} # Fit the bounds of the absorption spec to a line and subtract from absorption spectrum.#{{{ baseline1 = absorption['field', lambda x: x < specStart] baseline2 = absorption['field', lambda x: x > specStop] fieldBaseline = array( list(baseline1.getaxis('field')) + list(baseline2.getaxis('field'))) baseline = pys.concat([baseline1, baseline2], 'field') baseline.labels('field', fieldBaseline) # Do the first order correction c1, fit1 = baseline.polyfit('field', order=1) fit1 = pys.nddata( array(c1[0] + absorption.getaxis('field') * c1[1])).rename( 'value', 'field').labels('field', absorption.getaxis('field')) correctedAbs1st = absorption.runcopy(real) - fit1.runcopy(real) c3, fit3 = baseline.polyfit('field', order=3) fit3 = pys.nddata( array(c3[0] + absorption.getaxis('field') * c3[1] + (absorption.getaxis('field')**2) * c3[2] + (absorption.getaxis('field')**3) * c3[3])).rename( 'value', 'field').labels('field', absorption.getaxis('field')) correctedAbs3rd = absorption.runcopy(real) - fit3.runcopy(real) #}}} # Set the values of absorption spec outside of int window to zero.#{{{ zeroCorr = correctedAbs1st.copy() zeroCorr['field', lambda x: x < specStart] = 0.0 zeroCorr['field', lambda x: x > specStop] = 0.0 #}}} # Plot absorption results#{{{ firstFigure = pys.nextfigure(firstFigure, 'Absorption') pys.plot(absorption, label='uncorrected') pys.plot(fit1, label='1st order fit') pys.plot(fit3, label='3rd order fit') pys.plot(correctedAbs1st, label='1st corr') pys.plot(correctedAbs3rd, label='3rd corr') pys.plot(zeroCorr, label='zero cut') pys.title('Absorption Spectrum') pys.ylabel('Absorptive Signal') pys.xlabel('Field (G)') pys.giveSpace(spaceVal=0.001) pys.legend() #}}} # Calculate and plot the double integral for the various corrections you've made #{{{ doubleInt = absorption.copy().integrate('field') doubleIntC1 = correctedAbs1st.copy().integrate('field') doubleIntC3 = correctedAbs3rd.copy().integrate('field') doubleIntZC = zeroCorr.copy().integrate('field') diValue = doubleIntC3.data.max() print "\nI calculate the double integral to be: %0.2f\n" % diValue firstFigure = pys.nextfigure(firstFigure, 'DoubleIntegral') pys.plot(doubleInt, label='uncorrected') pys.plot(doubleIntC1, label='1st corrected') pys.plot(doubleIntC3, label='3rd corrected') pys.plot(doubleIntZC, label='zero corrected') pys.legend(loc=2) pys.title('Double Integral Results') pys.ylabel('Second Integral (arb)') pys.xlabel('Field (G)') pys.giveSpace(spaceVal=0.001) #}}} # If the calibration file is present use that to calculate spin concentration#{{{ if normalized == 'good': if EPRCalFile: calib = calcSpinConc(EPRCalFile) ### Fit the series and calculate concentration c, fit = calib.polyfit('concentration') spinConc = (diValue - c[0]) / c[1] # Plotting firstFigure = pys.nextfigure(firstFigure, 'SpinConcentration') pys.plot(calib, 'r.', markersize=15) pys.plot(fit, 'g') pys.plot(spinConc, diValue, 'b.', markersize=20) pys.title('Estimated Spin Concentration') pys.xlabel('Spin Concentration') pys.ylabel('Double Integral') ax = pys.gca() ax.text(spinConc, diValue - (0.2 * diValue), '%0.2f uM' % spinConc, color='blue', fontsize=15) pys.giveSpace() else: spinConc = None #}}} return spec, lineWidths, spectralWidth, centerField, doubleIntZC, doubleIntC3, diValue, spinConc, amplitudes
tempThreshold+=0.01 ampVals,phaseVals = where(currTable.data<=tempThreshold) # find values in given range. phaseIndex = argmin(abs(phaseVals-currIndex[1])) # get index of phase and amp that is closest to previous value. ampIndex = argmin(abs(ampVals-currIndex[0])) currIndex = (ampVals[ampIndex],phaseVals[phaseIndex]) # reset the index ampList.append(lookupTable.getaxis('amp')[ampVals[ampIndex]]) # calculate new amplitude and phase values phaseList.append(lookupTable.getaxis('phase')[phaseVals[phaseIndex]]) foundWaveform.append(lookupTable.data[currIndex]) print "Loop took %0.2f seconds"%(time.time()-start) foundWaveform = pys.nddata(array(foundWaveform)).rename('value','t').labels('t',waveform.getaxis('t')) phaseList = array(phaseList) ampList = array(ampList) figure() pys.plot(foundWaveform) pys.plot(waveform) # track phase and amplitude figure() pys.image(lookupTable) plot(phaseList,ampList,'g.',markersize=10) plot(phaseList,ampList,'k--',alpha=0.5) ylim(ampList.min(),ampList.max()) xlim(phaseList.min(),phaseList.max()) xbandWave = pys.nddata(array(ampList)*exp(1j*array(phaseList)*pi/180)).rename('value','t').labels('t',waveform.getaxis('t')) figure() pys.plot(xbandWave,label='real') pys.plot(xbandWave.runcopy(imag),label='imag') legend()
modulation = pys.nddata(2*pi*(-freqWidth*timeAxis + rate/2*timeAxis**2)).rename('value','t').labels(['t'],[timeAxis]) # this is the frequency modulation chirp = pys.nddata(exp(1j*modulation.data)).rename('value','t').labels(['t'],[timeAxis]) planeWave = pys.nddata(exp(1j*2*pi*freqOffset*timeAxis)).rename('value','t').labels(['t'],[timeAxis]) #{{{ outputData = pullCsvData(outputDataFile,3) outputData = pys.nddata(outputData[:,0]+1j*outputData[:,1]).rename('value','digAmp').labels('digAmp',outputData[:,2]) # take only what we can use and set to full scale outputClean = outputData['digAmp',lambda x: logical_and(x>=dynamicRangeMin,x<=dynamicRangeMax)] # Clean up the amplitude outputAmp = outputClean.runcopy(abs) outputAmp.data -= outputAmp.data.min() outputAmp /= outputAmp.data.max() pys.figure() pys.plot(outputData.runcopy(abs)) pys.plot(outputAmp.runcopy(abs)) # calculate the phase roll at given amp, unwrap the roll so we can interpolate. outputClean.data = arctan2(outputClean.runcopy(imag).data,outputClean.runcopy(real).data) outputClean.data = unwrap(outputClean.data) pys.figure() pys.plot(outputClean,'r.') pys.title('phase roll')#}}} # amplitude modulation sinMod = pys.nddata(sin(pi/chirpLength*timeAxis)).rename('value','t').labels(['t'],[timeAxis]) # the corrected amplitude correctedDigAmp = nddata(interp(sinMod.data,outputAmp.data,outputAmp.getaxis('digAmp'))).rename('value','t').labels('t',timeAxis) # the phase roll for our amplitude input phaseRoll = nddata(interp(correctedDigAmp.data,outputClean.getaxis('digAmp'),outputClean.data)).rename('value','t').labels('t',timeAxis) pys.figure() pys.plot(phaseRoll)
collection = db.localDataRevisedDataLayout # This is my test collection#}}} dataSet = list(collection.find({'expName': '150529_CheYPep_N62C_5MUrea_ODNP'}))[0] epr = dtb.dictToNdData('cwEPR', dataSet) t1Data = dtb.dictToNdData('t1PowerODNP', dataSet) t1Data.sort('power') t1fits = dataSet.get('data').get('t1PowerODNP').get('fitList') powerArray = pys.r_[t1Data.getaxis('power').min():t1Data.getaxis('power').max( ):100j] t1Fit = pys.nddata(t1fits[0] + t1fits[1] * powerArray).rename( 'value', 'power').labels('power', powerArray) pys.figure() pys.plot(t1Data) pys.plot(t1Fit) kSigmaData = dtb.dictToNdData('kSigmaODNP', dataSet, retValue=False) powerArray = pys.r_[kSigmaData.getaxis('power').min():kSigmaData. getaxis('power').max():100j] ksFits = dataSet.get('data').get('kSigmaODNP').get('fitList') kSigmaFit = pys.nddata(ksFits[0] / (ksFits[1] + powerArray) * powerArray).rename('value', 'power').labels('power', powerArray) pys.figure() pys.plot(kSigmaData) pys.plot(kSigmaFit) pys.show()
centerField = peak.getaxis('field')[1] + lineWidths[1]/2.# assuming the center point comes out in the center. The way the code is built this should be robust specStart = centerField - spectralWidth specStop = centerField + spectralWidth print "\nI calculate the spectral width to be: ",spectralWidth," G \n" print "I calculate the center field to be: ",centerField," G \n" print "I set spectral bounds of: ", specStart," and ", specStop," G \n"#}}} # Baseline correct the spectrum #{{{ baseline1 = spec['field',lambda x: x < specStart].copy().mean('field') baseline2 = spec['field',lambda x: x > specStop].copy().mean('field') baseline = average(array([baseline1.data,baseline2.data])) spec.data -= baseline # Plot the results fl.figurelist = pys.nextfigure(fl.figurelist,'EPRSpectra') pys.plot(spec,'m',alpha=0.6) pys.plot(peak,'ro',markersize=10) pys.plot(valley,'ro',markersize=10) pys.plot(spec['field',lambda x: logical_and(x>specStart,x<specStop)],'b') pys.title('Integration Window') pys.ylabel('Spectral Intensity') pys.xlabel('Field (G)') pys.giveSpace(spaceVal=0.001) #}}} ### Take the first integral #{{{ absorption = spec.copy().integrate('field')#}}} # Fit the bounds of the absorption spec to a line and subtract from absorption spectrum.#{{{ baseline1 = absorption['field',lambda x: x < specStart] baseline2 = absorption['field',lambda x: x > specStop]
output = output['phase',0:2] else: output = saveOutput.copy() #start = 13822e-9-(len(ampArray)*100e-9) start = 1112e-9 width = 100e-9 bufferVal = 25e-9 # now calculate the phase and amplitude of each time increment. if reCalcData: data = pys.ndshape([len(ampArray),len(phaseArray)],['amp','phase']) data = data.alloc(dtype='complex') data.labels(['amp','phase'],[ampArray,phaseArray])#}}} expOutput = [] pys.figure() pys.plot(output['phase',0]) for countPhase,phase in enumerate(output.getaxis('phase')): print "Analyzing phase %i of %i"%(countPhase,len(output.getaxis('phase'))) for countAmp,amp in enumerate(ampArray): currSlice = output['phase',countPhase,'t',lambda x: logical_and(x > start + width*countAmp + bufferVal, x < start + width*(countAmp+1) - bufferVal)] data['amp',countAmp,'phase',countPhase] = currSlice.copy().mean('t').data if debug: pys.plot(currSlice,'r') pys.title('Pulse trace') pys.xlabel('time (us)') pys.ylabel('amplitude') pys.tight_layout() pys.savefig('pulseTrace.png') pys.figure()
currTable -= dataVal print "found edge case low bound is now %0.2f and high bound is %0.2f"%(lowBound,highBound) else: currTable = lookupTable['phase',lambda x: logical_and(x >= lowBound, x <= highBound)].copy() - dataVal currTable = currTable['amp',lambda x: logical_and(x>=ampLowBound,x<=ampHighBound)] phaseLowBounds.append(lowBound) phaseHighBounds.append(highBound) minimaIndex = unravel_index(argmin(currTable.runcopy(abs).data),shape(currTable.data)) amp = lookupTable.getaxis('amp')[minimaIndex[0]] phase = lookupTable.getaxis('phase')[minimaIndex[1]] locatedData.append(lookupTable.data[minimaIndex]) ampList.append(amp) phaseList.append(phase) print "Search loop for waveform took: ",time.time()-start print "Size of search table is: ",shape(currTable.data) pys.plot(array(phaseList),array(ampList),'o',markersize=5) pys.plot(array(phaseList),array(ampList),'--') locatedData = pys.nddata(array(locatedData)).rename('value','t').labels('t',waveform.getaxis('t')) interpolatedWaveform = pys.nddata(array(ampList)*exp(1j*(pi*array(phaseList)/180))).rename('value','t').labels('t',waveform.getaxis('t')) smoothedData = correctedData.copy().convolve('t',5e-9) ### Calculate the phase and amplitude jumps. phases = [] amps = [] for count in range(len(phaseList)-1): phases.append(phaseList[count]-phaseList[count+1]) amps.append(ampList[count]-ampList[count+1]) figure() plot(waveform.getaxis('t')[0:-1],array(phases),label='phaseDiff') plot(waveform.getaxis('t')[0:-1],array(amps),label='ampDiff') legend() title('Phase and amplitude Jumps')
import pymongo import matlablike as pys import nmrfit pys.close('all') MONGODB_URI = 'mongodb://*****:*****@ds047040.mongolab.com:47040/magresdata' # This is the address to the database hosted at MongoLab.com # Make the connection to the server as client conn = pymongo.MongoClient( MONGODB_URI) # Connect to the database that I purchased db = conn.magresdata collection = db.hanLabODNPTest # This is my test collection searchDict = { 'spinLabel': 'MTSL', 'osmolyte': 'None', 'osmolyteConcentration': 'None', 'macroMolecule': 'CheY', 'bindingPartner': 'P2' } #,'repeat':'0'}#,{'spinLabel':'MTSL','osmolyte':'urea','osmolyteConcentration':'5M','macroMolecule':'CheY','repeat':'0'}] listOfSets = list( collection.find(searchDict) ) # this gives me a list of dictionaries from the collection that satisfy the constraints imposed by my search dictionary. dataTag = 'kSigma' # This defines what data I pull from the database data = dtb.dictToNdData(dataTag, listOfSets[0], retValue=False) data = nmrfit.ksp(data) data.fit() pys.plot(data) pys.plot(data.eval(100)) pys.show()
currIndex = (currIndex[0],len(lookupTable.getaxis('phase'))-1) currTable = currTable['phase',currIndex[1]-maxIndexShift:currIndex[1]] minimaIndex = unravel_index(argmin(currTable.runcopy(abs).data),shape(currTable.data)) currIndex = (minimaIndex[0],minimaIndex[1]+(currIndex[1]-maxIndexShift)) # you cut the phase indecies by currIndex, now add it back ampList.append(lookupTable.getaxis('amp')[currIndex[0]]) # calculate new amplitude and phase values phaseList.append(lookupTable.getaxis('phase')[currIndex[1]]) foundWaveform.append(lookupTable.data[currIndex]) print "Loop took %0.2f seconds"%(time.time()-start) foundWaveform = pys.nddata(array(foundWaveform)).rename('value','t').labels('t',waveform.getaxis('t')) phaseList = array(phaseList) ampList = array(ampList) figure() pys.plot(foundWaveform) pys.plot(waveform) # track phase and amplitude figure() pys.image(lookupTable) plot(phaseList,ampList,'g.',markersize=10) plot(phaseList,ampList,'k--',alpha=0.5) ylim(ampList.min(),ampList.max()) xlim(phaseList.min(),phaseList.max()) xbandWave = pys.nddata(array(ampList)*exp(1j*array(phaseList)*pi/180)).rename('value','t').labels('t',waveform.getaxis('t')) if convolveOutput: toSynthesize=xbandWave.copy().convolve('t',timeResolution*2) else: toSynthesize=xbandWave.copy()
'value', 'time') # change the dimension label from the default 'value' to 'time' waveform.labels('time', x) # give the 'time' dimension labels # Note I could do this in one line as waveform = ps.nddata(y).rename('value','time').labels('time',x) # lets generate some error for the data set. error = np.random.random(len(y)) * 0.01 waveform.set_error( error ) # throw the error into the dataset. Note you can also assign error to a dimension by 'set_error('dimName',arrayOfError)' # plot the data ps.figure() ps.plot( waveform ) # note here plot is superloaded to handle nddata instead of the usual plot(x,y). Note this is a wrapper for the standard plot function and passes all arguements onto matplotlib. ps.title('My Initial Waveform') ################################################################################# ### Lets manipulate the data set now. ################################################################################# # make a copy of the data set pulse = waveform.copy() # make a square pulse by setting anything before 10s and after 20s to zero pulse['time', lambda x: x < 10.] = 0.0 pulse['time', lambda x: x > 20.] = 0.0 # plot the pulse ps.figure()