diff --git a/@MyDaq/MyDaq.m b/@MyDaq/MyDaq.m index 9ac7c01..1c87850 100644 --- a/@MyDaq/MyDaq.m +++ b/@MyDaq/MyDaq.m @@ -1,963 +1,975 @@ % Acquisition and analysis program that receives data from Collector. Can % also be used for analysis of previously acquired traces. classdef MyDaq < handle properties %Global variable with Daq name is cleared on exit. global_name %Contains GUI handles Gui %Contains Reference trace (MyTrace object) Ref %Contains Data trace (MyTrace object) Data %Contains Background trace (MyTrace object) Background %List of all the programs with run files ProgramList %Struct containing Cursor objects Cursors %Struct containing Cursor labels CrsLabels %Struct containing MyFit objects Fits %Input parser for class constructor ConstructionParser %Struct for listeners Listeners %Sets the colors of fits, data and reference fit_color='k'; data_color='b'; ref_color='r'; bg_color='c'; end properties (Dependent=true) save_dir main_plot open_fits open_crs end properties (Dependent=true, SetAccess=private, GetAccess=public) %Properties for saving files base_dir session_name filename end methods (Access=public) %% Class functions %Constructor function function this=MyDaq(varargin) % Initialize variables % Traces this.Ref=MyTrace(); this.Data=MyTrace(); this.Background=MyTrace(); % Lists this.ProgramList=struct(); this.Cursors=struct(); this.CrsLabels=struct(); this.Fits=struct(); this.ConstructionParser; this.Listeners=struct(); % Parse inputs p=inputParser; addParameter(p,'global_name','',@ischar); addParameter(p,'collector_handle',[]); this.ConstructionParser=p; parse(p, varargin{:}); this.global_name = p.Results.global_name; %Sets a listener to the collector if ~isempty(p.Results.collector_handle) this.Listeners.Collector.NewDataWithHeaders=... addlistener(p.Results.collector_handle,... 'NewDataWithHeaders',... @(~,eventdata) acquireNewData(this,eventdata)); else errordlg(['No collector handle was supplied. ',... 'DAQ will be unable to acquire data'],... 'Error: No collector'); end %The list of instruments is automatically populated from the %run files this.ProgramList = readRunFiles(); %We grab the guihandles from a GUI made in Guide. this.Gui=guihandles(eval('GuiDaq')); %This function sets all the callbacks for the GUI. If a new %button is made, the associated callback must be put in the %initGui function initGui(this); % Initialize the menu based on the available run files content = menuFromRunFiles(this.ProgramList,... 'show_in_daq',true); set(this.Gui.InstrMenu,'String',[{'Select the application'};... content.titles]); % Add a property to the menu for storing the program file % names if ~isprop(this.Gui.InstrMenu, 'ItemsData') addprop(this.Gui.InstrMenu, 'ItemsData'); end set(this.Gui.InstrMenu,'ItemsData',[{''};... content.tags]); hold(this.main_plot,'on'); %Initializes saving locations this.base_dir=getLocalSettings('measurement_base_dir'); this.session_name='placeholder'; this.filename='placeholder'; end function delete(this) %Deletes the MyFit objects and their listeners cellfun(@(x) deleteListeners(this,x), this.open_fits); structfun(@(x) delete(x), this.Fits); %Deletes other listeners if ~isempty(fieldnames(this.Listeners)) cellfun(@(x) deleteListeners(this, x),... fieldnames(this.Listeners)); end % clear global variable, to which Daq handle is assigned evalin('base', sprintf('clear(''%s'')', this.global_name)); this.Gui.figure1.CloseRequestFcn=''; %Deletes the figure delete(this.Gui.figure1); %Removes the figure handle to prevent memory leaks this.Gui=[]; end end methods (Access=private) %Sets callback functions for the GUI initGui(this) %Executes when the GUI is closed function closeFigure(this,~,~) delete(this); end %Updates fits function updateFits(this) %Pushes data into fits in the form of MyTrace objects, so that %units etc follow. Also updates user supplied parameters. for i=1:length(this.open_fits) switch this.open_fits{i} case {'Linear','Quadratic','Gaussian',... 'Exponential','Beta'} this.Fits.(this.open_fits{i}).Data=... getFitData(this,'VertData'); case {'Lorentzian','DoubleLorentzian'} this.Fits.(this.open_fits{i}).Data=... getFitData(this,'VertData'); %Here we push the information about line spacing %into the fit object if the reference cursors are %open. Only for Lorentzian fits. if isfield(this.Cursors,'VertRef') ind=findCursorData(this,'Data','VertRef'); this.Fits.(this.open_fits{i}).CalVals.line_spacing=... range(this.Data.x(ind)); end case {'G0'} this.Fits.G0.MechTrace=getFitData(this,'VertData'); this.Fits.G0.CalTrace=getFitData(this,'VertRef'); end end end % If vertical cursors are on, takes only data within cursors. If %the cursor is not open, it takes all the data from the selected %trace in the analysis trace selection dropdown function Trace=getFitData(this,varargin) %Parses varargin input p=inputParser; addOptional(p,'name','',@ischar); parse(p,varargin{:}) name=p.Results.name; %Finds out which trace the user wants to fit. trc_opts=this.Gui.SelTrace.String; trc_str=trc_opts{this.Gui.SelTrace.Value}; % Note the use of copy here! This is a handle %class, so if normal assignment is used, this.Fits.Data and %this.(trace_str) will refer to the same object, causing roblems. %Name input is the name of the cursor to be used to extract data. Trace=copy(this.(trc_str)); %If the cursor is open for the trace we are analyzing, we take %only the data enclosed by the cursor. if isfield(this.Cursors,name) ind=findCursorData(this, trc_str, name); Trace.x=this.(trc_str).x(ind); Trace.y=this.(trc_str).y(ind); end end %Finds data between named cursors in the given trace function ind=findCursorData(this, trc_str, name) crs_pos=sort([this.Cursors.(name){1}.Location,... this.Cursors.(name){2}.Location]); ind=(this.(trc_str).x>crs_pos(1) & this.(trc_str).x %Prints the figure to the clipboard print(newFig,'-clipboard','-dbitmap'); %Deletes the figure delete(newFig); end %Resets the axis to be tight around the plots. function updateAxis(this) axis(this.main_plot,'tight'); end end methods (Access=public) %% Callbacks %Callback for copying the plot to clipboard function copyPlotCallback(this,~,~) copyPlot(this); end %Callback for centering cursors function centerCursorsCallback(this, ~, ~) if ~this.Gui.LogX.Value x_pos=mean(this.main_plot.XLim); else x_pos=10^(mean(log10(this.main_plot.XLim))); end if ~this.Gui.LogY.Value y_pos=mean(this.main_plot.YLim); else y_pos=10^(mean(log10(this.main_plot.YLim))); end for i=1:length(this.open_crs) switch this.Cursors.(this.open_crs{i}){1}.Orientation case 'horizontal' pos=y_pos; case 'vertical' pos=x_pos; end %Centers the position cellfun(@(x) set(x,'Location',pos), ... this.Cursors.(this.open_crs{i})); %Triggers the UpdateCursorBar event, which triggers %listener callback to reposition text cellfun(@(x) notify(x,'UpdateCursorBar'),... this.Cursors.(this.open_crs{i})); %Triggers the EndDrag event, updating the data in the fit %objects. cellfun(@(x) notify(x,'EndDrag'),... this.Cursors.(this.open_crs{i})); end end %Callback for creating vertical data cursors function cursorButtonCallback(this, hObject, ~) name=erase(hObject.Tag,'Button'); %Gets the first four characters of the tag (Vert or Horz) type=name(1:4); %Changes the color of the button and appropriately creates or %deletes the cursors. if hObject.Value hObject.BackgroundColor=[0,1,0.2]; createCursors(this,name,type); else hObject.BackgroundColor=[0.941,0.941,0.941]; deleteCursors(this,name); end end %Callback for the instrument menu function instrMenuCallback(this,hObject,~) val=hObject.Value; if val==1 %Returns if we are on the dummy option ('Select instrument') return else tag = hObject.ItemsData{val}; end try eval(this.ProgramList.(tag).run_expr); catch errordlg(sprintf('An error occured while running %s',... this.ProgramList.(tag).name)) end end %Select trace callback. If we change the trace being analyzed, the %fit objects are updated. function selTraceCallback(this, ~, ~) updateFits(this) end %Saves the data if the save data button is pressed. function saveCallback(this, src, ~) switch src.Tag case 'SaveData' saveTrace(this,'Data'); case 'SaveRef' saveTrace(this,'Ref'); end end function saveTrace(this, trace_tag) %Check if the trace is valid (i.e. x and y are equal length) %before saving if ~this.(trace_tag).validatePlot errordlg(sprintf('%s trace was empty, could not save',... trace_tag)); return end [~,~,ext]=fileparts(this.filename); if isempty(ext) % Add default file extension fullfilename=fullfile(this.save_dir,[this.filename,'.txt']); else % Use file extension supplied in the field fullfilename=fullfile(this.save_dir,this.filename); end %Save in a readable format using the method of MyTrace save(this.(trace_tag), fullfilename) end %Toggle button callback for showing the data trace. function showDataCallback(this, hObject, ~) if hObject.Value hObject.BackgroundColor=[0,1,0.2]; setVisible(this.Data,this.main_plot,1); updateAxis(this); else hObject.BackgroundColor=[0.941,0.941,0.941]; setVisible(this.Data,this.main_plot,0); updateAxis(this); end end %Toggle button callback for showing the ref trace function showRefCallback(this, hObject, ~) if hObject.Value hObject.BackgroundColor=[0,1,0.2]; setVisible(this.Ref,this.main_plot,1); updateAxis(this); else hObject.BackgroundColor=[0.941,0.941,0.941]; setVisible(this.Ref,this.main_plot,0); updateAxis(this); end end %Callback for moving the data to reference. function dataToRefCallback(this, ~, ~) if this.Data.validatePlot set(this.Ref,... 'x',this.Data.x,... 'y',this.Data.y,... 'name_x',this.Data.name_x,... 'name_y',this.Data.name_y,... 'unit_x',this.Data.unit_x,... 'unit_y',this.Data.unit_y); %Since UID is automatically reset when y is changed, we now %change it back to be the same as the Data. this.Ref.uid=this.Data.uid; this.Ref.MeasHeaders=copy(this.Data.MeasHeaders); %Plot the reference trace and make it visible plot(this.Ref, this.main_plot, 'Color',this.ref_color,... 'make_labels',true); setVisible(this.Ref, this.main_plot,1); %Update the fit objects updateFits(this); %Change button color this.Gui.ShowRef.Value=1; this.Gui.ShowRef.BackgroundColor=[0,1,0.2]; else warning('Data trace was empty, could not move to reference') end end %Callback for ref to bg button. Sends the reference to background function refToBgCallback(this, ~, ~) if this.Ref.validatePlot this.Background.x=this.Ref.x; this.Background.y=this.Ref.y; this.Background.plot(this.main_plot,... 'Color',this.bg_color,'make_labels',true); this.Background.setVisible(this.main_plot,1); else warning('Reference trace was empty, could not move to background') end end %Callback for data to bg button. Sends the data to background function dataToBgCallback(this, ~, ~) if this.Data.validatePlot this.Background.x=this.Data.x; this.Background.y=this.Data.y; this.Background.plot(this.main_plot,... 'Color',this.bg_color,'make_labels',true); this.Background.setVisible(this.main_plot,1); else warning('Data trace was empty, could not move to background') end end %Callback for clear background button. Clears the background function clearBgCallback(this, ~, ~) this.Background.x=[]; this.Background.y=[]; this.Background.setVisible(this.main_plot,0); end %Callback for LogY button. Sets the YScale to log/lin function logYCallback(this, hObject, ~) if hObject.Value this.main_plot.YScale='Log'; hObject.BackgroundColor=[0,1,0.2]; else this.main_plot.YScale='Linear'; hObject.BackgroundColor=[0.941,0.941,0.941]; end updateAxis(this); updateCursors(this); end %Callback for LogX button. Sets the XScale to log/lin. Updates the %axis and cursors afterwards. function logXCallback(this, hObject, ~) if get(hObject,'Value') set(this.main_plot,'XScale','Log'); set(hObject, 'BackgroundColor',[0,1,0.2]); else set(this.main_plot,'XScale','Linear'); set(hObject, 'BackgroundColor',[0.941,0.941,0.941]); end updateAxis(this); updateCursors(this); end %Base directory callback. Sets the base directory. Also %updates fit objects with the new save directory. function baseDirCallback(this, ~, ~) for i=1:length(this.open_fits) this.Fits.(this.open_fits{i}).base_dir=this.base_dir; end end %Callback for session name edit box. Sets the session name. Also %updates fit objects with the new save directory. function sessionNameCallback(this, ~, ~) for i=1:length(this.open_fits) this.Fits.(this.open_fits{i}).session_name=this.session_name; end end %Callback for filename edit box. Sets the file name. Also %updates fit objects with the new file name. function fileNameCallback(this, ~,~) for i=1:length(this.open_fits) this.Fits.(this.open_fits{i}).filename=this.filename; end end %Callback for the analyze menu (popup menu for selecting fits). %Opens the correct MyFit object. function analyzeMenuCallback(this, hObject, ~) analyze_ind=hObject.Value; %Finds the correct fit name by erasing spaces and other %superfluous strings analyze_name=hObject.String{analyze_ind}; analyze_name=erase(analyze_name,'Fit'); analyze_name=erase(analyze_name,'Calibration'); analyze_name=erase(analyze_name,' '); %Sets the correct tooltip hObject.TooltipString=sprintf(this.Gui.AnalyzeTip{analyze_ind}) ; %Opens the correct analysis tool switch analyze_name case {'Linear','Quadratic','Exponential',... 'Lorentzian','Gaussian',... 'DoubleLorentzian'} openMyFit(this,analyze_name); case 'g0' openMyG(this); case 'Beta' openMyBeta(this); end end function openMyFit(this,fit_name) %Sees if the MyFit object is already open, if it is, changes the %focus to it, if not, opens it. if ismember(fit_name,fieldnames(this.Fits)) %Changes focus to the relevant fit window figure(this.Fits.(fit_name).Gui.Window); else %Gets the data for the fit using the getFitData function %with the vertical cursors DataTrace=getFitData(this,'VertData'); %Makes an instance of MyFit with correct parameters. this.Fits.(fit_name)=MyFit(... 'fit_name',fit_name,... 'enable_plot',1,... 'plot_handle',this.main_plot,... 'Data',DataTrace,... 'base_dir',this.base_dir,... 'session_name',this.session_name,... 'filename',this.filename); updateFits(this); %Sets up a listener for the Deletion event, which %removes the MyFit object from the Fits structure if it is %deleted. this.Listeners.(fit_name).Deletion=... addlistener(this.Fits.(fit_name),'ObjectBeingDestroyed',... @(src, eventdata) deleteFit(this, src, eventdata)); %Sets up a listener for the NewFit. Callback plots the fit %on the main plot. this.Listeners.(fit_name).NewFit=... addlistener(this.Fits.(fit_name),'NewFit',... @(src, eventdata) plotNewFit(this, src, eventdata)); %Sets up a listener for NewInitVal this.Listeners.(fit_name).NewInitVal=... addlistener(this.Fits.(fit_name),'NewInitVal',... @(~,~) updateCursors(this)); end end %Opens MyG class if it is not open. function openMyG(this) if ismember('G0',this.open_fits) figure(this.Fits.G0.Gui.figure1); else %Populate the MyG class with the right data. We assume the %mechanics is in the Data trace. MechTrace=getFitData(this,'VertData'); CalTrace=getFitData(this,'VertRef'); this.Fits.G0=MyG('MechTrace',MechTrace,'CalTrace',CalTrace,... 'name','G0'); %Adds listener for object being destroyed this.Listeners.G0.Deletion=addlistener(this.Fits.G0,... 'ObjectBeingDestroyed',... @(~,~) deleteObj(this,'G0')); end end %Opens MyBeta class if it is not open. function openMyBeta(this) if ismember('Beta', this.open_fits) figure(this.Fits.Beta.Gui.figure1); else DataTrace=getFitData(this); this.Fits.Beta=MyBeta('Data',DataTrace); %Adds listener for object being destroyed, to perform cleanup this.Listeners.Beta.Deletion=addlistener(this.Fits.Beta,... 'ObjectBeingDestroyed',... @(~,~) deleteObj(this,'Beta')); end end %Callback for load data button function loadDataCallback(this, ~, ~) if isempty(this.base_dir) warning('Please input a valid folder name for loading a trace'); this.base_dir=pwd; end [load_name,path_name]=uigetfile('.txt','Select the trace',... this.base_dir); if load_name==0 warning('No file was selected'); return end load_path=[path_name,load_name]; %Finds the destination trace from the GUI dest_trc=this.Gui.DestTrc.String{this.Gui.DestTrc.Value}; %Call the load trace function on the right trace load(this.(dest_trc), load_path); %Color and plot the right trace. plot(this.(dest_trc), this.main_plot,... 'Color',this.(sprintf('%s_color',lower(dest_trc))),... 'make_labels',true); %Update axis and cursors updateAxis(this); updateCursors(this); end + + % Callback for open folder button + function openFolderCallback(this, hObject, eventdata) + dir=uigetdir(this.Gui.BaseDir.String); + if ~isempty(dir) + this.Gui.BaseDir.String=dir; + end + + % Execute the same callback as if the base directory edit + % field was manually updated + baseDirCallback(this, hObject, eventdata); + end end methods (Access=public) %% Listener functions %Callback function for NewFit listener. Plots the fit in the %window using the plotFit function of the MyFit object function plotNewFit(this, src, ~) src.plotFit('Color',this.fit_color); updateAxis(this); updateCursors(this); end %Callback function for the NewData listener function acquireNewData(this, EventData) %Get the currently selected instrument val=this.Gui.InstrMenu.Value; curr_instr_name=this.Gui.InstrMenu.ItemsData{val}; %Get the name of instrument that generated new data SourceInstr = EventData.Instr; source_name = SourceInstr.name; %Check if the data originates from the currently selected %instrument if strcmp(source_name, curr_instr_name) hline=getLineHandle(this.Data,this.main_plot); %Copy the data from the source instrument this.Data=copy(SourceInstr.Trace); %We give the new trace object the right line handle to plot in if ~isempty(hline) this.Data.hlines{1}=hline; end plot(this.Data, this.main_plot,... 'Color',this.data_color,... 'make_labels',true) updateAxis(this); updateCursors(this); updateFits(this); end end %Callback function for MyFit ObjectBeingDestroyed listener. %Removes the relevant field from the Fits struct and deletes the %listeners from the object. function deleteFit(this, src, ~) %Deletes the object from the Fits struct and deletes listeners deleteObj(this,src.fit_name); %Clears the fits src.clearFit; %Updates cursors since the fits are removed from the plot updateCursors(this); end %Callback function for other analysis method deletion listeners. %Does the same as above. function deleteObj(this,name) if ismember(name,this.open_fits) this.Fits=rmfield(this.Fits,name); end deleteListeners(this, name); end %Listener update function for vertical cursor function vertCursorUpdate(this, src) %Finds the index of the cursor. All cursors are tagged %(name)1, (name)2, e.g. VertData2, ind is the number. ind=str2double(src.Tag(end)); tag=src.Tag(1:(end-1)); %Moves the cursor labels set(this.CrsLabels.(tag){ind},'Position',[src.Location,... this.CrsLabels.(tag){ind}.Position(2),0]); if strcmp(tag,'VertData') %Sets the edit box displaying the location of the cursor this.Gui.(sprintf('EditV%d',ind)).String=... num2str(src.Location); %Sets the edit box displaying the difference in locations this.Gui.EditV2V1.String=... num2str(this.Cursors.VertData{2}.Location-... this.Cursors.VertData{1}.Location); end end %Listener update function for horizontal cursor function horzCursorUpdate(this, src) %Finds the index of the cursor. All cursors are tagged %(name)1, (name)2, e.g. VertData2, ind is the number. ind=str2double(src.Tag(end)); tag=src.Tag(1:(end-1)); %Moves the cursor labels set(this.CrsLabels.(tag){ind},'Position',... [this.CrsLabels.(tag){ind}.Position(1),... src.Location,0]); if strcmp(tag,'HorzData') %Sets the edit box displaying the location of the cursor this.Gui.(sprintf('EditH%d',ind)).String=... num2str(src.Location); %Sets the edit box displaying the difference in locations this.Gui.EditH2H1.String=... num2str(this.Cursors.HorzData{2}.Location-... this.Cursors.HorzData{1}.Location); end end %Function that deletes listeners from the listeners struct, %corresponding to an object of name obj_name deleteListeners(this, obj_name); end %Get functions for dependent variables without set functions methods %Get function from save directory function save_dir=get.save_dir(this) save_dir=createSessionPath(this.base_dir,this.session_name); end %Get function for the plot handles function main_plot=get.main_plot(this) main_plot=this.Gui.figure1.CurrentAxes; end %Get function for open fits function open_fits=get.open_fits(this) open_fits=fieldnames(this.Fits); end %Get function that displays names of open cursors function open_crs=get.open_crs(this) open_crs=fieldnames(this.Cursors); end end %Get and set functions for dependent properties with SetAccess methods function base_dir=get.base_dir(this) try base_dir=this.Gui.BaseDir.String; catch base_dir=pwd; end end function set.base_dir(this,base_dir) this.Gui.BaseDir.String=base_dir; end function session_name=get.session_name(this) try session_name=this.Gui.SessionName.String; catch session_name=''; end end function set.session_name(this,session_name) this.Gui.SessionName.String=session_name; end function filename=get.filename(this) try filename=this.Gui.FileName.String; catch filename='placeholder'; end end function set.filename(this,filename) this.Gui.FileName.String=filename; end end end \ No newline at end of file diff --git a/@MyDaq/initGui.m b/@MyDaq/initGui.m index ff78f97..08e89f7 100644 --- a/@MyDaq/initGui.m +++ b/@MyDaq/initGui.m @@ -1,116 +1,119 @@ %Initializes MyDaq Gui. Needs no inputs, but should be modified if you wish %to change the callbacks etc. function initGui(this) %Close request function is set to delete function of the class this.Gui.figure1.CloseRequestFcn=@(hObject,eventdata)... closeFigure(this, hObject, eventdata); %Sets callback for the edit box of the base directory this.Gui.BaseDir.Callback=@(hObject, eventdata)... baseDirCallback(this, hObject, eventdata); %Sets callback for the session name edit box this.Gui.SessionName.Callback=@(hObject, eventdata)... sessionNameCallback(this, hObject, eventdata); %Sets callback for the file name edit box this.Gui.FileName.Callback=@(hObject, eventdata) ... fileNameCallback(this, hObject,eventdata); %Sets callback for the save data button this.Gui.SaveData.Callback=@(hObject, eventdata) ... saveCallback(this, hObject,eventdata); %Sets callback for the save ref button this.Gui.SaveRef.Callback=@(hObject, eventdata)... saveCallback(this, hObject, eventdata); %Sets callback for the show data button this.Gui.ShowData.Callback=@(hObject, eventdata)... showDataCallback(this, hObject, eventdata); %Sets callback for the show reference button this.Gui.ShowRef.Callback=@(hObject, eventdata)... showRefCallback(this, hObject, eventdata); %Sets callback for the data to reference button this.Gui.DataToRef.Callback=@(hObject, eventdata)... dataToRefCallback(this, hObject, eventdata); %Sets callback for the LogY button this.Gui.LogY.Callback=@(hObject, eventdata) ... logYCallback(this, hObject, eventdata); %Sets callback for the LogX button this.Gui.LogX.Callback=@(hObject, eventdata)... logXCallback(this, hObject, eventdata); %Sets callback for the data to background button this.Gui.DataToBg.Callback=@(hObject, eventdata) ... dataToBgCallback(this, hObject,eventdata); %Sets callback for the ref to background button this.Gui.RefToBg.Callback=@(hObject, eventdata) ... refToBgCallback(this, hObject,eventdata); %Sets callback for the clear background button this.Gui.ClearBg.Callback=@(hObject, eventdata)... clearBgCallback(this, hObject,eventdata); %Sets callback for the select trace popup menu this.Gui.SelTrace.Callback=@(hObject,eventdata)... selTraceCallback(this, hObject,eventdata); %Sets callback for the vertical cursor button this.Gui.VertDataButton.Callback=@(hObject, eventdata)... cursorButtonCallback(this, hObject,eventdata); %Sets callback for the horizontal cursors button this.Gui.HorzDataButton.Callback=@(hObject, eventdata)... cursorButtonCallback(this, hObject,eventdata); %Sets callback for the reference cursors button this.Gui.VertRefButton.Callback=@(hObject, eventdata)... cursorButtonCallback(this, hObject,eventdata); %Sets callback for the center cursors button this.Gui.CenterCursors.Callback=@(hObject,eventdata)... centerCursorsCallback(this,hObject,eventdata); %Sets callback for the center cursors button this.Gui.CopyPlot.Callback=@(hObject,eventdata)... copyPlotCallback(this,hObject,eventdata); %Sets callback for load trace button this.Gui.LoadButton.Callback=@(hObject,eventdata)... loadDataCallback(this,hObject,eventdata); +%Sets callback for open directory button +this.Gui.OpenFolderButton.Callback=@(hObject,eventdata)... + openFolderCallback(this,hObject,eventdata); %Initializes the AnalyzeMenu this.Gui.AnalyzeMenu.Callback=@(hObject, eventdata)... analyzeMenuCallback(this, hObject,eventdata); %List of available analysis routines this.Gui.AnalyzeMenu.String={'Select a routine...',... 'Linear Fit','Quadratic Fit','Exponential Fit',... 'Gaussian Fit','Lorentzian Fit','Double Lorentzian Fit',... 'g0 Calibration','Beta Calibration'}; %Tooltips for AnalyzeMenu standard_tip=['Generate initial parameters with gen. init. param. \n',... 'Press Analyze to fit. Move the sliders or enter numbers to',... ' change initial parameters.\n']; this.Gui.AnalyzeTip{1}='Select a routine to open it.'; this.Gui.AnalyzeTip{2}=standard_tip; this.Gui.AnalyzeTip{3}=standard_tip; this.Gui.AnalyzeTip{4}=[standard_tip,... 'Calculation of the quality factor (assuming amplitude ringdown) ',... 'is included']; this.Gui.AnalyzeTip{5}=standard_tip; this.Gui.AnalyzeTip{6}=... [standard_tip,... 'To calibrate optical linewidths, move the reference cursors to',... ' have the correct number of resonances between them \n',... 'The number of resonances can be changed by changing the number of ',... 'lines in the GUI. \n The FSR is entered in the line spacing field \n',... 'The tab for mechanics is automatically populated and calculated.']; this.Gui.AnalyzeTip{7}= [standard_tip,... 'To calibrate optical linewidths, move the reference cursors to',... ' have the correct number of resonances between them \n',... 'The number of resonances can be changed by changing the number of ',... 'lines in the GUI. \n The FSR is entered in the line spacing field \n',... 'The modal spacing is automatically calculated']; this.Gui.AnalyzeTip{8}=['Put calibration tone between reference cursors.\n',... 'Put mechanical mode signal between vertical cursors.\n',... 'Enter the correct temperature and beta, then press analyze to find g0.']; this.Gui.AnalyzeTip{9}=['Automatically calculates beta based on first ',... 'and second order phase modulation sidebands']; %Initializes the InstrMenu this.Gui.InstrMenu.Callback=@(hObject,eventdata) ... instrMenuCallback(this,hObject,eventdata); %Initializes the axis this.main_plot.Box='on'; this.main_plot.XLabel.String='x'; this.main_plot.YLabel.String='y'; end \ No newline at end of file diff --git a/GUIs/GuiDaq.fig b/GUIs/GuiDaq.fig index 469c62d..0a413f0 100644 Binary files a/GUIs/GuiDaq.fig and b/GUIs/GuiDaq.fig differ diff --git a/GUIs/GuiDaq.m b/GUIs/GuiDaq.m index f1cec15..d364ad7 100644 --- a/GUIs/GuiDaq.m +++ b/GUIs/GuiDaq.m @@ -1,348 +1,249 @@ function varargout = GuiDaq(varargin) % GUIDAQ MATLAB code for GuiDaq.fig % GUIDAQ, by itself, creates a new GUIDAQ or raises the existing % singleton*. % % H = GUIDAQ returns the handle to a new GUIDAQ or the handle to % the existing singleton*. % % GUIDAQ('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in GUIDAQ.M with the given input arguments. % % GUIDAQ('Property','Value',...) creates a new GUIDAQ or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before GuiDaq_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to GuiDaq_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help GuiDaq -% Last Modified by GUIDE v2.5 24-Aug-2018 16:39:21 +% Last Modified by GUIDE v2.5 25-Dec-2018 15:48:30 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @GuiDaq_OpeningFcn, ... 'gui_OutputFcn', @GuiDaq_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before GuiDaq is made visible. function GuiDaq_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to GuiDaq (see VARARGIN) % Choose default command line output for GuiDaq handles.output = hObject; % Update handles structure guidata(hObject, handles); % --- Outputs from this function are returned to the command line. function varargout = GuiDaq_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes during object creation, after setting all properties. function InstrMenu_CreateFcn(hObject, eventdata, handles) % hObject handle to InstrMenu (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: popupmenu controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function EditV1_CreateFcn(hObject, eventdata, handles) % hObject handle to EditV1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function EditV2_CreateFcn(hObject, eventdata, handles) % hObject handle to EditV2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function EditV2V1_CreateFcn(hObject, eventdata, handles) % hObject handle to EditV2V1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function EditH1_CreateFcn(hObject, eventdata, handles) % hObject handle to EditH1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function EditH2_CreateFcn(hObject, eventdata, handles) % hObject handle to EditH2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function EditH2H1_CreateFcn(hObject, eventdata, handles) % hObject handle to EditH2H1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function AnalyzeMenu_CreateFcn(hObject, eventdata, handles) % hObject handle to AnalyzeMenu (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: popupmenu controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function SelTrace_CreateFcn(hObject, eventdata, handles) % hObject handle to SelTrace (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: popupmenu controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function BaseDir_CreateFcn(hObject, eventdata, handles) % hObject handle to BaseDir (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function SessionName_CreateFcn(hObject, eventdata, handles) % hObject handle to SessionName (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function FileName_CreateFcn(hObject, eventdata, handles) % hObject handle to FileName (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end -% --- Executes on button press in record. -function record_Callback(hObject, eventdata, handles) -% hObject handle to record (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -%Takes the data from the fit -try - h_main_plot=getappdata(0,'h_main_plot'); - fit_meta_data=getappdata(h_main_plot,'fit_meta_data'); - - f=fit_meta_data(1); - lw=fit_meta_data(2); - Q=fit_meta_data(3); -catch - error('No fit parameters found') -end - -%Standardized save path -save_path=[handles.Drive_Letter,':\Measurement Campaigns\']; - -%Checks if a session name and file name is given -if ~isstr(get(handles.SessionName,'string')) - error('No session name given') -elseif ~isstr(get(handles.FileName,'string')) - error('No file name given') -end - -%Puts the date in front of the session name -session_name=[datestr(now,'yyyy-mm-dd '),... - get(handles.SessionName,'string'),'\']; - -%Makes the path if it does not exist -if ~exist([save_path,session_name],'dir') - mkdir(save_path,session_name); -end - -%Full path -final_path=[save_path,session_name,'Q factor','.txt']; - -%Creates the file if it does not exist, otherwise opens the file -if ~exist(final_path,'file') - fileID=fopen(final_path,'w'); - %Creates headers in the file - fmt=['%s\t%s\t%s\t\t%s\t%s\t\r\n']; - fprintf(fileID,fmt,'Beam#','f(MHz)','Q(10^6)','Q*f(10^14)','lw'); -else - fileID=fopen(final_path,'a'); -end - -%Formatting string -fmt=['%s\t%3.3f\t%3.3f\t\t%3.3f\t\t%3.3f\r\n']; -tag=get(handles.edit_tag,'string'); -fprintf('Data saved in %s',final_path); -%Reshapes the data in appropriate units -fprintf(fileID,fmt,tag{1},f/1e6,Q/1e6,Q*f/1e14,lw); -fclose(fileID); - -function edit_tag_Callback(hObject, eventdata, handles) -% hObject handle to edit_tag (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hints: get(hObject,'String') returns contents of edit_tag as text -% str2double(get(hObject,'String')) returns contents of edit_tag as a double - % --- Executes during object creation, after setting all properties. function edit_tag_CreateFcn(hObject, eventdata, handles) % hObject handle to edit_tag (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end -% --- Executes on button press in Subtract_BG. -function Subtract_BG_Callback(hObject, eventdata, handles) -% hObject handle to Subtract_BG (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of Subtract_BG -h_main_plot=getappdata(0,'h_main_plot'); -if (get(hObject,'Value')==1) - set(hObject, 'BackGroundColor',[0,1,.2]); - y_data=getappdata(h_main_plot,'y_data')-getappdata(h_main_plot,'y_BG'); -else - set(hObject, 'BackGroundColor',[0.941,0.941,0.941]); - y_data=getappdata(h_main_plot,'y_data')+getappdata(h_main_plot,'y_BG'); -end -setappdata(h_main_plot,'y_data',y_data); -update_axes - - -% --- Executes on button press in togglebutton9. -function togglebutton9_Callback(hObject, eventdata, handles) -% hObject handle to togglebutton9 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of togglebutton9 % --- Executes during object creation, after setting all properties. function figure1_CreateFcn(hObject, eventdata, handles) % hObject handle to figure1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % --- Executes during object creation, after setting all properties. function DestTrc_CreateFcn(hObject, eventdata, handles) % hObject handle to DestTrc (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: popupmenu controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end - - -% --- Executes when selected object is changed in uipanel1. -function uipanel1_SelectionChangedFcn(hObject, eventdata, handles) -% hObject handle to the selected object in uipanel1 -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) diff --git a/GUIs/GuiScope.mlapp b/GUIs/GuiScope.mlapp index ff1659b..f548da6 100644 Binary files a/GUIs/GuiScope.mlapp and b/GUIs/GuiScope.mlapp differ