Code covered by the BSD License  

Highlights from
Vector Field TB

from Vector Field TB by Francesco Visentin
A group of class to perform vector field (DPIV) data analysis and visualization

sfield
classdef sfield
    % SFIELD is a class to describe scalar field.
    %   SFIELD is an object that contains information of a scalar field
    %   derived from a vector field (VFIELD) object. The class is part of
    %   the VECTOR FIELD TOOLBOX.
    %
    %   SF_OBJ = SFIELD(VF_OBJ, FIELD_NAME) derive the required FIELD_NAME
    %   scalar field from the vecrtor field (VFIELD). SF_OBJ inherits the
    %   following properties from the VF_OBJ: X, Y, NAMET, NAMEX, NAMEY,
    %   SAMPLING RATE, SIZE, UNITT, UNITX, UNITY and VECTORTYPE.
    %
    %   Available fields are:
    %   'AbsCurl'               : absolute value of the curl field
    %   'Curl'                  : angular velocity of a vector field
    %   'Divergence'            : divergence of a vector field
    %   'Energy'                : kinematic energy of the vector field
    %   'Enstrophy'             : integral of the square of the vorticity
    %   'Q'                     : Q method
    %   'SquaredStrainRate2d'   : the rate of change in strain with respect to time
    %   'VelocityAngleDeg'      : angle (DEG) of each velocity vector
    %   'VelocityAngleRad'      : angle (RAD) of each velocity vector
    %   'VelocityNorm'          : norm of the velocity vector [sqrt(u.^2 + v.^2)]
    %   'VelocityX'             : x-component of the vector field (u)
    %   'VelocityY'             : y-component of the vector field (v)
    %
    %   To derive negative value of the scalar field, just add '-' in front
    %   of the field name (e.g. '-AbsCurl', '-VelocityX').
    %
    %   Other names for the field are available but will be removed in
    %   future version.
    %
    %   See also: dataset, vfield, sensor, sensorarray
    
    properties
        x       = [];   % xTickLabel coming from vField data (Mx1)
        y       = [];   % yTickLabel coming from vField data (Nx1)
        t       = [];   % zTickLabel coming from vFiedl data (Lx1);
        val     = [];   % field value (NxMxT)
        
        mask    = [];   % Mask for velocity field data
        
        fieldInfo = struct(...
            'fieldName', '', ...        % Name of the scalar field
            'fieldLabel', '', ...       % Label for DATASET oject
            'fieldUnit', '', ...        % Unit of measure for the x-component of the velocity field
            'namet', '', ...            % t-axis name
            'namex', '', ...            % x-axis name
            'namey', '', ...            % y-axis name
            'samplingRate', NaN, ...    % Sampling rate
            'size', [], ...             % Field size (ROWS x COLS x TIME)
            'unitt', '', ...            % Time unit of measure.
            'unitx', '', ...            % x-axis unit of measure
            'unity', '', ...            % y-axis unit of measure
            'vectorType', [] ...        % Vector type (0: original | 1: interpolated)
            );
    end
    
    methods
        function sf_obj = sfield(varargin)
            % SF_OBJ = SFIELD(VF_OBJ, FIELD_NAME)
            
            option = sf_obj.sf_parseInput(varargin{:});
            
            if ~isempty(option.vField)
                % A VFIELD is provided
                
                u = option.vField.u;
                v = option.vField.v;
                
                % Convert masked value to NaN
                u(option.vField.mask == 1) = NaN;
                v(option.vField.mask == 1) = NaN;
                
                % Determin unit of measure scale factor
                [scale,sf_unkown] = sf_obj.sf_getScaleFactor(option.vField);
                
                % Determin the time unit
                if sf_unkown
                    time_unit = ['(' option.vField.fieldInfo.unitx '/(' option.vField.fieldInfo.unitu '))'];
                else
                    time_unit = option.vField.fieldInfo.unitt;
                end
                
                switch strtok(lower(option.mode),'+-')
                    case {'velocityx','ux','vx','u'}
                        sf_obj.val = u;
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = option.vField.fieldInfo.nameu;
                        sf_obj.fieldInfo.fieldLabel    = 'VelocityX';
                        sf_obj.fieldInfo.fieldUnit     = option.vField.fieldInfo.unitu;
                    case {'velocityy','uy','vy','v'}
                        sf_obj.val = v;
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = option.vField.fieldInfo.namev;
                        sf_obj.fieldInfo.fieldLabel    = 'VelocityY';
                        sf_obj.fieldInfo.fieldUnit     = option.vField.fieldInfo.unitv;
                    case {'velocitynorm','norm','magnitude'}
                        sf_obj.val = sqrt(u.^2 + v.^2);
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = ['sqrt(' option.vField.fieldInfo.nameu '^2 + ' option.vField.fieldInfo.namev '^2)'];
                        sf_obj.fieldInfo.fieldLabel    = 'VelocityNorm';
                        sf_obj.fieldInfo.fieldUnit     = option.vField.fieldInfo.unitv;
                    case {'energy','ken','en'}
                        sf_obj.val = .5*(u.^2 + v.^2);
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = 'Energy';
                        sf_obj.fieldInfo.fieldLabel    = sf_obj.fieldInfo.fieldName;
                        sf_obj.fieldInfo.fieldUnit     = ['(' option.vField.fieldInfo.nameu ')^2'];
                    case {'velocityanglerad','angle','rad'}
                        sf_obj.val = mod(atan2(v,u),2*pi);
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = 'Velocity angle';
                        sf_obj.fieldInfo.fieldLabel    = 'VelocityAngleRad';
                        sf_obj.fieldInfo.fieldUnit     = 'rad';
                    case {'velocityangledeg','deg'}
                        sf_obj.val = mod(atan2(v,u),2*pi)*180/pi;
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = 'Velocity angle';
                        sf_obj.fieldInfo.fieldLabel    = 'VelocityAngleDef';
                        sf_obj.fieldInfo.fieldUnit     = 'deg';
                    case {'curl','rot','vort'}
                        [mx,my] = meshgrid(option.vField.x,option.vField.y);
                        for k = 1:option.vField.fieldInfo.size(3)
                            sf_obj.val(:,:,k) = 2*curl(mx,my,u(:,:,k),v(:,:,k)).*scale;
                        end
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = 'Curl';
                        sf_obj.fieldInfo.fieldLabel    = sf_obj.fieldInfo.fieldName;
                        sf_obj.fieldInfo.fieldUnit     = [time_unit '^{-1}'];
                    case {'abscurl','absrot','absvort'}
                        tmp = sfield(option.vField,'curl');
                        sf_obj.val = abs(tmp.val);
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = '|Curl|';
                        sf_obj.fieldInfo.fieldLabel    = 'AbsCurl';
                        sf_obj.fieldInfo.fieldUnit     = tmp.fieldInfo.fieldUnit;
                    case {'divergence','div'}
                        [mx,my] = meshgrid(option.vField.x,option.vField.y);
                        for k = 1:option.vField.fieldInfo.size(3)
                            sf_obj.val(:,:,k) = divergence(mx,my,u(:,:,k),v(:,:,k)).*scale;
                        end
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = 'Divergence';
                        sf_obj.fieldInfo.fieldLabel    = sf_obj.fieldInfo.fieldName;
                        sf_obj.fieldInfo.fieldUnit     = [time_unit '^{-1}'];
                    case {'enstrophy','ens'}
                        tmp = sfield(option.vField,'curl');
                        sf_obj.val = tmp.val.^2/2;
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = 'Enstrophy';
                        sf_obj.fieldInfo.fieldLabel    = sf_obj.fieldInfo.fieldName;
                        sf_obj.fieldInfo.fieldUnit     = [time_unit '^{-2}'];
                    case {'squaredstrainrate2d','eps','epsilon'}
                        for k = 1:option.vField.fieldInfo.size(3)
                            [dudx, dudy] = gradient(option.vField.u(:,:,k),...
                                abs(diff(option.vField.x(1:2))),abs(diff(option.vField.y(1:2))));
                            [dvdx, dvdy] = gradient(option.vField.v(:,:,k),...
                                abs(diff(option.vField.x(1:2))),abs(diff(option.vField.y(1:2))));
                            sf_obj.val(:,:,k) = (dudx.*scale).^2 + (dvdy.*scale).^2 + .5*(((dudy + dvdx).*scale).^2);
                        end
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = '2D Squared strain rate';
                        sf_obj.fieldInfo.fieldLabel    = 'SquaredStrainRate2d';
                        sf_obj.fieldInfo.fieldUnit     = [time_unit '^{-2}'];
                    case {'q'}
                        ens_tmp = sfield(option.vField,'ens');
                        eps_tmp = sfield(option.vField,'eps');
                        
                        sf_obj.val = .5*(ens_tmp.val - eps_tmp.val);
                        
                        % Units and names
                        sf_obj.fieldInfo.fieldName     = 'Q';
                        sf_obj.fieldInfo.fieldLabel    = sf_obj.fieldInfo.fieldName;
                        sf_obj.fieldInfo.fieldUnit     = [time_unit '^{-2}'];
                    otherwise
                        error('vectorFieldTB:sfield:sfield:input', ...
                            [ '''' option.mode ''' is not a supported mode parameter.']);
                end
                
                % Set other fields
                sf_obj.x        = option.vField.x;
                sf_obj.y        = option.vField.y;
                sf_obj.t        = option.vField.t;
                sf_obj.mask     = option.vField.mask;
                
                sf_obj.fieldInfo.namex          = option.vField.fieldInfo.namex;
                sf_obj.fieldInfo.namey          = option.vField.fieldInfo.namey;
                sf_obj.fieldInfo.namet          = option.vField.fieldInfo.namet;   
                sf_obj.fieldInfo.samplingRate   = option.vField.fieldInfo.samplingRate;
                sf_obj.fieldInfo.size           = option.vField.fieldInfo.size;
                sf_obj.fieldInfo.unitt          = time_unit;
                sf_obj.fieldInfo.unitx          = option.vField.fieldInfo.unitx;
                sf_obj.fieldInfo.unity          = option.vField.fieldInfo.unity;
                sf_obj.fieldInfo.vectorType     = option.vField.fieldInfo.vectorType;
                
                if strfind(option.mode,'-')
                    sf_obj.val                     = -sf_obj.val;
                    sf_obj.fieldInfo.fieldName     = ['-' sf_obj.fieldInfo.fieldName];
                    sf_obj.fieldInfo.fieldLabel    = ['minus_' sf_obj.fieldInfo.fieldLabel];
                end
            else
                error('vectorFieldTB:sfield:sfield:input', ...
                    'A VFIELD object is required.');
            end
        end
        
        % End
        function sf_index = end(sf_obj,position,~)
            if isempty(sf_obj.val)
                error('vectorFieldTB:sfield:end:noFieldFound',...
                    'The object is empty');
            else
                sf_index = sf_obj.fieldInfo.size(position);
            end
        end
        
        % Struct
        function sf_struct = struct(sf_obj)
            % STRUCT returns the structured version of the SFIELD object
            sf_fieldnames   = fieldnames(sf_obj);
            values          = cell(length(sf_fieldnames), 1);
            
            for k = 1:length(sf_fieldnames)
                [values{k, :}] = sf_obj.(sf_fieldnames{k});
            end
            
            sf_struct = cell2struct(values, sf_fieldnames, 1);
        end
    end
    
end

Contact us