source: MML/trunk/machine/SOLEIL/StorageRing/measchroFBT.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: 17.9 KB
Line 
1function [Chromaticity, FileName] = measchro(varargin)
2%MEASCHRO -  measures the chromaticity function emperically
3%  Chrom         = measchro(DeltaRF, WaitFlag);
4%  ChromHardware = measchro(DeltaRF, WaitFlag, 'Hardware');
5%  ChromPhysics  = measchro(DeltaRF, WaitFlag, 'Physics');
6%  ChromStruct   = measchro(DeltaRF, WaitFlag, 'Struct');
7%
8%  INPUTS
9%  1. DeltaRF - Vector of master oscillator values to scan over
10%               {Default:  [-.4% -.2% 0 .2% .4%] energy change}
11%  2. WaitFlag >= 0, WaitFlag seconds before measuring the tune (sec)
12%               = -1, wait until the magnets are done ramping
13%               = -3, wait until the magnets are done ramping + a delay of 2.2*getfamilydata('TuneDelay') {default}
14%               = -4, wait until keyboard input
15%               = -5, input the tune measurement manually by keyboard input
16%  4. 'Hardware' - Returns chromaticity in hardware units (typically, Tune/MHz or Tune/MHz)
17%     'Physics'  - Returns chromaticity in physics  units (Tune/(dp/p))  {Default}
18%  5. 'Struct'  - Will return a two element dispersion data structure array {Default, unless Mode='Model'}
19%     'Numeric' - Will return vector outputs
20%  6. Optional override of the mode:
21%     'Online'    - Set/Get data online 
22%     'Simulator' - Set/Get data on the simulated accelerator (ie, same commands as 'Online')
23%     'Model'     - Get the model chromaticity directly from the model (uses modelchro, DeltaRF is ignored)
24%     'Manual'    - Set/Get data manually
25%  7. 'Archive'   - Save a chromaticity data structure to \<Directory.ChroData>\Chromaticity\
26%                   with filename <ChroArchiveFile><Date><Time>.mat  {Default, unless Mode='Model'}
27%                   To change the filename, included the filename after the 'Archive', '' to browse
28%     'NoArchive' - No file archive {Default}
29%  8. 'Display'   - Prints status information to the command window {Default, unless Mode='Model'}
30%     'NoDisplay' - Nothing is printed to the command window
31%
32
33%  OUTPUT
34%                  | Horizontal Chromaticity |
35%  ChromHardware = |                         |  [Delta Tune / Delta Frequency]
36%                  | Vertical Chromaticity   |       (Hardware Units)
37%
38
39%                 | Horizontal Chromaticity |
40%  ChromPhysics = |                         |  [Delta Tune / Delta Energy]
41%                 | Vertical Chromaticity   |       (Physics Units)
42%
43%  When computing physics units the momentum compaction factor is required.  The default MCF is
44%  found using getmcf.  To override the default enter the new value after the 'Physics' input.
45%  For example,  ChromPhysics = measchro(DeltaRF, WaitFlag, 'Physics', .0011);
46%
47%  Tune vs RF frequency or momentum are plotted to the screen
48%
49%  Fields for structure outputs:
50%            Data: [2x1] Chromaticity vector
51%      FamilyName: 'Chromaticity'
52%         Monitor: Tune structure
53%        Actuator: RF frequency structure
54%   DeltaActuator: Vector of frequency shifts in Hz
55%       TimeStamp: Timestamp
56%  DataDescriptor: 'Chromacity'
57%       CreatedBy: 'measchro'
58%             MCF: Momentum compaction factor/linear
59%              RF: Vector of frequency settings in Hz
60%               X: Reference orbit
61%               Y: Reference orbit
62%           Tune0: Initial tune
63%            Tune: Tune change with RF frequency, 2 row vectors
64%              dp: Vector of normalized momentum shifts
65%         PolyFit: Polynomial fit of chromaticity in terms of rf shift or momentum
66%
67%  NOTE
68%  1. 'Hardware', 'Physics', 'Eta', 'Archive', 'Numeric', and 'Struct' are not case sensitive
69%  2. 'Zeta' can be used instead of 'Physics'
70%  3.  All inputs are optional
71%  4.  One reason FamilyName is added to the output structure so that getdata can be
72%      used to locate archived dispersion measurements.
73%  5.  Units for DeltaRF depend on the 'Physics' or 'Hardware' flags
74%  6. Beware of what units you are working in.  The default units for chromaticity
75%     are physics units.  This is an exception to the normal middle layer convention.
76%     Hardware units for "chromaticity" is in tune change per change in RF frequency. 
77%     Since this is an unusual unit to work with, the default units for chromaticity
78%     is physics units.  Note that goal chromaticity is also stored in physics units.
79%     plotchro can switch between 'Hardware' and 'Physics' after the measurement is taken.
80%     As an example of the difference between the units, at Spear3 1 unit of chromaticity
81%     in physics units corresponds to roughly -1.8 units in hardware units. 
82%
83%  See also plotchro, measdisp
84%
85%  Written by Greg Portmann and Jeff Corbett
86
87%
88%  Written by Gregory J. Portmann
89%  Modified by Laurent S. Nadolski
90
91NRFSteps = 1;
92WaitFlag = 8;
93MCF = [];
94StructOutputFlag = 0;
95FileName = -1;
96ArchiveFlag = 0;
97DisplayFlag = -1;
98ModeFlag  = '';         % model, online, manual, or '' for default mode
99UnitsFlag = 'Physics';  % hardware, physics, or '' for default units
100
101
102% Look if 'struct' or 'numeric' in on the input line
103for i = length(varargin):-1:1
104    if strcmpi(varargin{i},'Struct')
105        StructOutputFlag = 1;
106        varargin(i) = [];
107    elseif iscell(varargin{i})
108        % Ignor cells
109    elseif strcmpi(varargin{i},'Numeric')
110        StructOutputFlag = 0;
111        varargin(i) = [];
112    elseif strcmpi(varargin{i},'Archive')
113        ArchiveFlag = 1;
114        if length(varargin) > i
115            % Look for a filename as the next input
116            if ischar(varargin{i+1})
117                FileName = varargin{i+1};
118                varargin(i+1) = [];
119            end
120        end
121        varargin(i) = [];
122    elseif strcmpi(varargin{i},'NoArchive')
123        ArchiveFlag = 0;
124        varargin(i) = [];
125    elseif strcmpi(varargin{i},'Zeta') || strcmpi(varargin{i},'Physics')
126        UnitsFlag = 'Physics';
127        varargin(i) = [];
128        if length(varargin) >= i
129            if isnumeric(varargin{i})
130                MCF = varargin{i};
131                varargin(i) = [];
132                if any(size(MCF)>1)
133                    error('Input MCF must be a scalar');
134                end
135            end
136        end
137    elseif strcmpi(varargin{i},'Hardware')
138        UnitsFlag = 'Hardware';
139        varargin(i) = [];
140        if length(varargin) >= i
141            if isnumeric(varargin{i})
142                MCF = varargin{i};
143                varargin(i) = [];
144                if any(size(MCF)>1)
145                    error('Input MCF must be a scalar');
146                end
147            end
148        end
149    elseif strcmpi(varargin{i},'Simulator') || strcmpi(varargin{i},'Model') || strcmpi(varargin{i},'Online') || strcmpi(varargin{i},'Manual')
150        ModeFlag = varargin{i};
151        varargin(i) = [];
152    elseif strcmpi(varargin{i},'NoDisplay')
153        DisplayFlag = 0;
154        varargin(i) = [];
155    elseif strcmpi(varargin{i},'Display')
156        DisplayFlag = 1;
157        varargin(i) = [];
158    end
159end
160
161% Default for Model is no display, no archive
162if DisplayFlag == -1 && strcmpi(ModeFlag,'Model')
163    DisplayFlag = 0;
164end
165if ArchiveFlag == -1 && strcmpi(ModeFlag,'Model')
166    ArchiveFlag = 0;
167end
168
169
170% DeltaRF input
171if length(varargin) >= 1
172    if isnumeric(varargin{1})
173        DeltaRF = varargin{1};
174    else
175        DeltaRF = [];
176    end
177else
178    DeltaRF = [];
179end
180
181% WaitFlag input
182if length(varargin) >= 2
183    WaitFlag = varargin{2};
184end
185if isempty(WaitFlag) || WaitFlag == -3
186    WaitFlag = 2.2 * getfamilydata('TuneDelay');
187end
188if isempty(WaitFlag)
189    WaitFlag = input('   Delay for Tune Measurement (Seconds, Keyboard Pause = -4, or Manual Tune Input = -5) = ');
190end
191
192
193% Archive data structure
194if ArchiveFlag
195    if isempty(FileName)
196        FileName = appendtimestamp(getfamilydata('Default', 'ChroArchiveFile'));
197        DirectoryName = getfamilydata('Directory','ChroData');
198        if isempty(DirectoryName)
199            DirectoryName = [getfamilydata('Directory','DataRoot') 'Chromaticity', filesep];
200        else
201            % Make sure default directory exists
202            DirStart = pwd;
203            [DirectoryName, ErrorFlag] = gotodirectory(DirectoryName);
204            cd(DirStart);
205        end
206        [FileName, DirectoryName] = uiputfile('*.mat', 'Select Chromaticity File', [DirectoryName FileName]);
207        if FileName == 0
208            ArchiveFlag = 0;
209            disp('   Chromaticity measurement canceled.');
210            Chromaticity=[]; FileName='';
211            return
212        end
213        FileName = [DirectoryName, FileName];
214    elseif FileName == -1
215        FileName = appendtimestamp(getfamilydata('Default', 'ChroArchiveFile'));
216        DirectoryName = getfamilydata('Directory','ChroData');
217        if isempty(DirectoryName)
218            DirectoryName = [getfamilydata('Directory','DataRoot') 'Chromaticity', filesep];
219        end
220        FileName = [DirectoryName, FileName];
221    end
222end
223
224
225% Get units from the RF frequency
226if isempty(UnitsFlag)
227    UnitsFlag = getfamilydata('RF','Setpoint','Units');
228end
229
230
231if strcmpi(UnitsFlag,'Hardware')
232    RFUnitsString = getfamilydata('RF','Setpoint','HWUnits');
233elseif strcmpi(UnitsFlag,'Physics')
234    RFUnitsString = getfamilydata('RF','Setpoint','PhysicsUnits');
235else
236    error('RF units unknown.  Inputs DeltaRF directly.');
237end
238
239% DeltaRF default
240if isempty(DeltaRF)
241    % Get the default from the AD is in Hardware units
242    DeltaRF = getfamilydata('DeltaRFChro');
243   
244    % If the default is not in the AD
245    if isempty(DeltaRF)
246        DeltaRF = getrf('Hardware') * getmcf * [-.004 -.002 0 .002 .004] ;  % .2% energy change per step
247    else
248        if strcmpi(UnitsFlag,'Physics')
249            % Since the default from the AO must be in hardware units, change to physics units
250            DeltaRF = hw2physics('RF', 'Setpoint', DeltaRF, [1 1], ModeFlag);
251        end
252    end   
253end
254
255
256% Check DeltaRF for reasonable values
257if strcmpi(RFUnitsString, 'MHz')
258    if abs(max(DeltaRF)-min(DeltaRF)) > .0001;  % .001 MHz
259        tmp = questdlg(sprintf('%f MHz is a large RF change.  Do you want to continue?', abs(max(DeltaRF)-min(DeltaRF))),'Dispersion Measurement','YES','NO','YES');
260        if strcmp(tmp,'NO')
261            Chromaticity=[];
262            return
263        end
264    end
265elseif strcmpi(RFUnitsString, 'kHz')
266    if abs(max(DeltaRF)-min(DeltaRF)) > 1;  % kHz
267        tmp = questdlg(sprintf('%f kHz is a large RF change.  Do you want to continue?', abs(max(DeltaRF)-min(DeltaRF))),'Dispersion Measurement','YES','NO','YES');
268        if strcmp(tmp,'NO')
269            Chromaticity=[];
270            return
271        end
272    end
273elseif strcmpi(RFUnitsString, 'Hz')
274    if abs(max(DeltaRF)-min(DeltaRF)) > 1000;  % Hz
275        tmp = questdlg(sprintf('%f Hz is a large RF change.  Do you want to continue?', abs(max(DeltaRF)-min(DeltaRF))),'Dispersion Measurement','YES','NO','YES');
276        if strcmp(tmp,'NO')
277            Chromaticity=[];
278            return
279        end
280    end
281else
282    % Don't who how to check, hence no check made
283end
284
285% DeltaRF must be in "RFUnitsString" units at this point
286
287
288RFsp = getrf('Struct', UnitsFlag, ModeFlag);
289
290if isempty(MCF)
291    MCF = getmcf(ModeFlag);
292end
293
294
295% Fill the chromaticity structure (response matrix structure + some fields)
296c.Data = [];
297c.FamilyName = 'Chromaticity';
298if isfamily('TUNEFBT')
299    c.Monitor = family2datastruct('TUNEFBT','Monitor',[1 1;1 2]);
300else
301    c.Monitor = gettuneFBT('Struct', 'Model');  % Just to fill the structure
302    c.Monitor.Data = NaN * c.Monitor.Data;
303end
304c.Monitor = gettuneFBT('Struct', ModeFlag);     % Should WaitFlag before to be sure to get a good measurement ?????
305c.Actuator = RFsp;
306c.ActuatorDelta = DeltaRF;
307c.GeV = getenergy(ModeFlag);
308c.DCCT = getam('DCCT', ModeFlag);
309c.ModulationMethod = 'Unipolar';
310c.WaitFlag = WaitFlag;
311c.TimeStamp = clock;
312c.Mode = ModeFlag;
313c.Units = UnitsFlag;
314c.UnitsString = [];
315c.DataDescriptor = 'Chromaticity';
316c.CreatedBy = 'measchro';
317c.OperationalMode = getfamilydata('OperationalMode');
318
319% Nonstandard response matrix fields
320if strcmpi(ModeFlag,'Manual')
321    c.X = NaN;
322    c.Y = NaN;
323else
324    c.X = getx('Struct', UnitsFlag, ModeFlag);
325    c.Y = gety('Struct', UnitsFlag, ModeFlag);
326end
327c.MCF = MCF;
328RF0 = RFsp.Data(1);
329c.dp = -DeltaRF / (RF0*MCF);
330
331
332if strcmpi(ModeFlag,'Model') || strcmpi(ModeFlag,'Simulator')
333    % No need for delays with the model
334    WaitFlag = 0;
335    ExtraDelay = 0;
336end
337
338
339if strcmpi(ModeFlag,'Model')
340    c.Data = modelchro('Physics');
341   
342    if strcmpi(UnitsFlag,'Physics')
343        TuneUnitsString = getfamilydata('TUNEFBT','Monitor','PhysicsUnits');
344        if isempty(TuneUnitsString)
345            TuneUnitsString = 'Fractional Tune';
346        end
347        c.UnitsString = [TuneUnitsString, '/(dp/p)'];
348    else
349        % Tune Shift vs. RF Frequency
350        c.Data(1,1) = c.Data(1,1) / (-RF0 * MCF);
351        c.Data(2,1) = c.Data(2,1) / (-RF0 * MCF);       
352        TuneUnitsString = getfamilydata('TUNEFBT','Monitor','HWUnits');
353        if isempty(TuneUnitsString)
354            TuneUnitsString = 'Fractional Tune';
355        end
356        c.UnitsString = [TuneUnitsString, '/',getfamilydata('RF','Setpoint','HWUnits')];
357    end
358   
359else
360    % Online or Simulator
361    % Start measurement
362    if DisplayFlag
363        fprintf('   Begin chromaticity measurement\n');
364    end   
365    for i = 1:length(DeltaRF)
366        %setrf(RF0 + DeltaRF(i), UnitsFlag, ModeFlag);
367        if (isempty(ModeFlag) && strcmpi(getfamilydata('RF','Setpoint','Mode'),'Manual')) || strcmpi(ModeFlag,'Manual')
368            % One shot setting of RF
369            setrf(RF0 + DeltaRF(i), UnitsFlag, ModeFlag);
370        else
371            % Slow setting of RF
372            rf = getrf(UnitsFlag, ModeFlag);
373            for k = 1:NRFSteps
374                setsp('RF', rf + k/NRFSteps * (RF0+DeltaRF(i)-rf), [], -1, UnitsFlag, ModeFlag);
375                pause(0.1);
376            end
377        end
378       
379        RF(:,i) = getrf(UnitsFlag, ModeFlag);
380        if DisplayFlag
381            fprintf('   %d. RF frequency is %.5f\n', i, RF(:,i));
382        end
383
384        % Wait for tune monitor to have fresh data
385        if WaitFlag >= 0
386            if DisplayFlag && ~strcmpi(ModeFlag,'Manual')
387                fprintf('      Pausing %f seconds for the tune measurement\n', WaitFlag);
388                pause(0);
389            end
390            sleep(WaitFlag);
391            Tune(:,i) = gettuneFBT(ModeFlag);
392        elseif WaitFlag == -4
393            tmp = input('      Hit return when the tune measurement is ready. ');
394            Tune(:,i) = gettuneFBT(ModeFlag);
395        elseif WaitFlag == -5
396            Tune(1,i) = input('      Input the horizontal tune = ');
397            Tune(2,i) = input('      Input the  vertical  tune = ');
398        else
399            error('Tune delay method unknown');
400        end
401       
402        %if any(isnan(Tune))
403        %    fprintf('   Chromaticity measurement failed.  RF frequency reset.\n');
404        %    setrf(RF0, UnitsFlag, ModeFlag);
405        %    Chromaticity = [NaN; NaN];
406        %    return;
407        %end
408    end
409   
410   
411    % Reset RF
412    %setrf(RF0, UnitsFlag, ModeFlag);
413    if isempty(ModeFlag) && strcmpi(getfamilydata('RF','Setpoint','Mode'),'Manual')
414        % One shot setting of RF
415        setrf(RF0, UnitsFlag, ModeFlag);
416    else
417        % Slow setting of RF
418        rf = getrf(UnitsFlag, ModeFlag);
419        for k = 1:NRFSteps
420            setsp('RF', rf + k/NRFSteps * (RF0-rf), [], -1, UnitsFlag, ModeFlag);
421            pause(0.1);
422        end
423    end
424   
425   
426    % Load Tune measurements into the chromaticy structure
427    c.Tune = Tune;
428   
429    if strcmpi(UnitsFlag,'Physics')
430        %%%%%%%%%%%%%%%%%%%%%%%%%%%
431        % Tune Shift vs. Momentum % 
432        %%%%%%%%%%%%%%%%%%%%%%%%%%%
433       
434        % Horizontal tune vs. momentum
435        p = polyfit(c.dp, Tune(1,:), 2);              %2nd order polynomial fit to data   
436        c.PolyFit(1,:) = p;
437        c.Data(1,1) = p(2);
438       
439        % Vertical  tune vs. rf frequency
440        p = polyfit(c.dp, Tune(2,:), 2);
441        c.PolyFit(2,:) = p;
442        c.Data(2,1) = p(2);
443       
444        TuneUnitsString = getfamilydata('TUNEFBT','Monitor','PhysicsUnits');
445        if isempty(TuneUnitsString)
446            c.UnitsString = ['Fractional Tune/(dp/p)'];
447        else
448            c.UnitsString = [TuneUnitsString,'/(dp/p)'];
449        end
450       
451        %fprintf('\n   Horizontal Chromaticity (Un-normalized) = %f \n', c.Data(1));
452        %fprintf('   Vertical   Chromaticity (Un-normalized) = %f \n'  , c.Data(2));
453    else
454        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
455        % Tune Shift vs. RF Frequency % 
456        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457       
458        % Horizontal tune vs. rf frequency
459        p = polyfit(DeltaRF, Tune(1,:), 2);      % 2nd order polynomial fit to data
460        c.PolyFit(1,:) = p;
461        c.Data(1,1) = p(2);
462       
463        % Vertical  tune vs. rf frequency
464        p = polyfit(DeltaRF, Tune(2,:), 2);
465        c.PolyFit(2,:) = p;
466        c.Data(2,1) = p(2);
467       
468        TuneUnitsString = getfamilydata('TUNEFBT','Monitor','HWUnits');
469        if isempty(TuneUnitsString)
470            c.UnitsString = ['Fractional Tune/',getfamilydata('RF','Setpoint','HWUnits')];
471        else
472            c.UnitsString = [TuneUnitsString,'/',getfamilydata('RF','Setpoint','HWUnits')];
473        end
474    end
475end
476
477if DisplayFlag
478    fprintf('   Chromaticity = %f [%s]\n', c.Data(1), c.UnitsString);
479    fprintf('   Chromaticity = %f [%s]\n', c.Data(2), c.UnitsString);
480end
481
482if DisplayFlag && ~strcmpi(ModeFlag,'Model')
483    figure;
484    plotchro(c);
485end
486
487
488% Archive data structure
489if ArchiveFlag
490    % If the filename contains a directory then make sure it exists
491    [DirectoryName, FileName, Ext] = fileparts(FileName);
492    DirStart = pwd;
493    [DirectoryName, ErrorFlag] = gotodirectory(DirectoryName);
494    Chromaticity = c;
495    save(FileName, 'Chromaticity');
496    if DisplayFlag
497        fprintf('   Chromaticity data saved to %s.mat\n', [DirectoryName FileName]);
498        if ErrorFlag
499            fprintf('   Warning: %s was not the desired directory\n', DirectoryName);
500        end
501    end
502    cd(DirStart);
503    FileName = [DirectoryName, FileName, '.mat'];
504end
505if FileName == -1
506    FileName = '';
507end
508
509
510% Load output data
511if StructOutputFlag
512    Chromaticity = c;
513else
514    Chromaticity = c.Data;
515end
516
517
518if DisplayFlag
519    fprintf('   Chromaticity measurement is complete.\n');
520end
521
522
Note: See TracBrowser for help on using the repository browser.