diff m-toolbox/classes/@ao/fromWaveform.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m-toolbox/classes/@ao/fromWaveform.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,267 @@
+% FROMWAVEFORM Construct an ao from a waveform
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FUNCTION:    fromWaveform
+%
+% DESCRIPTION: Construct an ao from a waveform
+%
+% CALL:        a = fromWaveform(pl)
+%
+% PARAMETER:   pl: Parameter list object
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function a = fromWaveform(a, pli, callerIsMethod)
+  
+  VERSION = '$Id: fromWaveform.m,v 1.44 2011/08/15 10:42:38 hewitson Exp $';
+  
+  if callerIsMethod
+    % do nothing
+  else
+    % get AO info
+    ii = ao.getInfo('ao', 'From Waveform');
+    
+    % Set the method version string in the minfo object
+    ii.setMversion([VERSION '-->' ii.mversion]);
+  end
+  
+  if callerIsMethod
+    pl        = pli;
+  else
+    % Combine input plist with default values
+    pl = applyDefaults(ii.plists, pli);
+  end
+  
+  nsecs   = find(pl, 'nsecs');
+  fs      = find(pl, 'fs');
+  t0      = find(pl, 't0');
+  
+  waveform = find(pl, 'waveform');
+  if numel(nsecs) == 1
+    if isempty(nsecs) || nsecs == 0
+      error('### Please provide ''Nsecs'' for waveform constructor.');
+    end
+  end
+  if  isempty(fs) || fs == 0
+    error('### Please provide ''fs'' for waveform constructor.');
+  end
+  
+  % Override defaults
+  if isempty(t0)
+    t0 = time(0);
+  elseif ischar(t0) || isnumeric(t0)
+    t0 = time(t0);
+  end
+  if isempty(find(pl, 'name'))
+    pl.pset('Name', waveform);
+  end
+  
+  
+  switch lower(waveform)
+    %------------ Sine Wave
+    case {'sine wave', 'sinewave', 'sine-wave', 'sine'}
+      ampl = find(pl, 'A');
+      freq = find(pl, 'f');
+      phi  = find(pl, 'phi');
+      Toff = find(pl, 'Toff');
+      gaps = find(pl, 'gaps');
+      
+      % If Toff is a time-string or a time object then convert this time
+      % into a number of seconds depending to T0
+      if ischar(Toff) || iscell(Toff) || isa(Toff, 'plist')
+        
+        % If the t0 is the default value then set it to the first value of Toff
+        if strcmpi(find(pl, 't0'), '1970-01-01 00:00:00.000')
+          t0 = time(Toff(1));
+        end
+        
+        newToff = [];
+        if ischar(Toff)
+          newToff = (time(Toff).utc_epoch_milli - t0.utc_epoch_milli) /1e3;
+        else
+          Toff = time(Toff);
+          for zz = 1:numel(Toff)
+            newToff = [newToff (Toff(zz).utc_epoch_milli - t0.utc_epoch_milli)/1e3];
+          end
+        end
+        
+        Toff = newToff;
+      end
+      
+      % The user specified gaps instead of offsets.
+      % (The gap is before the signal starts)
+      if isempty(pli.find('Toff')) && ~isempty(gaps)
+        Toff(1) = gaps(1);
+        for ww = 2:numel(nsecs)
+          Toff(ww) = sum(gaps(1:ww)) + sum(nsecs(1:ww-1));
+        end
+      end
+      
+      % If the number of  Amplitude, frequency and phase are not the same
+      % then duplicate the last specified value.
+      max_waves = max([numel(ampl), numel(freq), numel(phi), numel(nsecs), numel(Toff)]);
+      
+      ampl  = [ampl, repmat(ampl(end),   1, max_waves - numel(ampl))];
+      freq  = [freq, repmat(freq(end),   1, max_waves - numel(freq))];
+      phi   = [phi,  repmat(phi(end),    1, max_waves - numel(phi))];
+      nsecs = [nsecs, repmat(nsecs(end), 1, max_waves - numel(nsecs))];
+      Toff  = [Toff, repmat(Toff(end),   1, max_waves - numel(Toff))];
+      
+      %%%%%%%%%%%%%%%%%%%%   add different sine waves with time offset  %%%%%%%%%%%%%%%%%%%%
+      
+      maxValues = 0;
+      % Predefine the total result with zeros
+      for kk = 1:numel(Toff)
+        values = (Toff(kk) + nsecs(kk)) * fs;
+        if maxValues < values
+          maxValues = values;
+        end
+      end
+      total = zeros(maxValues, 1);
+      
+      % Over all sine waves
+      for kk = 1:numel(Toff)
+        
+        % Compute the y-values of each sine wave
+        t = 0 : 1/fs : nsecs(kk)-1/fs;
+        y = ampl(kk) * sin(2*pi*freq(kk)*t + phi(kk));
+        
+        % Add the computed values to the total result
+        begT = floor(Toff(kk)*fs);
+        endT = begT + nsecs(kk)*fs;
+        idx  = begT+1:endT;
+        
+        total(idx) = total(idx) + y.';
+        
+      end
+      
+      if isempty(total)
+        error('### You have defined a sine-wave with the length zero.');
+      end
+      
+      ts = tsdata(total, fs);
+      ts.setXunits(find(pl, 'xunits'));
+      ts.setYunits(find(pl, 'yunits'));
+      ts.setT0(t0);
+      
+      % Make an analysis object
+      a.data = ts;
+      if callerIsMethod
+        % do nothing
+        % At the moment, we keep adding the history.
+        % There might be something we need for rebuilding, like RAND_STREAM
+        a.addHistory(ii, pl, [], []);
+      else
+        % Add history
+        a.addHistory(ii, pl, [], []);
+      end
+      
+      % Set some procedure information
+      a.procinfo = plist('start times', time(t0.utc_epoch_milli/1e3 + Toff));
+      
+      % Set the object properties from the plist
+      a.setObjectProperties(pl);
+      
+      % This is a special case where we don't evaluate a string function
+      % but build the values according to the recipe. As such we have
+      % already handled the setting of properties and history and we can
+      % return here.
+      return
+      
+    case 'noise'
+      ntype = find(pl, 'type');
+      pl.getSetRandState();
+      
+      if isempty(ntype)
+        ntype = 'Normal';
+      end
+      sigma = find(pl, 'sigma');
+      if isempty(sigma)
+        sigma = 1;
+      end
+      
+      switch lower(ntype)
+        case 'normal'
+          tsfcn = sprintf('%g.*randn(size(t))', sigma);
+          
+        case 'uniform'
+          tsfcn = sprintf('%g.*rand(size(t))', sigma);
+          
+      end
+      %------------ Chirp
+    case 'chirp'
+      f0  = find(pl, 'f0');
+      fe  = find(pl, 'f1');
+      te  = find(pl, 't1');
+      if isempty(f0)
+        f0 = 0;
+      end
+      if isempty(fe)
+        fe = fs/2;
+      end
+      if isempty(te)
+        te = nsecs;
+      end
+      tsfcn = sprintf('chirp(t,%g,%g,%g)', f0, fe, te);
+      %------------ Gaussian pulse
+    case {'gaussian pulse', 'gaussian-pulse'}
+      fc  = find(pl, 'f0');
+      bw  = find(pl, 'bw');
+      if isempty(fc)
+        fc = 1;
+      end
+      if isempty(bw)
+        bw = fs/2;
+      end
+      tsfcn = sprintf('gauspuls(t,%g,%g)', fc, bw);
+    case {'square wave', 'squarewave', 'square-wave', 'square'}
+      freq = find(pl, 'f');
+      duty = find(pl, 'duty');
+      if isempty(freq)
+        freq = 1;
+      end
+      if isempty(duty)
+        duty = 50;
+      end
+      tsfcn = sprintf('square(2*pi*%g*t,%g)', freq, duty);
+    case {'saw tooth', 'sawtooth', 'saw-tooth', 'saw'}
+      freq  = find(pl, 'f');
+      width = find(pl, 'width');
+      if isempty(freq)
+        freq = 1;
+      end
+      if isempty(width)
+        width = 0.5;
+      end
+      tsfcn = sprintf('sawtooth(2*pi*%g*t,%g)', freq, width);
+    otherwise
+        error('### Unknown waveform type [%s]', waveform);
+  end
+  
+  % construct tsdata
+  t = 0 : 1/fs : nsecs-1/fs; % t = linspace(0, nsecs(kk)-1/fs, nsecs(kk)*fs);
+  % make y data
+  y = eval([tsfcn ';']);
+  
+  ts = tsdata(t, y');
+  ts.setT0(t0);
+  ts.setXunits(find(pl, 'xunits'));
+  ts.setYunits(find(pl, 'yunits'));
+  
+  % Make an analysis object
+  a.data = ts;
+  
+  if callerIsMethod
+    % do nothing
+    % At the moment, we keep adding the history.
+    % There might be something we need for rebuilding, like RAND_STREAM
+    a.addHistory(ii, pl, [], []);
+  else
+    % Add history
+    a.addHistory(ii, pl, [], []);
+  end
+    
+  % Set the object properties from the plist
+  a.setObjectProperties(pl);
+  
+end
+