예제 #1
0
def main():

    if (len(_sys.argv) > 1 and _os.path.exists(_sys.argv[1]) and _os.path.isfile(_sys.argv[1])):
        filename = _sys.argv[1]
    else:
        filename = _gui.get_path("*.csv",defaultFile="odmanalysis.csv")
    
    
    commonPath = _os.path.abspath(_os.path.split(filename)[0])
    measurementName = _os.path.split(_os.path.split(filename)[0])[1]
    
    try:
        settings = _odm.CurveFitSettings.loadFromFile(commonPath + '/odmSettings.ini')
        print "settings loaded from local odmSettings.ini"
    except:
        settings = _gui.getSettingsFromUser(None)
        settings.saveToFile(commonPath + '/odmSettings.ini')
        print "settings saved to local odmSettings.ini"
    
    df = _odm.readAnalysisData(filename)
    
    makeDisplacementPlots(df,commonPath, measurementName = measurementName, nmPerPx = settings.pxToNm)
    
    
    _plt.show()
예제 #2
0
 def processDataFrame(self,df):
     """
     Processes a dataframe of raw odm data and analyzes the displacement. If this is the first dataframe
     that is being processed, the gui will show to ask the user for fit-function details.
     
     For subsequent calls to this method, the last fit-result of the previous dataframe
     is used as the initial parameters for the fit in the current dataframe.
     
     Parameters
     ----------
     
     df: pandas.DataFrame
         ODM dataframe that contains the raw ODM data
     
     
     """
     if df is None:
         return None
     
     print "processing %s - %s" % (df.index.min(),df.index.max())
     
     if not self.curveFitSettings:
         globalSettings = _odm.CurveFitSettings.loadFromFileOrCreateDefault('./CurveFitScriptSettings.ini')
         settings = _odm.CurveFitSettings.loadFromFileOrCreateDefault(self.commonPath + '/odmSettings.ini',prototype=globalSettings)
         _gui.getSettingsFromUser(settings)
         self.curveFitSettings = settings
         settings.saveToFile()
     
     if not self.movingPeakFitSettings:
         q = _mp.Queue() #it is nescessary to host all gui elements in their own process, because the cannot be spawned from another thread than the main one.
         p = _mp.Process(target=_getPeakFitSettingsFromUser, args=(q,df,settings))
         p.start()
         settingsDict = q.get()
         p.join()
         self.movingPeakFitSettings = settingsDict['movingPeakFitSettings']
         self.referencePeakFitSettings = settingsDict['referencePeakFitSettings']
        
     df_movingPeak = _odm.calculatePeakDisplacements(df.intensityProfile, self.movingPeakFitSettings, pInitial = self.popt_mp_previous, factor=100,maxfev=20000)
     
     df_movingPeak.rename(columns = lambda columnName: columnName + "_mp",inplace=True)
     df = df.join(df_movingPeak)
     self.popt_mp_previous = df.curveFitResult_mp[-1].popt
     
     if (self.referencePeakFitSettings is not None):
         df_referencePeak = _odm.calculatePeakDisplacements(df.intensityProfile, self.referencePeakFitSettings, pInitial = self.popt_ref_previous, factor=100,maxfev=20000)
         df_referencePeak.rename(columns = lambda columnName: columnName + "_ref",inplace=True)
         df = df.join(df_referencePeak)
         self.popt_ref_previous = df.curveFitResult_ref[-1].popt
         df['displacement'] = df.displacement_mp - df.displacement_ref
     else:
         df['displacement'] = df.displacement_mp
     
     if (self.lastDataFrame is not None):
         tail = self.lastDataFrame.iloc[-2:]
         dfC = _pd.concat([tail,df])
         _odm.getActuationDirectionAndCycle(dfC,startDirection = tail.direction.iloc[1],startCycleNumber = tail.cycleNumber.iloc[1])
         df = dfC.iloc[2:]
     else:
         _odm.getActuationDirectionAndCycle(df)
     
     self.lastDataFrame = df
     
     return df
def main():
    if len(sys.argv) > 1 and os.path.exists(sys.argv[1]) and os.path.isfile(sys.argv[1]):
        filename = sys.argv[1]
    else:
        filename = gui.get_path("*.csv", defaultFile="odmanalysis.csv")

    commonPath = os.path.abspath(os.path.split(filename)[0])

    try:
        settings = odm.CurveFitSettings.loadFromFile(commonPath + "/odmSettings.ini")
        print "settings loaded from local odmSettings.ini"
    except:
        settings = gui.getSettingsFromUser(None)
        settings.saveToFile(commonPath + "/odmSettings.ini")
        print "settings saved to local odmSettings.ini"

    nmPerPx = settings.pxToNm

    df = odm.readAnalysisData(filename)
    plt.plot(np.arange(len(df.displacement)), df.displacement * nmPerPx)

    plt.interactive(False)
    coordinateGrabber = gui.InteractiveCoordinateGrabber(plt.gcf(), 2, "Select range for fitting a polynomial...")
    coordinateGrabber.promptMessages = ["Select lower limit...", "Select upper limit..."]
    coordinates = coordinateGrabber.getValuesFromUser()

    xLimits = [int(c[0]) for c in coordinates]

    dfs = df.iloc[slice(*xLimits)]

    validInput = False
    while validInput == False:
        try:
            deg = int(raw_input("Polynomial degree: "))
            validInput = True
        except:
            pass

    xValues = np.arange(len(dfs.displacement))
    p = cp.polyfit(xValues, dfs.displacement, deg)
    noise = (dfs.displacement - cp.polyval(p, xValues)) * nmPerPx

    ax = plt.subplot(111)
    ax.plot(xValues, dfs.displacement * nmPerPx)
    ax.plot(xValues, cp.polyval(p, xValues) * nmPerPx, "r--")
    ax.set_xlabel("Actuator Voltage (V)")
    ax.set_ylabel("Displacement (nm)")

    fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, sharex=False, sharey=True, squeeze=True)
    ax1.plot(np.arange(len(noise)), noise, "o")
    ax2.hist(noise, bins=50, orientation="horizontal", facecolor="green", alpha=0.5)

    sd = ODMStats.makeStatsDescriptionDict(nmPerPx * dfs.displacement)
    peakDistanceToEdge = [abs(sd["mean"] - x * nmPerPx) for x in ax2.get_xlim()]
    xtext = 0.1 if peakDistanceToEdge[0] > peakDistanceToEdge[1] else 0.7
    ax2.text(xtext, 0.7, ODMStats.printStatsDescriptionDict(sd), transform=ax2.transAxes)

    ax1.set_ylabel("Displacement (nm)")
    ax2.set_xlabel("Count")
    fig.savefig(os.path.join(commonPath, "Displacement noise.png"), dpi=150)

    stats = noise.describe()
    with open(os.path.join(commonPath, "position_noise_stats.txt"), "w") as f:
        f.write(str(stats))

    plt.show()
예제 #4
0
def fitRawODMData(filename,settingsFile=None,fitSettingsFile=None,referenceIPDataFile=None):
    """
    This script opens and analyzes the target data.csv file produced by LabVIEW and
    analyzes the optical displacement of a peak relative to another peak.
    Results are saved to the same folder as the original data file.
    
    Parameters
    ----------
    
    filename: string
        Path to the data.csv file produced by LabVIEW that contains the raw 
        Optical Displacement Measurement Data.
    referenceIPDataFile: string
        Path the data.csv file of which the first intensity profile will be used
        as a reference for initializing the fit function.
    
    
    Returns
    -------
    
    dataframe: pandas.DataFrame
        A dataframe that contains the raw data, the calculated displacements,
        curve fit results and other diagnostic data.
    movingPeakFitSettings : CurveFitSettings instance
        The curve fit settings used for the moving peak.
    referencePeakFitSettings: CurveFitSettings instance
        The curve fit settings used for the reference peak.
    measurementName: string
        The name of the measurement (deduced from the folder name of the csv file)
    """
    
    commonPath = os.path.abspath(os.path.split(filename)[0])
    measurementName = os.path.split(os.path.split(filename)[0])[1]
    
    globalSettings = odm.CurveFitSettings.loadFromFileOrCreateDefault('./CurveFitScriptSettings.ini')
    
    if (settingsFile is not None):
        print "reading settings from %s" % settingsFile
        settings = odm.CurveFitSettings.loadFromFile(settingsFile)
    else:
        settings = odm.CurveFitSettings.loadFromFileOrCreateDefault(commonPath + '/odmSettings.ini',prototype=globalSettings)
        gui.getSettingsFromUser(settings)

    
    

    
    df = odm.readODMData(filename)
    
    if referenceIPDataFile is not None:
        print "using the first profile from %s for initializing the fit functions" % referenceIPDataFile
        for chunk in odm.getODMDataReader(referenceIPDataFile, chunksize=1):
            referenceIntensityProfile = chunk.intensityProfile.iloc[0]
            break
    else:
        referenceIntensityProfile = df.intensityProfile.iloc[0]
    

    if (fitSettingsFile is not None):
        with file(fitSettingsFile,'r') as f:
            print "reading fit settings from %s" % fitSettingsFile
            settingsDict = pickle.load(f)
            movingPeakFitSettings = settingsDict['movingPeakFitSettings']
            referencePeakFitSettings = settingsDict['referencePeakFitSettings']
        
    else:
        movingPeakFitFunction = ff.createFitFunction(settings.defaultFitFunction)
        movingPeakFitSettings = gui.getPeakFitSettingsFromUser(referenceIntensityProfile,movingPeakFitFunction,
                                                           estimatorPromptPrefix="Moving peak:",
                                                           windowTitle="Moving Peak estimates")
        
        try:
            referencePeakFitFunction = ff.createFitFunction(settings.defaultFitFunction)
            referencePeakFitSettings = gui.getPeakFitSettingsFromUser(referenceIntensityProfile,referencePeakFitFunction,
                                                                      estimatorPromptPrefix="Reference peak:",
                                                                      windowTitle="Reference Peak estimates")
        except: #exception occurs if user cancels the 'dialog'
            referencePeakFitFunction = None        
            referencePeakFitSettings = None
            print 'no reference'
    

    movingPeakFitSettings.referenceIntensityProfile = referenceIntensityProfile
    referencePeakFitSettings.referenceIntensityProfile = referenceIntensityProfile




    print "fitting a %s function..." % settings.defaultFitFunction
    df_movingPeak = odm.calculatePeakDisplacements(df.intensityProfile, movingPeakFitSettings, factor=100,maxfev=20000)
    
    df_movingPeak.rename(columns = lambda columnName: columnName + "_mp",inplace=True)
    df = df.join(df_movingPeak)
    
    if (referencePeakFitSettings is not None):
        df_referencePeak = odm.calculatePeakDisplacements(df.intensityProfile, referencePeakFitSettings, factor=100,maxfev=20000)
        df_referencePeak.rename(columns = lambda columnName: columnName + "_ref",inplace=True)
        df = df.join(df_referencePeak)
        df['displacement'] = df.displacement_mp - df.displacement_ref
    else:
        df['displacement'] = df.displacement_mp
    
    
    #save settings
    sys.stdout.write("saving defaults...")
    globalSettings.saveToFile()
    sys.stdout.write("done\r\n")
    
    sys.stdout.write("saving local setting file...")
    settings.saveToFile()
    sys.stdout.write("done\r\n")
    
    print "done"    
    
    #save calculated peak position data as csv
    sys.stdout.write("saving dataframe as csv file...")
    exportColumns = ['relativeTime','cycleNumber','direction','actuatorVoltage','displacement','displacement_mp','chiSquare_mp']
    if ('displacement_ref' in df.columns):
        exportColumns +=['displacement_ref','chiSquare_ref']
    df[exportColumns].to_csv(os.path.join(commonPath,'odmanalysis.csv'),index_label='timestamp')
    sys.stdout.write("done\r\n")
    
    #save fit results as pickled dataframe
    sys.stdout.write("pickling fit results dataframe as pcl file...")
    fitResultColumns = ['curveFitResult_mp']
    if 'curveFitResult_ref' in df.columns:
        fitResultColumns += ['curveFitResult_ref']
    df[fitResultColumns].to_pickle(commonPath + '/fitResults.pcl')
    sys.stdout.write("done\r\n")
    
    #save the used fit functions and fit settings as pickled objects
    sys.stdout.write("pickling fit functions and settings...")
    settingsDict = {'movingPeakFitSettings': movingPeakFitSettings,
                             'referencePeakFitSettings': referencePeakFitSettings if referencePeakFitSettings is not None else None}
    with file(commonPath+'/fitSettings.pcl','w') as stream:
        pickle.dump(settingsDict,stream)
    sys.stdout.write("done\r\n")
    
    print "ALL DONE"
    
    return df,movingPeakFitSettings,referencePeakFitSettings,measurementName