source: MML/trunk/mml/measrespmat.m @ 4

Last change on this file since 4 was 4, checked in by zhangj, 10 years ago

Initial import--MML version from SOLEIL@2013

File size: 34.0 KB
Line 
1function S = measrespmat(varargin)
2%MEASRESPMAT - Measure a response matrix
3%
4%  For family name, device list inputs:
5%  S = measrespmat(MonitorFamily, MonitorDeviceList, ActuatorFamily, ActuatorDeviceList, ActuatorDelta, ModulationMethod, WaitFlag, ExtraDelay)
6%
7%  For data structure inputs:
8%  S = measrespmat(MonitorStruct, ActuatorStruct, ActuatorDelta, ModulationMethod, WaitFlag, ExtraDelay)
9%
10%  INPUTS
11%  1. MonitorFamily       - AcceleratorObjects family name for monitors
12%     MonitorDeviceList   - AcceleratorObjects device list for monitors (element or device)
13%                           (MonitorFamily and MonitorDeviceList can be cell arrays)
14%     or
15%     MonitorStruct can replace MonitorFamily and MonitorDeviceList
16%
17%  2. ActuatorFamily      - AcceleratorObjects family name for actuators
18%     ActuatorDeviceList  - AcceleratorObjects device list for actuators (element or device)
19%     or
20%     ActuatorStruct can replace ActuatorFamily and ActuatorDeviceList
21%
22%  3. ActuatorDelta    - Change in actuator {Default: getfamilydata('ActuatorFamily','Setpoint','DeltaRespMat')}
23%  4. ModulationMethod - Method for changing the ActuatorFamily
24%                       'bipolar' changes the ActuatorFamily by +/- ActuatorDelta/2 on each step {Default}
25%                       'unipolar' changes the ActuatorFamily from 0 to ActuatorDelta on each step
26%  5. WaitFlag - (see setpv for WaitFlag definitions) {Default: []}
27%                WaitFlag = -5 will override gets to manual mode
28%
29%  6. ExtraDelay - Extra time delay [seconds] after a setpoint change
30%
31%  7. 'Struct'  - Output will be a response matrix structure {Default for data structure inputs}
32%     'Numeric' - Output will be a numeric matrix            {Default for non-data structure inputs}
33%
34%  8. Optional override of the units:
35%     'Physics'  - Use physics  units
36%     'Hardware' - Use hardware units
37%
38%  9. Optional override of the mode:
39%     'Online' - Set/Get data online 
40%     'Model'  - Set/Get data on the model (same as 'Simulator')
41%     'Manual' - Set/Get data manually
42%
43%  10. 'Display'    - Prints status information to the command window {Default}
44%      'NoDisplay'  - Nothing is printed to the command window
45%
46%  11. 'MinimumBeamCurrent' - Minimum beam current before prompting for a refill
47%                             The current (as returned by getdcct) must follow the flag.
48%                             measbpmresp('MinimumBeamCurrent', 32.1)
49%                             will pause at a beam current of 32.1 and prompt for a refill.
50%
51%  OUTPUTS
52%  1. S = Response matrix
53%
54%     For stucture outputs:
55%     S(Monitor, Actuator).Data - Response matrix
56%                         .Monitor - Monitor data structure (starting orbit)
57%                         .Monitor1 - First  data point matrix
58%                         .Monitor2 - Second data point matrix
59%                         .Actuator - Corrector data structure
60%                         .ActuatorDelta - Corrector kick vector
61%                         .GeV - Electron beam energy
62%                         .ModulationMethod - 'unipolar' or 'bipolar'
63%                         .WaitFlag - Wait flag used when acquiring data
64%                         .ExtraDelay - Extra time delay
65%                         .TimeStamp - Matlab clock at the start of each actuator family
66%                         .CreatedBy
67%                         .DCCT
68%
69%  NOTES
70%  1. If MonitorFamily and MonitorDeviceList are cell arrays, then S is a cell array of response matrices.
71%  2. ActuatorFamily, ActuatorDeviceList, ActuatorDelta, ModulationMethod, WaitFlag are not cell arrrays.
72%  3. If ActuatorDeviceList is empty, then the entire family is change together.
73%  4. Bipolar mode changes the actuator by +/- ActuatorDelta/2
74%  5. Unipolar mode changes the actuator by ActuatorDelta
75%  6. Return values are MonitorChange/ActuatorDelta (normalized)
76%  7. When using cell array inputs don't mix structure data inputs with non-structure data
77%
78%  EXAMPLES
79%  1. 2x2 tune response matrix for Q7 and Q9 families (delay for tune matrix will need to be adjusted):
80%     TuneRmatrix = [measrespmat('TUNE',[1;2],'Q7',[],.5,'unipolar') ...
81%                    measrespmat('TUNE',[1;2],'Q9',[],.5,'unipolar')];
82%
83%  2. Orbit response matrix for all the horizontal correctors (+/-1 amp kick amplitude):
84%     Smat = measrespmat({'BPMx','BPMz'}, {getlist('BPMx'),getlist('BPMz')}, 'HCOR', ...
85%                                          getlist('HCOR'),1,'bipolar',-2);
86%     The output is stored in a cell array.  Smat{1} is the horizontal plane and Smat{2} is the vertical cross plane.
87%
88%  3. Orbit response matrix for all the horizontal correctors (Default kick amplitude):
89%     Smat = measrespmat(getx('Struct'), getsp('HCOR','struct'));
90
91%
92%  Written by Gregory J. Portmann
93%  Modified By Laurent S. Nadolski
94
95% Initialize
96ActuatorDelta = [];
97ActuatorDeviceList = [];
98ModulationMethod = 'bipolar';
99WaitFlag = [];
100WaitFlagMonitor = 0;
101ExtraDelay = 0;
102StructOutputFlag = 0;
103NumericOutputFlag = 0;
104DisplayFlag = 1;
105ModeFlagCell = {};
106UnitsFlagCell = {};
107DCCTStopFlag = 0;
108
109InputFlags = {};
110for i = length(varargin):-1:1
111    if isstruct(varargin{i})
112        % Ignor structures
113    elseif iscell(varargin{i})
114        % Ignor cells
115    elseif strcmpi(varargin{i},'Struct')
116        StructOutputFlag = 1;
117        varargin(i) = [];
118    elseif strcmpi(varargin{i},'Numeric')
119        NumericOutputFlag = 1;
120        StructOutputFlag = 0;
121        varargin(i) = [];
122    elseif strcmpi(varargin{i},'Simulator') || strcmpi(varargin{i},'Model')
123        ModeFlagCell = varargin(i);
124        InputFlags = [InputFlags varargin(i)];
125        varargin(i) = [];
126    elseif strcmpi(varargin{i},'Online')
127        ModeFlagCell = varargin(i);
128        InputFlags = [InputFlags varargin(i)];
129        varargin(i) = [];
130    elseif strcmpi(varargin{i},'Manual')
131        ModeFlagCell = varargin(i);
132        InputFlags = [InputFlags varargin(i)];
133        varargin(i) = [];
134    elseif strcmpi(varargin{i},'Physics')
135        UnitsFlagCell = varargin(i);
136        InputFlags = [InputFlags varargin(i)];
137        varargin(i) = [];
138    elseif strcmpi(varargin{i},'Hardware')
139        UnitsFlagCell = varargin(i);
140        InputFlags = [InputFlags varargin(i)];
141        varargin(i) = [];
142    elseif strcmpi(varargin{i},'NoDisplay')
143        DisplayFlag = 0;
144        varargin(i) = [];
145    elseif strcmpi(varargin{i},'Display')
146        DisplayFlag = 1;
147        varargin(i) = [];
148    elseif strcmpi(varargin{i},'MinimumBeamCurrent')
149        DCCTStopFlag = 1;
150        DCCTStop = varargin{i+1};
151        varargin(i+1) = [];
152        varargin(i) = [];
153    end
154end
155
156
157if length(varargin) < 2
158    error('Not enough inputs')
159end
160
161
162
163% Find out if the inputs are data structures
164StructInputFlag = 0;
165if isstruct(varargin{1})
166    StructInputFlag = 1;
167elseif iscell(varargin{1})
168    if isstruct(varargin{1}{1})
169        StructInputFlag = 1;
170    end
171end
172
173
174if StructInputFlag
175    % S = measrespmat(MonitorStruct, ActuatorStruct, ActuatorDelta, ModulationMethod, WaitFlag, ExtraDelay)
176    if length(varargin) < 2
177        error('At least 2 inputs required in structure mode.');
178    end
179   
180    % Only change StructOutputFlag if 'numeric' is not on the input line
181    if ~NumericOutputFlag
182        StructOutputFlag = 1;
183    end
184   
185    MonitorStruct = varargin{1};
186    ActuatorStruct = varargin{2};
187    if ~isstruct(ActuatorStruct)
188        error('If monitors are data structures, then the actuator must also be a data structure.');
189    end
190   
191    if iscell(varargin{1})
192        for j = 1:length(MonitorStruct)
193            if ~isstruct(MonitorStruct{j})
194                error('All monitors in the cell must be data structures or not (mixing methods not allowed).');
195            end
196           
197            MonitorFamily{j} = MonitorStruct{j}.FamilyName;
198            MonitorDeviceList{j} = MonitorStruct{j}.DeviceList;
199        end
200    else
201        MonitorFamily = MonitorStruct.FamilyName;
202        MonitorDeviceList = MonitorStruct.DeviceList;
203    end
204    ActuatorFamily = ActuatorStruct.FamilyName;
205    ActuatorDeviceList = ActuatorStruct.DeviceList;
206    if length(varargin) >= 3
207        ActuatorDelta = varargin{3};
208    end
209    if length(varargin) >= 4
210        ModulationMethod = varargin{4};
211    end
212    if length(varargin) >= 5
213        WaitFlag = varargin{5};
214    end
215    if length(varargin) >= 6
216        ExtraDelay = varargin{6};
217    end
218else
219    % S = measrespmat(MonitorFamily, MonitorDeviceList, ActuatorFamily, ActuatorDeviceList, ActuatorDelta, ModulationMethod, WaitFlag, ExtraDelay)
220    if length(varargin) < 3
221        error('At least 3 inputs required ');
222    end
223    MonitorFamily = varargin{1};
224    MonitorDeviceList = varargin{2};
225    ActuatorFamily = varargin{3};
226    if length(varargin) >= 4
227        ActuatorDeviceList = varargin{4};
228    end
229    if length(varargin) >= 5
230        ActuatorDelta = varargin{5};
231    end
232    if length(varargin) >= 6
233        ModulationMethod = varargin{6};
234    end
235    if length(varargin) >= 7
236        WaitFlag = varargin{7};
237    end
238    if length(varargin) >= 8
239        ExtraDelay = varargin{8};
240    end
241end
242
243% Remove extra delay for model
244if any(strcmpi('Model', ModeFlagCell)) || any(strcmpi('Simulator', ModeFlagCell))
245    ExtraDelay = 0;
246end
247
248if isempty(ModulationMethod)
249    ModulationMethod = 'bipolar';
250elseif ~strcmpi(ModulationMethod, 'unipolar') && ~strcmpi(ModulationMethod, 'bipolar')
251    error('ModulationMethod must be ''unipolar'' or ''bipolar''');
252end
253
254
255% Force to be a cells of equal length
256if ~iscell(MonitorFamily)
257    MonitorFamily = {MonitorFamily};
258end
259if ~iscell(MonitorDeviceList)
260    MonitorDeviceList = {MonitorDeviceList};
261end
262if ~iscell(ActuatorFamily)
263    ActuatorFamily = {ActuatorFamily};
264end
265if isempty(ActuatorDeviceList)
266    for i = 1:length(ActuatorFamily)
267        ActuatorDeviceList{i} = [];
268    end
269elseif ~iscell(ActuatorDeviceList)
270    ActuatorDeviceList = {ActuatorDeviceList};
271end
272if isempty(ActuatorDelta)
273    for i = 1:length(ActuatorFamily)
274        ActuatorDelta{i} = [];
275    end
276elseif ~iscell(ActuatorDelta)
277    ActuatorDelta = {ActuatorDelta};
278end
279
280
281% Force column for monitors and rows for actuators
282MonitorFamily = MonitorFamily(:);
283MonitorDeviceList = MonitorDeviceList(:);
284ActuatorFamily = ActuatorFamily(:)';
285ActuatorDeviceList = ActuatorDeviceList(:)';
286ActuatorDelta = ActuatorDelta(:)';
287
288
289% Check length of cell inputs
290if length(MonitorFamily) ~= length(MonitorDeviceList)
291    error('The length of MonitorFamily (cell) must equal the length of MonitorDeviceList (cell)');
292end
293if length(ActuatorFamily) ~= length(ActuatorDeviceList)
294    error('The length of ActuatorFamily (cell) must equal the length of ActuatorDeviceList (cell)');
295end
296if length(ActuatorFamily) ~= length(ActuatorDelta)
297    error('The length of ActuatorFamily (cell) must equal the length of ActuatorDelta (cell)');
298end
299
300
301% Manual mode for monitors
302WaitFlagMonitor = WaitFlag;
303if WaitFlag == -5
304    WaitFlag = 0;
305end
306
307
308% First get all defaults and do some error checking
309for iActFam = 1:length(ActuatorFamily)
310    % Convert element list to a device list if necessary
311    if size(ActuatorDeviceList{iActFam},2) == 1
312        ActuatorDeviceList{iActFam} = elem2dev(ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam});
313    end
314   
315    % Get ActuatorDelta if empty
316    if isempty(ActuatorDelta{iActFam})
317        % Find the delta from the AO (.DeltaRespMat is always hardware!!!)
318        ActuatorDelta{iActFam} = getfamilydata(ActuatorFamily{iActFam}, 'Setpoint', 'DeltaRespMat', ActuatorDeviceList{iActFam});
319        if isempty(ActuatorDelta{iActFam})
320            error(sprintf('%s.Setpoint.DeltaRespMat field must be set properly',ActuatorFamily{iActFam}));
321        end
322       
323        % Check if ActuatorDelta needs a units conversion
324        if strcmpi(UnitsFlagCell,{'Physics'})
325            % Check over-ride
326            ActuatorDelta{iActFam} = hw2physics(ActuatorFamily{iActFam}, 'Setpoint', ActuatorDelta{iActFam}, ActuatorDeviceList{iActFam}, ModeFlagCell{:});
327        else
328            % Check family
329            Units = getfamilydata(ActuatorFamily{iActFam}, 'Setpoint', 'Units');
330            if strcmpi(Units, 'Physics')
331                ActuatorDelta{iActFam} = hw2physics(ActuatorFamily{iActFam}, 'Setpoint', ActuatorDelta{iActFam}, ActuatorDeviceList{iActFam}, ModeFlagCell{:});
332            end
333        end
334        %if strcmpi(UnitsFlagCell,{'Hardware'}) & strcmpi(Units, 'Physics')
335        %    ActuatorDelta{iActFam} = physics2hw(ActuatorFamily{iActFam}, 'Setpoint', ActuatorDelta{iActFam}, ActuatorDeviceList{iActFam}, ModeFlagCell{:});       
336        %end
337    end
338    if isempty(ActuatorDelta{iActFam})
339        error('ActuatorDelta is empty.  Must be an input or in the family structure (.DeltaRespMat in hardware units)');
340    end
341    if ~isnumeric(ActuatorDelta{iActFam})
342        error('ActuatorDelta must be numeric.');
343    end
344   
345    % Force ActuatorDelta to be a column vector
346    ActuatorDelta{iActFam} = ActuatorDelta{iActFam}(:);
347   
348    % Check for entire family
349    if isempty(ActuatorDeviceList{iActFam})
350        % Set the entire family at once
351        iActDeviceTotal{iActFam} = 1;
352       
353        % Expand a scalar to all devices
354        if length(ActuatorDelta{iActFam}) == 1
355            % OK
356        elseif length(ActuatorDelta{iActFam}) == length(family2dev(ActuatorFamily{iActFam}))
357            % OK
358        else
359            error('ActuatorDelta must be a scalar or equal in length to the number of devices');
360        end
361    else
362        iActDeviceTotal{iActFam} = size(ActuatorDeviceList{iActFam},1);
363       
364        % Expand a scalar to all devices if scalar
365        if length(ActuatorDelta{iActFam}) == 1
366            ActuatorDelta{iActFam} = ActuatorDelta{iActFam} * ones(iActDeviceTotal{iActFam},1);
367        end
368        % Size of ActuatorDelta must equal total number of devices
369        if length(ActuatorDelta{iActFam}) ~= iActDeviceTotal{iActFam}
370            error('ActuatorDelta must be a scalar or equal in length to the number of devices');
371        end
372    end
373   
374    % Check for zeros
375    if any(ActuatorDelta{iActFam} == 0)
376        error('At least one the actuator deltas is zero.');
377    end
378
379    % Get initial actuator values
380    ActuatorStart{iActFam} = getsp(ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}, 'Struct', InputFlags{:});
381    InitActuator = ActuatorStart{iActFam}.Data;
382   
383    % Check actuator limits
384    if strcmpi(ModulationMethod, 'unipolar')
385        % unipolar measurement
386        [LimitFlag, LimitList] = checklimits(ActuatorFamily{iActFam}, InitActuator+ActuatorDelta{iActFam}, ActuatorDeviceList{iActFam}, UnitsFlagCell{:});
387        if LimitFlag
388            MagnetString = sprintf('%s(%d,%d)=%f, Delta=%f', ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(LimitList(1),:), InitActuator(LimitList(1)), ActuatorDelta{iActFam}(LimitList(1)));
389            error(['Actuator limit would be exceeded (Setpoint+Delta) (', MagnetString, ')']);
390        end
391    elseif strcmpi(ModulationMethod, 'bipolar')
392        % bipolar measurement
393        [LimitFlag, LimitList] = checklimits(ActuatorFamily{iActFam}, InitActuator-ActuatorDelta{iActFam}/2, ActuatorDeviceList{iActFam}, UnitsFlagCell{:});
394        if LimitFlag
395            if isempty(ActuatorDeviceList{:}),  ActuatorDeviceList{:} = [1 1]; end
396            MagnetString = sprintf('%s(%d,%d)=%f, Delta=%f', ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(LimitList(1),:), InitActuator(LimitList(1)), ActuatorDelta{iActFam}(LimitList(1)));
397            error(['Actuator limit would be exceeded (Setpoint-Delta/2) (', MagnetString, ')']);
398        end
399        [LimitFlag, LimitList] = checklimits(ActuatorFamily{iActFam}, InitActuator+ActuatorDelta{iActFam}/2, ActuatorDeviceList{iActFam}, UnitsFlagCell{:});
400        if LimitFlag
401            MagnetString = sprintf('%s(%d,%d)=%f, Delta=%f', ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(LimitList(1),:), InitActuator(LimitList(1)), ActuatorDelta{iActFam}(LimitList(1)));
402            error(['Actuator limit would be exceeded (Setpoint+Delta/2) (', MagnetString, ')']);
403        end
404    end
405end
406
407
408if DisplayFlag
409    fprintf('   Measuring response using a %s actuator method\n', lower(ModulationMethod));
410end
411
412% Begin main loop over actuators
413StopNow = 0;
414for iActFam = 1:length(ActuatorFamily)
415    t0 = clock;
416    clear R;
417       
418    % Get initial monitor values
419    if StructOutputFlag
420        if WaitFlagMonitor == -5
421            MonitorStart = getam(MonitorFamily, MonitorDeviceList, 'Struct', 'Manual', UnitsFlagCell{:});
422        else
423            MonitorStart = getam(MonitorFamily, MonitorDeviceList, 'Struct', InputFlags{:});
424        end
425        if isfamily('DCCT')
426            DCCTStart = getdcct(ModeFlagCell{:});
427        else
428            DCCTStart = NaN;
429        end
430    end
431   
432    % Get initial actuator values
433    InitActuator = ActuatorStart{iActFam}.Data;
434   
435    % Just to display common names (empty if not using common names)
436    CommonNameList = family2common(ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam});
437
438    % Iterate on each actuator in the device list
439    if DisplayFlag % & ~isempty(ActuatorDeviceList{iActFam})  %iActDeviceTotal{iActFam} > 1
440        fprintf('\n   %s family response matrix\n', ActuatorFamily{iActFam});
441    end
442   
443    % Individual actuator loop
444    for iActDevice = 1:iActDeviceTotal{iActFam}
445        if ~isempty(CommonNameList)
446            CommonName = [deblank(CommonNameList(iActDevice,:)), ' '];
447            if strcmpi(deblank(CommonName), ActuatorFamily{iActFam})
448                CommonName = '';
449            end
450        end
451
452        % Remove the CommonName for now
453        CommonName = '';
454
455        % Step actuator down for bipolar
456        try
457            if strcmpi(ModulationMethod, 'bipolar')
458                if isempty(ActuatorDeviceList{iActFam})
459                    if DisplayFlag
460                        fprintf('   %s family nominal value is %f [%s]\n', ActuatorFamily{iActFam}, InitActuator(1), ActuatorStart{iActFam}.UnitsString);
461                        fprintf('   Changing family by %+f [%s] from nominal\n', -ActuatorDelta{iActFam}(1)/2, ActuatorStart{iActFam}.UnitsString);
462                        drawnow;
463                    end
464                    DeltaActuator =                InitActuator-ActuatorDelta{iActFam}/2;
465                    setsp(ActuatorFamily{iActFam}, DeltaActuator, ActuatorDeviceList{iActFam}, WaitFlag, InputFlags{:});
466                else
467                    if DisplayFlag
468                        fprintf('   %d. %s%s(%d,%d) nominal value is %f [%s]\n', iActDevice, CommonName, ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(iActDevice,:), InitActuator(iActDevice), ActuatorStart{iActFam}.UnitsString);
469                        fprintf('   %d. Changing actuator by %+f [%s] from nominal\n', iActDevice, -ActuatorDelta{iActFam}(iActDevice)/2, ActuatorStart{iActFam}.UnitsString);
470                        drawnow;
471                    end
472                    DeltaActuator =                InitActuator(iActDevice)-ActuatorDelta{iActFam}(iActDevice)/2;
473                    setsp(ActuatorFamily{iActFam}, DeltaActuator, ActuatorDeviceList{iActFam}(iActDevice,:), WaitFlag, InputFlags{:});
474                end
475            elseif strcmpi(ModulationMethod, 'unipolar')
476                if isempty(ActuatorDeviceList{iActFam})
477                    DeltaActuator = InitActuator(1);
478                else
479                    DeltaActuator = InitActuator(iActDevice);
480                end
481                if DisplayFlag
482                    if isempty(ActuatorDeviceList{iActFam})
483                        fprintf('   %s family nominal value is %f [%s]\n', ActuatorFamily{iActFam}, InitActuator(1), ActuatorStart{iActFam}.UnitsString);
484                        %fprintf('   No change to actuator\n');
485                        drawnow;
486                    else
487                        fprintf('   %d. %s%s(%d,%d) nominal value is %f [%s]\n', iActDevice, CommonName, ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(iActDevice,:), InitActuator(iActDevice), ActuatorStart{iActFam}.UnitsString);
488                        %fprintf('   %d. No change to actuator\n', iActDevice);
489                        drawnow;
490                    end
491                end
492            end
493           
494        catch err
495            fprintf('   %s\n', lasterr);
496            if isempty(ActuatorDeviceList{iActFam})
497                FamilyMessage = sprintf('An error occurred setting %s to %f [%s].\n', ActuatorFamily{iActFam}, InitActuator(iActDevice), DeltaActuator, ActuatorStart{iActFam}.UnitsString);
498            else
499                FamilyMessage = sprintf('An error occurred setting %s(%d,%d) to %f [%s].\n', ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(iActDevice,:), DeltaActuator, ActuatorStart{iActFam}.UnitsString);
500            end
501            CommandInput = questdlg( ...
502                strvcat(FamilyMessage, ...
503                strvcat('Either manually varify that the magnet is at the proper setpoint', ...
504                strvcat('and continue measuring the response matrix or stop','the response matrix measurement?'))), ...
505                'MEASRESPMAT', ...
506                'Continue', ...
507                'Stop', ...
508                'Continue');
509            switch CommandInput
510                case 'Stop'
511                    error('Response matrix measurement stopped.');
512                    %S = {}
513                    %return;
514                case 'Continue'
515                    %keyboard
516            end
517        end
518
519        % Wait for signal processing if requested
520        sleep(ExtraDelay);
521
522        %if DisplayFlag
523        %    fprintf('   Recording data point #1\n'); drawnow;
524        %end
525
526        % Acquire data
527        if WaitFlagMonitor == -5
528            Xm = getam(MonitorFamily, MonitorDeviceList, 'Manual', UnitsFlagCell{:});
529        else
530            Xm = getam(MonitorFamily, MonitorDeviceList, InputFlags{:});
531        end
532
533        % Step actuator up
534        try
535            if strcmpi(ModulationMethod, 'bipolar')
536                if isempty(ActuatorDeviceList{iActFam})
537                    if DisplayFlag
538                        fprintf('   Changing family by %+f [%s] from nominal\n', ActuatorDelta{iActFam}(1)/2, ActuatorStart{iActFam}.UnitsString);
539                        drawnow;
540                    end
541                    DeltaActuator =                InitActuator+ActuatorDelta{iActFam}/2;
542                    setsp(ActuatorFamily{iActFam}, DeltaActuator, ActuatorDeviceList{iActFam}, WaitFlag, InputFlags{:});
543                else
544                    if DisplayFlag
545                        fprintf('   %d. Changing actuator by %+f [%s] from nominal\n', iActDevice, ActuatorDelta{iActFam}(iActDevice)/2, ActuatorStart{iActFam}.UnitsString);
546                        drawnow;
547                    end
548                    DeltaActuator =                InitActuator(iActDevice)+ActuatorDelta{iActFam}(iActDevice)/2;
549                    setsp(ActuatorFamily{iActFam}, DeltaActuator, ActuatorDeviceList{iActFam}(iActDevice,:), WaitFlag, InputFlags{:});
550                end
551            elseif strcmpi(ModulationMethod, 'unipolar')
552                if isempty(ActuatorDeviceList{iActFam})
553                    if DisplayFlag
554                        fprintf('   Changing family by %+f [%s] from nominal\n', ActuatorDelta{iActFam}(1), ActuatorStart{iActFam}.UnitsString);
555                        drawnow;
556                    end
557                    DeltaActuator =                InitActuator+ActuatorDelta{iActFam};
558                    setsp(ActuatorFamily{iActFam}, DeltaActuator, ActuatorDeviceList{iActFam}, WaitFlag, InputFlags{:});
559                else
560                    if DisplayFlag
561                        fprintf('   %d. Changing actuator by %+f [%s] from nominal\n', iActDevice, ActuatorDelta{iActFam}(iActDevice), ActuatorStart{iActFam}.UnitsString);
562                        drawnow;
563                    end
564                    DeltaActuator =                InitActuator(iActDevice)+ActuatorDelta{iActFam}(iActDevice);
565                    setsp(ActuatorFamily{iActFam}, DeltaActuator, ActuatorDeviceList{iActFam}(iActDevice,:), WaitFlag, InputFlags{:});
566                end
567            end
568        catch err
569            fprintf('   %s\n', lasterr);
570            if isempty(ActuatorDeviceList{iActFam})
571                FamilyMessage = sprintf('An error occurred setting %s to %f [%s].\n', ActuatorFamily{iActFam}, InitActuator(iActDevice), DeltaActuator, ActuatorStart{iActFam}.UnitsString);
572            else
573                FamilyMessage = sprintf('An error occurred setting %s(%d,%d) to %f [%s].\n', ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(iActDevice,:), DeltaActuator, ActuatorStart{iActFam}.UnitsString);
574            end
575            CommandInput = questdlg( ...
576                strvcat(FamilyMessage, ...
577                strvcat('Either manually varify that the magnet is at the proper setpoint', ...
578                strvcat('and continue measuring the response matrix or stop','the response matrix measurement?'))), ...
579                'MEASRESPMAT', ...
580                'Continue', ...
581                'Stop', ...
582                'Continue');
583            switch CommandInput
584                case 'Stop'
585                    error('Response matrix measurement stopped.');
586                    %S = {}
587                    %return;
588                case 'Continue'
589                    %keyboard
590            end
591        end
592
593        % Wait for signal processing if requested
594        sleep(ExtraDelay);
595
596        if DisplayFlag
597            %fprintf('   Recording data point #2\n'); drawnow;
598        end
599
600        % Acquire data
601        if WaitFlagMonitor == -5
602            Xp = getam(MonitorFamily, MonitorDeviceList, 'Manual', UnitsFlagCell{:});
603        else
604            Xp = getam(MonitorFamily, MonitorDeviceList, InputFlags{:});
605        end
606
607        % Restore actuators
608        try
609            if isempty(ActuatorDeviceList{iActFam})
610                DeltaActuator = InitActuator;
611                if WaitFlag == -2
612                    WaitFlagReset = -1;
613                else
614                    WaitFlagReset = WaitFlag;
615                end
616                setsp(ActuatorFamily{iActFam}, InitActuator, ActuatorDeviceList{iActFam}, WaitFlagReset, InputFlags{:});
617                if DisplayFlag
618                    if strcmpi(ActuatorStart{iActFam}.Mode, 'Manual')
619                        fprintf('   %s family reset\n', ActuatorFamily{iActFam});
620                    else
621                        FinalSP = getsp(ActuatorFamily{iActFam}, InputFlags{:});
622                        fprintf('   %s family reset to %f [%s]\n', ActuatorFamily{iActFam}, FinalSP(1), ActuatorStart{iActFam}.UnitsString);
623                    end
624                end
625            else
626                DeltaActuator = InitActuator(iActDevice);
627                if WaitFlag == -2
628                    WaitFlagReset = -1;
629                else
630                    WaitFlagReset = WaitFlag;
631                end
632                setsp(ActuatorFamily{iActFam}, InitActuator(iActDevice), ActuatorDeviceList{iActFam}(iActDevice,:), WaitFlagReset, InputFlags{:});
633                if DisplayFlag
634                    if strcmpi(ActuatorStart{iActFam}.Mode,'Manual')
635                        fprintf('   %d. %s%s(%d,%d) reset\n', iActDevice, CommonName, ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(iActDevice,:));
636                    else
637                        fprintf('   %d. %s%s(%d,%d) reset to %f [%s]\n', iActDevice, CommonName, ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(iActDevice,:), getsp(ActuatorFamily{iActFam},ActuatorDeviceList{iActFam}(iActDevice,:)), ActuatorStart{iActFam}.UnitsString);
638                    end
639                end
640            end
641            drawnow;
642        catch
643            fprintf('   %s\n', lasterr);
644            if isempty(ActuatorDeviceList{iActFam})
645                FamilyMessage = sprintf('An error occurred setting %s to %f [%s].\n', ActuatorFamily{iActFam}, InitActuator(iActDevice), DeltaActuator, ActuatorStart{iActFam}.UnitsString);
646            else
647                FamilyMessage = sprintf('An error occurred setting %s(%d,%d) to %f [%s].\n', ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam}(iActDevice,:), DeltaActuator, ActuatorStart{iActFam}.UnitsString);
648            end
649            CommandInput = questdlg( ...
650                strvcat(FamilyMessage, ...
651                strvcat('Either manually varify that the magnet is at the proper setpoint', ...
652                strvcat('and continue measuring the response matrix or stop','the response matrix measurement?'))), ...
653                'MEASRESPMAT', ...
654                'Continue', ...
655                'Stop', ...
656                'Continue');
657            switch CommandInput
658                case 'Stop'
659                    error('Response matrix measurement stopped.');
660                    %S = {}
661                    %return;
662                case 'Continue'
663                    %keyboard
664            end
665        end
666
667        if DisplayFlag && (iActDevice < iActDeviceTotal{iActFam})
668            fprintf('\n');
669        end
670       
671        % Compute differences
672        for iMonFam = 1:length(MonitorFamily)
673            if isempty(ActuatorDeviceList{iActFam})
674                % Compute response matrix columns
675                % For each magnet:  1. Divide by the change in amperes, like [Tune / Ampere]
676                %                   2. Scale each magnet by its fractional contribution in physics units (should use K*L, not just K)
677                if strcmpi(family2units(ActuatorFamily{iActFam},'Setpoint'),'Hardware')
678                    DeltaPhysics = hw2physics(ActuatorFamily{iActFam}, 'Setpoint', InitActuator+ActuatorDelta{iActFam}, ActuatorDeviceList{iActFam}, ModeFlagCell{:}) - hw2physics(ActuatorFamily{iActFam}, 'Setpoint', InitActuator, ActuatorDeviceList{iActFam}, ModeFlagCell{:});
679                else
680                    DeltaPhysics = ActuatorDelta{iActFam};
681                end
682               
683                % DeltaPhysics should be K*Leff (not just "K")
684                Leff = getleff(ActuatorFamily{iActFam}, ActuatorDeviceList{iActFam});
685               
686                % Zero Leff is trouble, just divide by the number of actuators
687                i = find(Leff==0);
688                Leff(i) = 1 / length(Leff);
689               
690                DeltaPhysics = DeltaPhysics .* Leff;
691               
692                % In order to backout the response at each magnet, assume that
693                % the response at each magnet is equal in physics units. 
694                DeltaMonitorPerPhysicsUnit = (Xp{iMonFam}-Xm{iMonFam}) / sum(DeltaPhysics);
695               
696                % Expand to each magnet
697                R{iMonFam} = DeltaMonitorPerPhysicsUnit * ones(1,length(DeltaPhysics));
698               
699                % When in hardware unit convert to delta monitor / ampere
700                if strcmpi(family2units(ActuatorFamily{iActFam},'Setpoint'),'Hardware')
701                    PhysicsUnitPerAmp = DeltaPhysics ./ ActuatorDelta{iActFam};
702                    for n = 1:length(DeltaPhysics)
703                        R{iMonFam}(:,n) = PhysicsUnitPerAmp(n) * R{iMonFam}(:,n);
704                    end
705                end
706               
707            else
708                % Just divide the monitor value by the actuator value
709                R{iMonFam}(:,iActDevice) = (Xp{iMonFam}-Xm{iMonFam}) / ActuatorDelta{iActFam}(iActDevice);
710            end
711           
712            % Save the measurements
713            Monitor1{iMonFam}(:,iActDevice) = Xm{iMonFam};
714            Monitor2{iMonFam}(:,iActDevice) = Xp{iMonFam};
715
716        end % iMonFam
717       
718        % If the beam current is too low, prompt for a refill
719        if DCCTStopFlag
720            if (getdcct - DCCTStop) < 0
721                CommandInput = questdlg( ...
722                    {sprintf('The present beam current is %f', getdcct), ...
723                    sprintf('A refill prompt was requested at %f', DCCTStop), ...
724                    '   ', ...
725                    'Your choices are:'
726                    sprintf('Continue - Continue and you will be prompted again a %f', DCCTStop), ...
727                    'Stop - Stop the measure right now', ...
728                    'Don''t ask again - Continue on without another interruption'}, ...
729                    'MEASRESPMAT', ...
730                    'Continue', ...
731                    'Stop', ...
732                    'Don''t ask again', 'Don''t ask again');
733                if isempty(CommandInput) || strcmp(CommandInput, 'Don''t ask again')
734                    DCCTStopFlag = 0;
735                elseif strcmp(CommandInput, 'Stop')
736                    StopNow = 1;
737                    break;
738                end
739            end
740        end
741   
742    end % iActDevice
743       
744    for iMonFam = 1:length(MonitorFamily)
745        if StructOutputFlag
746            S{iMonFam,iActFam}.Data = R{iMonFam};
747           
748            S{iMonFam,iActFam}.Monitor = MonitorStart{iMonFam};
749            S{iMonFam,iActFam}.Actuator = ActuatorStart{iActFam};
750            S{iMonFam,iActFam}.ActuatorDelta = ActuatorDelta{iActFam};
751           
752            S{iMonFam,iActFam}.Monitor1 = Monitor1{iMonFam};
753            S{iMonFam,iActFam}.Monitor2 = Monitor2{iMonFam};
754           
755            if ~strcmpi(MonitorStart{iMonFam}.Units, ActuatorStart{iActFam}.Units)
756                S{iMonFam,iActFam}.Units =  [MonitorStart{iMonFam}.Units, '/', ActuatorStart{iActFam}.Units];
757                fprintf('   Warning: Units are in a mixed mode');
758            else
759                S{iMonFam,iActFam}.Units = MonitorStart{iMonFam}.Units;
760            end
761            %S{iMonFam,iActFam}.UnitsString = ['[',MonitorStart{iMonFam}.UnitsString,']', '/', '[',ActuatorStart{iActFam}.UnitsString,']'];
762            S{iMonFam,iActFam}.UnitsString = [MonitorStart{iMonFam}.UnitsString, '/', ActuatorStart{iActFam}.UnitsString];
763
764            S{iMonFam,iActFam}.GeV = getenergy(ModeFlagCell{:});
765            S{iMonFam,iActFam}.TimeStamp = t0;
766            S{iMonFam,iActFam}.DCCT = DCCTStart;
767            S{iMonFam,iActFam}.ModulationMethod = ModulationMethod;
768            S{iMonFam,iActFam}.WaitFlag = WaitFlagMonitor;
769            S{iMonFam,iActFam}.ExtraDelay = ExtraDelay;
770            S{iMonFam,iActFam}.DataDescriptor = 'Response Matrix';
771            S{iMonFam,iActFam}.CreatedBy = 'measrespmat';
772            S{iMonFam,iActFam}.OperationalMode = getfamilydata('OperationalMode');
773        else
774            S{iMonFam,iActFam} = R{iMonFam};
775        end
776    end
777
778    if StopNow
779        break;
780    end
781
782end
783
784
785% For one family inputs, there is no need for a cell output
786if all(size(S) == [1 1])
787    S = S{1};
788end
789
Note: See TracBrowser for help on using the repository browser.