function [MagnetSetpoints, MagnetMonitors, BPMMonitors, MagnetSetpointsEnd, FileName] = monmags(varargin) %MONMAGS - Monitors all magnet power supplies and plots various statistics % % [MagnetSetpoints, MagnetMonitors, BPMMonitors, MagnetSetpointsEnd] = monmags(FileName, PlotDataFlag, UnitsFlag) % [MagnetSetpoints, MagnetMonitors, BPMMonitors, MagnetSetpointsEnd] = monmags(FileName, t, UnitsFlag) % % INPUTS % 1. FileName - file to load or save data {Default or []: prompt for a filename} % 2. PlotDataFlag - 0 -> get, save and plot data {Default: prompt for input} % 1 -> plot all families (data coming from a file) % 2 -> plot one family (data coming from a file) % t - time vector (see help getpv for more details) {Default: prompt for input} % 3. UnitsFlag ('Hardware' or 'Physics') - Just for plotting. {Default: default units when the data was taken} % 4. 'NoDisplay' - read or save the data file without plotting the result (just for getting data). % 5. 'Raw2Real' - if in hardware units, a raw2real conversion is make before plotting (no change is made to the measured data). % % OUTPUTS % 1. MagnetSetpoints - Cell array of magnet setpoints at the start of the test % 2. MagnetMonitors - Cell array of magnets monitors sampled according to the vector t % 3. BPMMonitors - Cell array of BPMs % 4. MagnetSetpointsEnd - Cell array of magnet setpoints at the end of the test % % NOTE % 1. Input order does not matter. All inputs are optional. % 2. Make sure the sample period is long enough to acquirer the data. It's % best to test on a few samples first (3 is points in the minimum). % 3. Orbits are also monitored. Use monbpm to just monitor the orbit. % % EXAMPLES % 1. To plot data in physics units (prompt for the file): % monmags('physics', 1); % 2. To get data for 3 minutes at 1 sample/second, save to filename=magdata101.mat (in % the current directory), and plot in default units: % monmags('magdata101',0:1:180); % % Written by Greg Portmann DisplayFlag = 1; FileName = -1; ArchiveFlag = -1; UnitsFlag = ''; PlotDataFlag = []; t = []; DirectoryName = ''; MagnetSetpoints =[]; MagnetMonitors = []; BPMMonitors = []; MagnetSetpointsEnd = []; Raw2RealFlag = 0; for i = length(varargin):-1:1 if isstruct(varargin{i}) % Remove varargin(i) = []; elseif iscell(varargin{i}) % Remove varargin(i) = []; elseif strcmpi(varargin{i},'struct') % Remove varargin(i) = []; elseif strcmpi(varargin{i},'numeric') % Remove varargin(i) = []; elseif strcmpi(varargin{i},'Display') DisplayFlag = 1; varargin(i) = []; elseif strcmpi(varargin{i},'NoDisplay') DisplayFlag = 0; varargin(i) = []; elseif strcmpi(varargin{i},'Physics') UnitsFlag = varargin{i}; varargin(i) = []; elseif strcmpi(varargin{i},'Raw2Real') Raw2RealFlag = 1; varargin(i) = []; elseif strcmpi(varargin{i},'Hardware') UnitsFlag = varargin{i}; varargin(i) = []; end end for i = length(varargin):-1:1 if ischar(varargin{i}) FileName = varargin{i}; if strcmpi(FileName,'Archive') PlotDataFlag = 0; ArchiveFlag = 1; if length(varargin) > i % Look for a filename as the next input if ischar(varargin{i+1}) FileName = varargin{i+1}; varargin(i+1) = []; end end varargin(i) = []; elseif strcmpi(varargin{i},'NoArchive') ArchiveFlag = 0; varargin(i) = []; end elseif isnumeric(varargin{i}) if length(varargin{i}) == 1 PlotDataFlag = varargin{i}; else PlotDataFlag = 0; t = varargin{i}; end varargin(i) = []; end end if isempty(PlotDataFlag) if FileName == -1 ButtonNumber = menu('What would you like to do?', 'Get New Data','Plot Data From a File','Plot 1 Family From a File','Cancel'); switch ButtonNumber case 1 PlotDataFlag = 0; case 2 PlotDataFlag = 1; case 3 PlotDataFlag = 2; otherwise fprintf(' monmags cancelled\n'); return end else if exist(FileName) || exist([FileName,'.mat']) PlotDataFlag = 1; else PlotDataFlag = 0; end end end % Get file for plotting if (isempty(FileName) || isequal(FileName,-1)) && PlotDataFlag > 0 DirectoryName = getfamilydata('Directory','DataRoot'); DirectoryName = [DirectoryName, 'Magnets\']; [FileName, DirectoryName] = uigetfile('*.mat', 'Select a magnet file', DirectoryName); if isnumeric(FileName) fprintf(' monmags cancelled'); return end end if PlotDataFlag == 0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Get Data From The Control System % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if ArchiveFlag if isempty(FileName) FileName = appendtimestamp('magnetdata'); DirectoryName = [getfamilydata('Directory','DataRoot'), 'Magnets', filesep]; % Make sure default directory exists DirStart = pwd; [DirectoryName, ErrorFlag] = gotodirectory(DirectoryName); cd(DirStart); [FileName, DirectoryName] = uiputfile('*.mat', 'Select a Magnet Monitor File', [DirectoryName FileName]); if isequal(FileName,0) || isequal(DirectoryName,0) disp(' Magnet power supply monitoring canceled.'); FileName = ''; return end FileName = [DirectoryName, FileName]; elseif FileName == -1 FileName = appendtimestamp('magnetdata'); DirectoryName = [getfamilydata('Directory','DataRoot'), 'Magnets', filesep]; FileName = [DirectoryName, FileName]; end else if nargout == 0 fprintf(' No output or filename input, so there is no reason to monitor the power supplies\n'); end end % Setup the family cell array MagnetFamilies = findmemberof('Magnet'); MagnetFamilies = MagnetFamilies(:); % If a family has all zero status remove it for i = length(MagnetFamilies):-1:1 Status = family2status(MagnetFamilies{i}); if all(Status==0) MagnetFamilies(i) = []; end end MagnetFamilies = editlist(MagnetFamilies); MagnetFamilies = MagnetFamilies(:); iMagnets = length(MagnetFamilies); MagnetDeviceLists = cell(iMagnets,1); % BPM families BPMFamilies = findmemberof('BPM'); BPMFamilies = BPMFamilies(:); % If a family has all zero status remove it for i = length(BPMFamilies):-1:1 Status = family2status(BPMFamilies{i}); if all(Status==0) BPMFamilies(i) = []; end end BPMFamilies = editlist(BPMFamilies(:)); BPMFamilies = BPMFamilies(:); iBPMs = length(BPMFamilies); BPMDeviceLists = cell(iBPMs,1); if isempty(MagnetFamilies) && isempty(BPMFamilies) fprintf(' Nothing to monitor.\n'); return; end disp(' '); disp(' This function monitors the storage ring magnets and BPMs then computes various'); disp(' accuracy statistics. The sample period should be long enough to acquire '); disp(' all the magnets and BPMs in the storage ring. The storage ring must be static'); disp(' during this measurement (no magnet or insertion device changes, etc). This '); disp(' function open a lot of windows, ">> close all" closes all figure windows.'); disp(' '); if isempty(t) prompt = {'Input the sample period (seconds)', 'Input the total data collection time (seconds)'}; answer = inputdlg(prompt,'monmags',1,{'1','180'}); if isempty(answer) fprintf(' monmags cancelled\n'); return end T = str2num(answer{1}); EndTime = str2num(answer{2}); t = 0:T:EndTime; end if length(t) < 3 fprintf('\n The input time vector only has %d sample points.\n', length(t)); fprintf(' The function will run with 3 but you should have a lot (like 100 or more).\n'); fprintf(' monmags cancelled'); return end fprintf(' Taking data for about %.1f seconds . . . ', t(end)); TimeStart = gettime; % Get the setpoints at the start MagnetSetpoints = getsp(MagnetFamilies, MagnetDeviceLists, 'Struct'); % Get the monitors (first connect to the channels so that the first sample time is not longer than the rest) % Forcing units to hardware is necessary to speedup the data taking tmp = getam([MagnetFamilies; BPMFamilies], [MagnetDeviceLists; BPMDeviceLists], 'Hardware'); Monitors = getam([MagnetFamilies; BPMFamilies], [MagnetDeviceLists; BPMDeviceLists], t, 'Struct', 'Hardware'); % Get the setpoints at the end (hopefully it's the same as the start) MagnetSetpointsEnd = getsp(MagnetFamilies, MagnetDeviceLists, 'Struct'); % Split the monitors into magnets and BPMs MagnetMonitors = Monitors(1:iMagnets); BPMMonitors = Monitors(iMagnets+1:iMagnets+iBPMs); fprintf('finished in %.1f seconds\n', Monitors{1}.tout(end)); fprintf(' Average Sampling Period = %.3f seconds (Max= %.3f, Min=%.3f seconds)\n', mean(diff(Monitors{1}.tout)), max(diff(Monitors{1}.tout)), min(diff(Monitors{1}.tout))); % Convert to the default units for i = 1:length(Monitors) ActualUnits = getunits(Monitors{i}.FamilyName); if strcmpi(ActualUnits, 'Physics') Monitors{i} = hw2physics(Monitors{i}); end end % Convert to fields (more readable) MagnetMonitors = cell2field(MagnetMonitors); MagnetSetpoints = cell2field(MagnetSetpoints); BPMMonitors = cell2field(BPMMonitors); MagnetSetpointsEnd = cell2field(MagnetSetpointsEnd); % Save data in the proper directory if ArchiveFlag || ischar(FileName) [DirectoryName, FileName, Ext] = fileparts(FileName); DirStart = pwd; [DirectoryName, ErrorFlag] = gotodirectory(DirectoryName); if ErrorFlag fprintf('\n There was a problem getting to the proper directory!\n\n'); end save(FileName, 'MagnetMonitors', 'MagnetSetpoints', 'BPMMonitors', 'MagnetSetpointsEnd'); cd(DirStart); FileName = [DirectoryName FileName]; if DisplayFlag fprintf(' Magnet power supply data saved to %s\n', FileName); fprintf(' The total measurement time was %.2f minutes.\n', (gettime-TimeStart)/60); else return; end else FileName = ''; end else %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Get data from file and plot it % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% load([DirectoryName, FileName]); end if ~DisplayFlag return end %%%%%%%%%%%% % Plotting % %%%%%%%%%%%% % Convert to cell arrays if ~iscell(MagnetMonitors) if isempty(MagnetMonitors) MagnetMonitors = {}; MagnetSetpoints = {}; MagnetSetpointsEnd = {}; else MagnetMonitors = field2cell(MagnetMonitors); MagnetSetpoints = field2cell(MagnetSetpoints); MagnetSetpointsEnd = field2cell(MagnetSetpointsEnd); end end if ~iscell(BPMMonitors) if isempty(BPMMonitors) BPMMonitors = {}; else BPMMonitors = field2cell(BPMMonitors); end end if ~isempty(MagnetMonitors) tout = MagnetMonitors{1}.tout; elseif ~isempty(BPMMonitors) tout = BPMMonitors{1}.tout; else fprintf(' There is not data in this file to plot.\n'); return end if PlotDataFlag == 2 % Plot one family for i = 1:length(MagnetMonitors) FamilyList{i} = MagnetMonitors{i}.FamilyName; end for i = 1:length(BPMMonitors) FamilyList{i+length(MagnetMonitors)} = BPMMonitors{i}.FamilyName; end FamilyNumber = menu('Choose a family', FamilyList); if FamilyNumber <= length(MagnetMonitors) MagnetMonitors = MagnetMonitors(FamilyNumber); MagnetSetpoints = MagnetSetpoints(FamilyNumber); BPMMonitors = []; else BPMMonitors = BPMMonitors(FamilyNumber-length(MagnetMonitors)); MagnetMonitors = []; MagnetSetpoints = []; end end % Plot all families for i = 1:length(MagnetMonitors) if strcmpi(UnitsFlag, 'Physics') MagnetMonitors{i} = hw2physics(MagnetMonitors{i}); MagnetSetpoints{i} = hw2physics(MagnetSetpoints{i}); elseif strcmpi(UnitsFlag, 'Hardware') MagnetMonitors{i} = physics2hw(MagnetMonitors{i}); MagnetSetpoints{i} = physics2hw(MagnetSetpoints{i}); end if Raw2RealFlag && strcmpi(MagnetMonitors{i}.Units, 'Hardware') MagnetMonitors{i} = raw2real(MagnetMonitors{i}); MagnetSetpoints{i} = raw2real(MagnetSetpoints{i}); end a = unique(MagnetMonitors{i}.Data, 'rows'); if size(a,1) == 1 % Single power supply or ganged power supply figure; subplot(2,1,1); hist(MagnetMonitors{i}.Data(1,:),200); title(sprintf('%s: SP=%g, mean(AM)=%g, SP-mean(AM)=%g', ... MagnetSetpoints{i}.FamilyName, ... MagnetSetpoints{i}.Data(1,1), ... mean(MagnetMonitors{i}.Data(1,:)), ... MagnetSetpoints{i}.Data(1,1) - mean(MagnetMonitors{i}.Data(1,:))), 'FontSize',8); xlabel(MagnetMonitors{i}.UnitsString,'FontSize',8); subplot(2,1,2); plot(MagnetMonitors{i}.tout, MagnetMonitors{i}.Data(1,:)); title(sprintf('std(AM)=%.3g, max(AM-mean(AM))=%.3g', ... std(MagnetMonitors{i}.Data(1,:)), ... max(abs(MagnetMonitors{i}.Data(1,:) - mean(MagnetMonitors{i}.Data(1,:))))), 'FontSize',8); ylabel(MagnetMonitors{i}.UnitsString,'FontSize',8); xlabel('Time [Seconds]','FontSize',8); addlabel(1,0,sprintf('%s', datestr(MagnetMonitors{i}.TimeStamp))); orient tall else % Independent power supplies PlotBySector = 1; ElementList = dev2elem(MagnetMonitors{i}.FamilyName, MagnetMonitors{i}.DeviceList); [Sector, Nsectors, Ndevices] = sectorticks(MagnetMonitors{i}.DeviceList); AMmean = mean(MagnetMonitors{i}.Data,2); AMstd = std(MagnetMonitors{i}.Data,0,2); %fprintf(' %s: mean(AM)=%7.3f Amps, SP-mean(AM)=%6.3f, std(AM)=%5.3f Amps\n', MagnetMonitors{i}.FamilyName, AMmean, MagnetSetpoints{i}.Data-AMmean, AMstd); figure; subplot(4,1,1); if PlotBySector bar(Sector, AMmean); xaxis([1 Nsectors+1]) set(gca,'XTick',1:Nsectors); else bar(ElementList, AMmean); end title(sprintf('%s Family (Units are in %s)', MagnetMonitors{i}.FamilyName, MagnetMonitors{i}.UnitsString)); ylabel('mean(AM)','FontSize',8); %ylabel(sprintf('mean(AM) [%s]',MagnetMonitors{i}.UnitsString),'FontSize',8); grid on; ymax = max(AMmean); ymin = min(AMmean); extra = .05*(ymax-ymin); if extra < 1e6*eps extra = 1e6*eps; end if ~isnan(extra) yaxis([ymin-extra ymax+extra]); end subplot(4,1,2); if PlotBySector bar(Sector, MagnetSetpoints{i}.Data-AMmean); xaxis([1 Nsectors+1]) set(gca,'XTick',1:Nsectors); else bar(ElementList, MagnetSetpoints{i}.Data-AMmean); end ylabel('SP-mean(AM)','FontSize',8); %ylabel(sprintf('SP-mean(AM) [%s]',MagnetMonitors{i}.UnitsString),'FontSize',8); grid on; subplot(4,1,3); if PlotBySector bar(Sector, AMstd); xaxis([1 Nsectors+1]) set(gca,'XTick',1:Nsectors); else bar(ElementList, AMstd); end ylabel('std(AM)','FontSize',8); %ylabel(sprintf('std(AM) [%s]',MagnetMonitors{i}.UnitsString),'FontSize',8); grid on; subplot(4,1,4); % Outlier test clear AM_AMmeanMax for n = 1:size(AMmean,1) [tmp,j] = max(abs(MagnetMonitors{i}.Data(n,:)-AMmean(n))); AM_AMmeanMax(n,1) = MagnetMonitors{i}.Data(n,j)-AMmean(n); end if PlotBySector bar(Sector, AM_AMmeanMax); xaxis([1 Nsectors+1]) set(gca,'XTick',1:Nsectors); else bar(ElementList, AM_AMmeanMax); end ylabel('max(AM-mean(AM))','FontSize',8); % ylabel(sprintf('max(AM-mean(AM)) [%s]',MagnetMonitors{i}.UnitsString),'FontSize',8); if PlotBySector xlabel('Sector Number'); else xlabel('Element Number','FontSize',8); end grid on; addlabel(1,0,sprintf('%s', datestr(MagnetMonitors{i}.TimeStamp))); orient tall if PlotDataFlag == 2 % Plot more stuff figure; % Worst SP-AMmean subplot(3,1,1); [tmp, k] = max(abs(MagnetSetpoints{i}.Data-AMmean)); hist(MagnetMonitors{i}.Data(k,:), 200); title(sprintf('Worst SP-mean(AM): %s(%d,%d) SP=%g, mean(AM)=%g, SP-mean(AM)=%g', ... MagnetSetpoints{i}.FamilyName, ... MagnetSetpoints{i}.DeviceList(k,1), MagnetSetpoints{i}.DeviceList(k,2), ... MagnetSetpoints{i}.Data(k,1), ... AMmean(k), ... MagnetSetpoints{i}.Data(k,1) - AMmean(k)), ... 'FontSize',8); xlabel(MagnetMonitors{i}.UnitsString,'FontSize',8); a1 = axis; % Worst std(AM) subplot(3,1,2); [tmp, k] = max(AMstd); hist(MagnetMonitors{i}.Data(k,:), 200); title(sprintf('Worst std(AM): %s(%d,%d) SP=%g, mean(AM)=%g, std(AM)=%g', ... MagnetSetpoints{i}.FamilyName, ... MagnetSetpoints{i}.DeviceList(k,1), MagnetSetpoints{i}.DeviceList(k,2), ... MagnetSetpoints{i}.Data(k,1), ... AMmean(k), ... AMstd(k)), ... 'FontSize',8); xlabel(MagnetMonitors{i}.UnitsString,'FontSize',8); a2 = axis; % Worst max(AM-mean(AM)) subplot(3,1,3); [tmp, k] = max(abs(AM_AMmeanMax)); hist(MagnetMonitors{i}.Data(k,:), 200); title(sprintf('Worst max(AM-mean(AM)): %s(%d,%d) SP=%g, mean(AM)=%g, max(AM-mean(AM))=%g', ... MagnetSetpoints{i}.FamilyName, ... MagnetSetpoints{i}.DeviceList(k,1), MagnetSetpoints{i}.DeviceList(k,2), ... MagnetSetpoints{i}.Data(k,1), ... AMmean(k), ... AM_AMmeanMax(k)), ... 'FontSize',8); xlabel(MagnetMonitors{i}.UnitsString,'FontSize',8); a3 = axis; % Force all the x-axis to be the same %xaxis([min([a1(1) a2(1) a3(1)]) max([a1(2) a2(2) a3(2)])]); %subplot(3,1,1); %xaxis([min([a1(1) a2(1) a3(1)]) max([a1(2) a2(2) a3(2)])]); %subplot(3,1,2); %xaxis([min([a1(1) a2(1) a3(1)]) max([a1(2) a2(2) a3(2)])]); %addlabel(1,0,sprintf('%s', datestr(MagnetMonitors{i}.TimeStamp))); orient tall end end end for i = 1:length(BPMMonitors) if ~all(isnan(BPMMonitors{i}.Data)) if strcmpi(UnitsFlag, 'physics') BPMMonitors{i} = hw2physics(BPMMonitors{i}); elseif strcmpi(UnitsFlag, 'hardware') BPMMonitors{i} = physics2hw(BPMMonitors{i}); end if Raw2RealFlag && strcmpi(BPMMonitors{i}.Units, 'Hardware') BPMMonitors{i} = raw2real(BPMMonitors{i}); end ElementList = dev2elem(BPMMonitors{i}.FamilyName, BPMMonitors{i}.DeviceList); if PlotDataFlag == 2 % Plot more stuff figure; subplot(2,1,1); plot(BPMMonitors{i}.tout, BPMMonitors{i}.Data); title(sprintf('%s Family (Raw Orbit Data)', BPMMonitors{i}.FamilyName)); ylabel(sprintf('%s [%s]', BPMMonitors{i}.FamilyName, BPMMonitors{i}.UnitsString)); axis tight; grid on; end % Plot difference orbits Orbit0 = BPMMonitors{i}.Data(:,1); for j = size(BPMMonitors{i}.Data,2):-1:1 BPMMonitors{i}.Data(:,j) = BPMMonitors{i}.Data(:,j) - Orbit0; end if PlotDataFlag == 2 subplot(2,1,2); plot(BPMMonitors{i}.tout, BPMMonitors{i}.Data); title(sprintf('%s Family Difference Orbits from %s', BPMMonitors{i}.FamilyName, datestr(BPMMonitors{i}.TimeStamp,13))); ylabel(sprintf('%s [%s]', BPMMonitors{i}.FamilyName, BPMMonitors{i}.UnitsString)); axis tight; grid on; addlabel(1,0,sprintf('%s', datestr(BPMMonitors{i}.TimeStamp))); orient tall end % Difference orbits DiffOrbits = diff(BPMMonitors{i}.Data, 1, 2); %fprintf(' %s: mean(AM)=%7.3f Amps, SP-mean(AM)=%6.3f, std(AM)=%5.3f Amps\n', BPMMonitors{i}.FamilyName, AMmean, BPMSetpoints{i}.Data-AMmean, AMstd); AMmean = mean(BPMMonitors{i}.Data,2); AMmax = max(BPMMonitors{i}.Data,[],2); AMmin = min(BPMMonitors{i}.Data,[],2); AMstd = std(BPMMonitors{i}.Data,0,2); AMstddetrend = std(detrend(BPMMonitors{i}.Data'))'; figure; subplot(2,1,1); stairs(ElementList-.5, AMmean, 'b'); hold on stairs(ElementList-.5, AMmax, 'r'); stairs(ElementList-.5, AMmin, 'g'); hold off title(sprintf('%s Family (Deviation from the Starting Orbit)', BPMMonitors{i}.FamilyName)); ylabel(sprintf('Max/Mean/Min [%s]', BPMMonitors{i}.UnitsString)); grid on; subplot(2,1,2); stairs(ElementList-.5, AMstd, 'b'); hold on; stairs(ElementList-.5, AMstddetrend, 'r'); stairs(ElementList-.5, std(DiffOrbits,0,2)/sqrt(2), 'g'); hold off ylabel(sprintf('STD [%s]', BPMMonitors{i}.UnitsString)); xlabel('Element Number'); legend('Raw data','Linear trend removed','Difference Orbits/sqrt(2)', 0); grid on; addlabel(1,0,sprintf('%s', datestr(BPMMonitors{i}.TimeStamp))); orient tall end end % Convert back to structures if ~isstruct(MagnetMonitors) MagnetMonitors = cell2field(MagnetMonitors); MagnetSetpoints = cell2field(MagnetSetpoints); MagnetSetpointsEnd = cell2field(MagnetSetpointsEnd); end if ~isempty(BPMMonitors) if ~isstruct(BPMMonitors) BPMMonitors = cell2field(BPMMonitors); end end