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()
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()
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