def calculateFits(self): #{{{ """ Pulls the fit values saved along with the data set and draws the fit line. """ dataSet = list( self.collection.find({'expName': self.currentListSelection}))[0] # t1 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) # kSigma t1Fit.other_info = {'fitValues': t1fits} 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) try: eprData = dtb.dictToNdData('cwEPR', dataSet) except: eprData = False dataToPlot = { 'kSigma': kSigmaData, 'kSigmaFit': kSigmaFit, 't1Set': t1Data, 't1SetFit': t1Fit, 'cwEPR': eprData } self.dataDict.update({self.currentListSelection: dataToPlot})
def loadEPRFits(fileName): # {{{ """ Load in the fitting data that the multi component NLSL fitting program returns. """ fileHandle = open(fileName, 'r') lines = fileHandle.readlines() # find out how many data lists I need. numSets = len(lines[0].split('\r\n')[0].split('\t')) # the structure is C0 - field, C1 - data, C2 - fit result, C3 - weights, C4 - component 1, C5 - component 2, C6 and on are more components. numComps = numSets - 4 toStore = zeros((len(lines), numSets)) for count, line in enumerate(lines): line = line.split('\r\n')[0].split('\t') for count1, item in enumerate(line): toStore[count, count1] = item rawData = pys.nddata(toStore[:, 1]).rename('value', 'field').labels( 'field', toStore[:, 0]) fit = pys.nddata(toStore[:, 2]).rename('value', 'field').labels( 'field', toStore[:, 0]) components = {} for i in range(numComps): components.update({ '%i' % i: pys.nddata(toStore[:, i + 4]).rename('value', 'field').labels( 'field', toStore[:, 0]) }) return rawData, fit, components # }}}
def calcSpinConc(calibrationFile): #{{{ """ Use the EPR Double integral value to calculate the sample concentration given a calibration file. Format of the calibration file (csv). Concentration (uM) X Double Integral Value ConcVal DI Val Args: CalibrationFile - csv of calibration returns: calibration - the estimated concentration of the spin system """ openFile = open(calibrationFile, 'rt') lines = openFile.readlines() lines = lines[0].split('\r') lines.pop(0) concL = [] diL = [] for line in lines: conc, di = line.split(',') concL.append(float(conc)) diL.append(float(di)) openFile.close() calib = pys.nddata(pys.array(diL)).rename('value', 'concentration').labels( 'concentration', pys.array(concL)) return calib #}}}
def findPeaks(spec,numberOfPeaks): """ 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. """ peaks = [] valleys = [] smash = spec.copy() for i in range(numberOfPeaks): peak = smash.data.argmax() peaks.append(peak) valley = smash.data.argmin() valleys.append(valley) #find the high bound notCrossed=True count = 0 while notCrossed: if float(smash['field',peak+count].data) <= 0.0: lowBound = peak+count notCrossed = False count-=1 # find the low bound notCrossed=True counts=0 while notCrossed: if float(smash['field',valley+counts].data) >= 0.0: highBound = valley+counts notCrossed = False counts+=1 smash['field',lowBound:highBound] = 0.0 peak = pys.nddata(spec.data[peaks]).rename('value','field').labels('field',spec.getaxis('field')[peaks]) valley = pys.nddata(spec.data[valleys]).rename('value','field').labels('field',spec.getaxis('field')[valleys]) # Calculate relevant parameters peak.sort('field') valley.sort('field') return peak,valley
def calculateFits(self):#{{{ """ Calculate the fits to both the T1 set and the kSigma set """ dataSet = list(self.collection.find({'expName':self.currentListSelection}))[0] t1Data = dtb.dictToNdData('t1Power',dataSet) t1Data.sort('power') # weighted fit as function of power out = minimize(residualLinear, params, args=(t1Data.getaxis('power'), t1Data.runcopy(pys.real).data, t1Data.get_error())) t1Fit = pys.nddata(analyticLinear(out.params,t1Data.getaxis('power'))).rename('value','power').labels('power',t1Data.getaxis('power')) kSigmaData = dtb.dictToNdData('kSigma',dataSet,retValue = False) kSigmaData = nmrfit.ksp(kSigmaData) kSigmaData.fit() self.dataDict.update({self.currentListSelection:{'kSigma':kSigmaData,'t1Set':t1Data,'t1SetFit':t1Fit}})
def loadFTEseemTrace(fileName): #{{{ """ Opens the FT ESEEM trace that is saved in the PEPP Matlab processing program. returns an nddata with frequency dimension in MHz """ openFile = open(fileName, 'r+') lines = openFile.readlines() freq = [] signal = [] for line in lines: line = filter(None, line.split('\n')[0].split(' ')) freq.append(float(line[0])) signal.append(float(line[1])) signal = pys.nddata(array(signal)).rename('value', 'MHz').labels( 'MHz', array(freq)) signal = signal['MHz', lambda x: x >= 0.0] return signal #}}}
def retSeriesData(self): #{{{ """ This is going to pull the kSigma value, T1 zero power value, EPR DI value. If T10 is available it should also return T10, kRho, xi, and tau. To Do: 1) Write in ways to calculate each data set 2) Add a list of the experiment names to each data set. 3) This needs changed to the databasing scheme of pulling the nddata sets. 4) Also you should just save the fits to the database. """ kSigmaList = [] t1List = [] indepDimList = [] for count, value in enumerate(self.itemsToPlot): currentData = self.dataDict.get(unicode(value)) ### this needs to change to accomodate the new method of saving the fit values. kSigma = pys.nddata( pys.array([ currentData.get('kSigmaFit').other_info.get('fitVales')[0] ])).set_error( pys.array( [pys.sqrt(currentData.get('kSigma').covar(r'ksmax'))])) T1 = currentData.get('t1SetFit').copy().interp( 'power', pys.array([0.0])).set_error( pys.array([pys.average(currentData.get('t1Set').data)])) kSigmaList.append(kSigma) t1List.append(T1) dataSet = list(self.collection.find({'expName': unicode(value)}))[0] if self.seriesXDim == 'spinLabelSite': try: indepDim = float(dataSet.get(self.seriesXDim)[1:-1]) except: print "\n expNum has no spin label site" indepDim = 0.0 print indepDim elif self.seriesXDim == 'repeat': indepDim = float(dataSet.get(self.seriesXDim)) indepDimList.append(indepDim) self.kSigma = pys.concat(kSigmaList, 'value').rename( 'value', self.seriesXDim).labels(self.seriesXDim, pys.array(indepDimList)) self.t1 = pys.concat(t1List, 'power').rename( 'power', self.seriesXDim).labels(self.seriesXDim, pys.array(indepDimList)) #}}}
def returnEPRSpec(fileName,doNormalize = True): #{{{ """ Return the cw-EPR derivative spectrum from the spc and par files output by the winEPR program. If doNormalize is set to True (recommended) this will normalize the spectral values to the number of scans run as well as the receiver gain settings. This is a more reproducible value as is independent of the two settings which may vary. args: fileName - (sting) full file name not including extension. e.g. '/Users/StupidRobot/exp_data/ryan_cnsi/epr/150525_ConcentrationSeries/200uM_4OHT_14-7mm' returns: 1-D nddata dimensioned by field values of spectrum, and containing the EPR experimental parameters as other_info. """ # Open the spc and par files and pull the data and relevant parameters specData = fromfile(fileName+'.spc','<f') # read the spc openFile = open(fileName + '.par','r') # read the par lines = openFile.readlines() expDict = {} for line in lines[0].split('\r'): try: splitData = line.split(' ') key = splitData.pop(0) value = splitData.pop(0) for data in splitData: value += data expDict.update({key:value}) except: pass # calculate the field values and normalize by the number of scans and return an nddata centerSet = float(expDict.get('HCF')) sweepWidth = float(expDict.get('HSW')) resolution = float(expDict.get('RES')) fieldVals = pys.r_[centerSet-sweepWidth/2.:centerSet+sweepWidth/2.:resolution*1j] numScans = float(expDict.get('JNS')) # I'm not sure if this is right rg = float(expDict.get('RRG')) # normalize the data so there is coherence between different scans. if doNormalize: specData /= rg specData /= numScans spec = pys.nddata(specData).rename('value','field').labels('field',fieldVals) spec.other_info = expDict return spec #}}}
unBound=False boundTable = True ### Input Waveform chirpLength = 3e-6 timeResolution = 5e-9 convolveOutput=False timeAxis = pys.r_[0:chirpLength+timeResolution:timeResolution] freqOffset = 0e6 freqOffsetArray = pys.r_[-freqOffset:freqOffset: 1j] freqWidth = 5e6 #freqWidth /= 16. rate = 2*freqWidth/chirpLength # this is the phase modulation phaseModulation = 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*phaseModulation.data)).rename('value','t').labels(['t'],[timeAxis]) ampModulation = pys.nddata(sin(pi/chirpLength*timeAxis)).rename('value','t').labels('t',timeAxis) ### this goes in the loop of things. planeWave = pys.nddata(exp(1j*2*pi*freqOffset*timeAxis)).rename('value','t').labels(['t'],[timeAxis]) waveform = chirp*planeWave*ampModulation ### Find the minima start = time.time() totalLength = len(waveform.data) phaseList = [] # Input amplitude and phase lists. ampList = [] foundWaveform = [] for count,dataVal in enumerate(waveform.data):
# constants debug = True dynamicRangeMin = 0.3 # This is where the modulation starts. dynamicRangeMax = 0.41 freqOffset = 1e6 #Hz freqWidth = 1e6 # Hz, I run plus and minus this width. This is also the width at 200 GHz, I scale approprately in code. chirpLength = 10e-6 # seconds amplitudeScalingFactor = 0.37 wave = p.make_highres_waveform([('rect',0,chirpLength+1e-6)],resolution = 1e-9) timeAxis = r_[0:chirpLength:1e-9] freqWidth /= 16. rate = 2*freqWidth/chirpLength # this is the phase modulation 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.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) c,fit = baseline.polyfit('field',order = 1) fit = pys.nddata(array(c[0] + absorption.getaxis('field')*c[1])).rename('value','field').labels('field',absorption.getaxis('field')) correctedAbs = absorption - fit#}}} # Set the values of absorption spec outside of int window to zero.#{{{ zeroCorr = correctedAbs.copy() zeroCorr['field',lambda x: x < specStart] = 0.0 zeroCorr['field',lambda x: x > specStop] = 0.0#}}} # Plot absorption results#{{{ fl.figurelist = pys.nextfigure(fl.figurelist,'Absorption') pys.plot(absorption) pys.plot(fit) pys.plot(correctedAbs) pys.plot(zeroCorr) pys.title('Absorption Spectrum') pys.ylabel('Absorptive Signal')
lookupTable = pys.nddata_hdf5(lookupTableFile) lookupTable.data /= lookupTable.data.max() preservedTable = lookupTable.copy() lookupTable = lookupTable['phase',lambda x: abs(x) < 10] ### Input Waveform chirpLength = 10e-6 timeAxis = pys.r_[0:chirpLength:1e-9] freqOffset = 0e6 freqOffsetArray = pys.r_[-freqOffset:freqOffset: 1j] freqWidth = 10e6 #freqWidth /= 16. rate = 2*freqWidth/chirpLength # this is the phase modulation phaseModulation = 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*phaseModulation.data)).rename('value','t').labels(['t'],[timeAxis]) ampModulation = pys.nddata(sin(pi/chirpLength*timeAxis)).rename('value','t').labels('t',timeAxis) for countFreq,freqOffset in enumerate(freqOffsetArray): start = time.time() close('all') planeWave = pys.nddata(exp(1j*2*pi*freqOffset*timeAxis)).rename('value','t').labels(['t'],[timeAxis]) waveform = chirp*planeWave*ampModulation #### Plot the original uncorrected pulse #fig, ax = subplots(2,sharex=True,figsize=(14,12)) #ax[0].plot(chirp.getaxis('t'),chirp.runcopy(real).data) #ax[0].plot(chirp.getaxis('t'),chirp.runcopy(imag).data) #ax[0].set_title('Chirp Pulse Uncorr')
def loadPulseEPRSpec(fileName, expType='fieldDomain', spect='Elexsys'): #{{{ """ This actually opens any single dimension pulse experiment performed on the Elexsys or Specman and returns an nddata. You're writing this because bruker's file format changes too much. You also included support for specman 1-D filetype spect - string - the spectrometer name i.e. 'Elexsys' or 'Specman' """ if spect == 'Elexsys': expDict = returnEPRExpDictDSC(fileName) specData = fromfile(fileName + '.DTA', '>d') # or if it is a DTA file read that instead real = [] imaginary = [] for i in range(0, len(specData), 2): real.append(specData[i]) imaginary.append(specData[i + 1]) data = array(real) + 1j * array(imaginary) numScans = int(expDict.get('n')) numAcc = int(expDict.get('h')) if expType == 'fieldDomain': centerField = float(expDict.get('CenterField')[-2]) sweepWidth = float(expDict.get('SweepWidth')[-2]) spec = pys.nddata(data).rename('value', 'field').labels( 'field', linspace(centerField - sweepWidth / 2, centerField + sweepWidth / 2, len(data))) elif expType == 'timeDomain': timeStart = float(expDict.get('XMIN')) timeStop = float(expDict.get('XWID')) unit = str(expDict.get('XUNI')) if unit == "'ns'": multiplier = 1e-9 elif unit == "'us'": multiplier = 1e-6 else: multiplier = 1 spec = pys.nddata(data).rename('value', 'time').labels( 'time', linspace(timeStart, timeStop, len(data))) spec.other_info.update({'timeUnit': unit}) spec /= numScans spec /= numAcc return spec elif spect == 'Specman': openFile = open(os.path.abspath(fileName), 'r+') lines = openFile.readlines() lines.pop(0) time = [] real = [] imag = [] for line in lines: line = filter(None, line.split('\n')[0].split(' ')) time.append(float(line[0])) real.append(float(line[1])) imag.append(float(line[2])) spec = pys.nddata(array(real) + 1j * array(imag)).rename( 'value', 'time').labels('time', array(time)) return spec
#self.collection = db.hanLabODNPTest # This is my test collection conn = pymongo.MongoClient('localhost', 27017) # Connect to the database that I purchased db = conn.homeDB # 'dynamicalTransition' is the name of my test database 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)
phase*=1000. phaseArray.append(phase) phaseArray = array(phaseArray) # this is in degress not radians. time = [] data = [] for count,line in enumerate(lines): print"parsing data. Line %i out of %i"%(count+1,len(lines)) line = line.split('\n')[0].split(' ') line = filter(None,line) time.append(float(line.pop(0))) # it looks that the first item is always the time increment indData = [] for item in line: item = item.split(' ') indData.append(float(item[0]) + 1j*float(item[1])) data.append(pys.nddata(array(indData)).rename('value','phase').labels('phase',phaseArray)) output = pys.concat(data,'t').labels('t',array(time)) saveOutput = output.copy() if debug: 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:
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
def loadCwEPRSpec(fileName, doNormalize=True, resample=False): #{{{ """ *** This code is crappy Right now you try to incorporate stuff for xepr cw scans and you do it in a try except loop which is not the way to do this!!! This is bad code. Fix when you aren't in a rush! # you might want to force a choice on spc or dta so that you can tell the necessary workup to perform for the given file type as the normalization is different. *** Return the cw-EPR derivative spectrum from the spc and par files output by the winEPR program. If doNormalize is set to True (recommended) this will normalize the spectral values to the number of scans run as well as the receiver gain settings. This is a more reproducible value as is independent of the two settings which may vary. args: fileName - (sting) full file name not including extension. e.g. '/Users/StupidRobot/exp_data/ryan_cnsi/epr/150525_ConcentrationSeries/200uM_4OHT_14-7mm' returns: 1-D nddata dimensioned by field values of spectrum, and containing the EPR experimental parameters as other_info. """ # Open the spc and par files and pull the data and relevant parameters #try: expDict = returnEPRExpDict(fileName) specData = fromfile(fileName + '.spc', '<f') # read the spc sizeY = expDict.get('SSY') xU = 'field' if sizeY: # this is a two dimensional data set sizeY = int(sizeY) sizeX = int(expDict.get('SSX')) yU = expDict.get('XYUN') specData = specData.reshape((sizeY, sizeX)) if expDict.get('HCF'): centerSet = float(expDict.get('HCF')) elif expDict.get('XXLB'): lowBound = float(expDict.get('XXLB')) width = float(expDict.get('XXWI')) centerSet = lowBound + width / 2. else: centerSet = float(expDict.get('GST')) sweepWidth = float(expDict.get('HSW')) if doNormalize: numScans = expDict.get('JNS') # I'm not sure if this is right if numScans: numScans = float(numScans) else: numScans = 1 specData /= numScans # normalize by number of scans if expDict.get('RRG'): rg = float(expDict.get('RRG')) modAmp = float(expDict.get('RMA')) specData /= modAmp # normalize by modulation amplitude specData /= rg # normalize by receiver gain normalized = 'good' else: normalized = 'bad' else: normalized = 'None' #except: # expDict = returnEPRExpDictDSC(fileName) # specData = fromfile(fileName+'.DTA','>c') # or if it is a DTA file read that instead # centerSet = float(expDict.get('CenterField').split(' ')[0]) # sweepWidth = float(expDict.get('SweepWidth').split(' ')[0]) # numScans = float(expDict.get('NbScansAcc')) # Yea bruker just changes things... # rg = float(expDict.get('RCAG')) # if doNormalize: # specData /= rg # normalized = 'good' # sizeY = False # calculate the field values and normalize by the number of scans and the receiver gain and return an nddata # The data is two dimensional so find second dimension and if sizeY: fieldVals = pys.r_[centerSet - sweepWidth / 2.:centerSet + sweepWidth / 2.:sizeX * 1j] LB = float(expDict.get('XYLB')) width = float(expDict.get('XYWI')) yDim = pys.r_[LB:LB + width:sizeY * 1j] if yU == 'dB': # Change it to power mW. yDim = 197.9 * 10**(-1 * yDim / 10) yU = 'mW' dataShape = pys.ndshape([sizeY, sizeX], [yU, xU]) data = dataShape.alloc(dtype='float') data.data = specData spec = data spec.labels([yU, xU], [yDim, fieldVals]) else: fieldVals = pys.r_[centerSet - sweepWidth / 2.:centerSet + sweepWidth / 2.:len(specData) * 1j] spec = pys.nddata(specData).rename('value', xU).labels(xU, fieldVals) if resample: # down sample the data to 512. This is for output to the multicomponent fitting program. newField = pys.r_[centerSet - sweepWidth / 2.:centerSet + sweepWidth / 2.:512 * 1j] spec = spec.interp(xU, newField) spec.other_info = expDict return spec, normalized #}}}
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
import matlablike as ps import numpy as np import random ps.close('all') ################################################################################# ### First make an nddata with dimesions, labels, and error ################################################################################# # generate x and y data for a oscillating waveform x = np.linspace(0, 100 * 2 * np.pi, 10000) y = np.sin(x) # initialize the nddata set waveform = ps.nddata(y) waveform.rename( '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()