예제 #1
0
 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})
예제 #2
0
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  # }}}
예제 #3
0
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  #}}}
예제 #4
0
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
예제 #5
0
 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}})
예제 #6
0
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  #}}}
예제 #7
0
 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))  #}}}
예제 #8
0
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 #}}}
예제 #9
0
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):
예제 #10
0
# 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))
예제 #11
0
    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')
예제 #13
0
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
예제 #14
0
#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:
예제 #16
0
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
예제 #17
0
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  #}}}
예제 #18
0
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
예제 #19
0
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()