classdef aesaAntenna < handle
    %AesaArray this class represents an AESA Antenna Array.
    %   This class models the performance of an AESA antenna array.
    %
    % 2pi/lambda (radians/m) is a form of "1" for unit conversion!
    properties
        arrayConfig;
        sumAzPattern;
        sumElPattern;
    end
    
    methods
        % class constructor
        function obj = aesaAntenna(configFile)
            %UNTITLED2 Construct an instance of this class
            %   Detailed explanation goes here
            obj.arrayConfig = yaml.loadFile(configFile,"ConvertToArray", true);
            
        end
        
        % create principle plane patterns for system...
        function [azPattern, angles_d] = getAzPattern(obj,freq_hz,az_d,el_d)
            numElem = obj.arrayConfig.numElemAz;
            elemSp_m = obj.arrayConfig.azSpacing_m;
            weights = obj.arrayConfig.AzWeights;
            [azPattern, angles_d] = getPattern(obj,freq_hz,az_d,numElem, elemSp_m , weights);
            obj.sumAzPattern=azPattern;
%             azPattern = azPattern .* azPattern; % model 2 way pattern
            
        end
        function [dAzPattern, angles_d] = getDAzPattern(obj,freq_hz,az_d,el_d)% need to call getAzPattern first to get the tranmit pattern
            numElem = obj.arrayConfig.numElemAz;
            elemSp_m = obj.arrayConfig.azSpacing_m;
            weights = obj.arrayConfig.DeltaAzWeights;
            [dAzPattern, angles_d] = getPattern(obj,freq_hz,az_d,numElem, elemSp_m , weights);
%             dAzPattern = dAzPattern .* obj.sumAzPattern; % model 2 way pattern
        end
        function [ElPattern, angles_d] = getElPattern(obj,freq_hz,az_d,el_d)
            numElem = obj.arrayConfig.numElemEl;
            elemSp_m = obj.arrayConfig.elSpacing_m;
            weights = obj.arrayConfig.ElWeights;
            [ElPattern, angles_d] = getPattern(obj,freq_hz,el_d,numElem, elemSp_m , weights);
            obj.sumElPattern=ElPattern;
%             ElPattern = ElPattern .* ElPattern; % model 2 way pattern
        end
        function [dElPattern, angles_d] = getDElPattern(obj,freq_hz,az_d,el_d) % need to call getElPattern first to get the tranmit pattern
            numElem = obj.arrayConfig.numElemEl;
            elemSp_m = obj.arrayConfig.elSpacing_m;
            weights = obj.arrayConfig.DeltaElWeights;
            [dElPattern, angles_d] = getPattern(obj,freq_hz,el_d,numElem, elemSp_m , weights);
%             dElPattern = dElPattern .* obj.sumElPattern;% model 2 way pattern
        end
        
        function [Pattern, angles_d] = getPattern(obj,freq_hz,angle_d,numElem, elemSp_m, weights)
            %getPattern -- caluclate and return the 2d principle plane pattern
            %   Calculate the principle plane azimuth pattern based on the
            %   weighting, antenna geometry and the frequency.
            numPts = 3600;
            inc = pi/numPts;
            % array of pointing angles to calculate beam pattern on (-90 to
            % 90 degrees)
            theta = -pi/2:inc:pi/2;
            angles_d = theta * 180 / pi;
            lambda_m = radConst.c_mps/(freq_hz);
            nd= ((1:numElem)-median(1:numElem))*2*pi/lambda_m * elemSp_m;
            % calculate the phasing for the array
            wts = weights.* exp(nd*sind(angle_d)*1i);
            % calculate the Azimuth Pattern
            % for each pointing angle...
            Pattern=zeros(size(theta),'like',1i);
            for ii = 1:length(theta)
                % cos(theta(ii) is the element pattern portion
                Pattern(ii) = (cos(theta(ii))^obj.arrayConfig.elemPatternRolloff)...
                    *wts*(exp(nd*sin(theta(ii))*1i))';
            end
            
        end
%%         % create 3D pattern for system
        function [Pattern_dB, angles_d] = get3DPattern(obj,freq_hz,az_d,el_d)
            %get3DPattern -- caluclate and return the azimuth pattern
            %   Calculate the principle plane azimuth pattern based on the
            %   weighting, antenna geometry and the frequency.
            
            %         % create 3D pattern for system
            
            numPts = 180;
            inc = pi/numPts;
            % array of pointing angles to calculate beam pattern on (-90 to
            % 90 degrees)
            theta = -pi/2:inc:pi/2;
            angles_d = theta * 180 / pi;
            lambda_m = radConst.c_mps/(freq_hz);
            
            elemSp_m=obj.arrayConfig.azSpacing_m;
            numElem = obj.arrayConfig.numElemAz;
            nd_horiz= ((1:numElem)-median(1:numElem))*2*pi/lambda_m * elemSp_m;
            elemSp_m=obj.arrayConfig.elSpacing_m;
            numElem = obj.arrayConfig.numElemEl;            
            nd_vert= ((1:numElem)-median(1:numElem))*2*pi/lambda_m * elemSp_m;
%             nd = nd_vert' * nd_horiz;
%            weights = obj.arrayConfig.ElWeights' * obj.arrayConfig.AzWeights;
            % calculate the phasing for the array
            vertWts = obj.arrayConfig.ElWeights .* exp(nd_vert*sin(el_d*pi/180)*1i);
            horizWts = obj.arrayConfig.AzWeights .* exp(nd_horiz*sin(az_d*pi/180)*1i);
            wts = vertWts' * horizWts;
            % calculate the Azimuth Pattern
            % for each pointing angle...
            Pattern=zeros(size(theta),'like',1i);
            for jj = 1:length(theta)
                for ii = 1:length(theta)
                    tempAz = (cos(theta(ii))^obj.arrayConfig.elemPatternRolloff)...
                        *horizWts*(exp(nd_horiz*sin(theta(ii))*1i))';
                    tempEl = (cos(theta(jj))^obj.arrayConfig.elemPatternRolloff)...
                        *vertWts*(exp(nd_vert*sin(theta(jj))*1i))';
                    Pattern(jj,ii)=tempAz*tempEl;
                end
            end
            Pattern_dB = 20 * log10(abs(Pattern));
        end
        

        %% normilize weights commented out for now...
        function normWeights(obj)
%             % normWeights -- normilize weights 
%             obj.arrayConfig.AzWeights =  obj.arrayConfig.AzWeights / ...
%                 ((obj.arrayConfig.AzWeights*obj.arrayConfig.AzWeights')^.5);
%             obj.arrayConfig.DeltaAzWeights =  obj.arrayConfig.DeltaAzWeights / ...
%                 ((obj.arrayConfig.DeltaAzWeights*obj.arrayConfig.DeltaAzWeights')^.5);
%             obj.arrayConfig.ElWeights =  obj.arrayConfig.ElWeights / ...
%                 ((obj.arrayConfig.ElWeights*obj.arrayConfig.ElWeights')^.5);
%             obj.arrayConfig.DeltaElWeights =  obj.arrayConfig.DeltaElWeights / ...
%                 ((obj.arrayConfig.DeltaElWeights*obj.arrayConfig.DeltaElWeights')^.5);
%             yaml.dumpFile('antennaConfig.yaml',obj.arrayConfig,"auto");
        end
    end
end

