%% FUNCIÓN GRÁFICO PSD
%<graficoPSD>

%PARÁMETROS DE RETORNO:
%Ninguno

%PARÁMETROS DE INGRESO:
%parametros: Estructura con parámetros de simulación
%fOndas: Arreglo de strings con referencia de formas de onda requeridas
%pGraf: Estructura con parámetros gráficos

function graficoPSD(parametros,fOndas,pGraf)


for fOnda=fOndas %control de ciclo según las formas de ondas solicitadas en cada gráfico PSD
    
    switch fOnda
        
        case "OFDM"
            disp('Implementación OFDM solicitada')
                        
            %Verifica si ya existe el archivo con la respuesta del vector
            %OFDM a transmitir. Sólo se crea en el primer llamado, y en los
            %demás se espera hacer uso del resultado ya obtenido y grabado
            opc=exist('vTX_OFDM.mat','file');%2(existe), %0(no existe)
            
            switch opc
                
               case 2 %Archivo existente
               disp('Vector ya creado, sólo se cargará resultado')
               load('vTX_OFDM.mat');
 
               case 0 %Se debe generar el archivo de reuso
               disp('Vector en proceso de creación')
               sumPxxOFDM=zeros(2*parametros.tamFFT,1);%vector almacenamiento periodograma OFDM
               
               %Los gráficos a recrear no están hechos a partir de un sólo
               %símbolo a transmitir, sino de un conjunto, cuyo resultado
               %se promedia antes de graficar. Se asumió el valor
               %almacenado en la estructura parametros.numTotSimb
               
               for ind=1:parametros.numTotSimb
                   [vTxOFDM,bGIzq,bGDer]= TX_OFDM(parametros);%Llamado a la función transmisión para OFDM
                   
                   [PxxOFDM,fOFDM]=periodogram(vTxOFDM,[],parametros.tamFFT*2,[],'centered');
                   sumPxxOFDM=sumPxxOFDM+PxxOFDM;
               end
                   sumPxxOFDM=sumPxxOFDM/mean(sumPxxOFDM(1+2*bGIzq:end-2*bGDer));%Valor de la media sólo sobre los valores 
                                                                                 %donde está confinada la señal
                   vOFDM_PSD=sumPxxOFDM; %Vector transmisión OFDM obtenido para PSD
                   
                   %En caso de que el fichero .mat no se genere, o se
                   %genere en otra ruta no accesible, podría habilitarse
                   %las siguients dos líneas:
                   %************************************
%                    assignin('base','vOFDM_PSD',vOFDM_PSD);%Almacenamiento en el Workspace
%                    assignin('base','fOFDM',fOFDM);
                   %************************************
                   save('vTX_OFDM.mat','vOFDM_PSD');%Almacenamiento vector PSD para OFDM
                   save('vTX_OFDM.mat','fOFDM','-append');%Almacenamiento vector frecuencias normalizadas
                otherwise
                    disp('Opción no esperada')
            end
                       
            %Definición de atributos del gráfico
            figure('Name',pGraf.Titulo1,'NumberTitle','off')
            hold on
            plot(fOFDM,10*log10(vOFDM_PSD),'b')
            legend(fOnda,'Location','south')
   
            xlabel('Frecuencia normalizada');
            ylabel('PSD (dBW/Hz)')
            ax=gca;
            ax.GridLineStyle='--';
            grid on
            ylim(pGraf.yLim)
            
        case "FBMC"
            disp('Implementación FBMC solicitada')
            
            %Verifica si ya existe el archivo con la respuesta del vector
            %FBMC a transmitir. Sólo se crea en el primer llamado, y en los
            %demás se espera hacer uso del resultado ya obtenido y grabado
            opc=exist('vTX_FBMC.mat','file');%2(existe), %0(no existe)
            
            switch opc
                
               case 2 %Archivo existente
               disp('Vector ya creado, sólo se cargará resultado')
               load('vTX_FBMC.mat');
 
               case 0 %Se debe generar el archivo de reuso
               disp('Vector en proceso de creación')
               KF=4*parametros.tamFFT; %Equivale a (K*tamaño_FFT) 
               sumPxxFBMC=zeros(KF*2,1);%vector almacenamiento periodograma FBMC.  
               buf_vTxFBMC=complex(zeros(4*parametros.tamFFT,parametros.numTotSimb));%Equivale a zeros(K*FFT,Número_símbolos) 
               bufSim=complex(zeros(2*KF,1));%buffer con valores del símbolo 
               
               %Los gráficos a recrear no están hechos a partir de un sólo
               %símbolo a transmitir, sino de un conjunto, cuyo resultado
               %se promedia antes de graficar. Se asumió el valor
               %almacenado en la estructura parametros.numTotSimb
               
               for ind=1:parametros.numTotSimb
                  
                    [txSimb,bGIzqFBMC,bGDerFBMC, Hk]= TX_FBMC(parametros,ind);%Llamado a la función transmisión para FBMC
                    
                    % Sobrelapamiento y suma
                        %La señal transmitida es la suma retrasada de los símbolos reales e imaginarios. 
                    
                    bufSim=[bufSim((parametros.tamFFT/2)+1:end);complex(zeros(parametros.tamFFT/2,1))];%corrimiento de muestras(tamFFT/2) a la izq
                    bufSim(KF+(1:KF))=bufSim(KF+(1:KF))+txSimb; % %Actualización mitad final del vector con resultado de iteración actual
                    
                    vTxFBMC=complex(bufSim(1:KF)); %Símbolo actual a transmitir FBMC
                                                    
                    buf_vTxFBMC(:,ind)=vTxFBMC;%Almacenamiento de señales transmitidas para todos los símbolos

                    coefPHYDYAS=coefPhydyasPSD(KF);% Generacion de coeficientes filtro PHYDYAS para gráfico PSD
                    
                    [PxxFBMC,fFBMC]=periodogram(vTxFBMC,coefPHYDYAS,KF*2,[]);
                    sumPxxFBMC=sumPxxFBMC+PxxFBMC;
               end
               
                   sumPxxFBMC=sumPxxFBMC/mean(sumPxxFBMC(1+2*bGIzqFBMC:end-2*bGDerFBMC));%Valor de la media sólo sobre los valores
                                                                                 %donde está confinada la señal
                   vFBMC_PSD=sumPxxFBMC; %Vector transmisión FBMC obtenido para PSD
                   
                   %En caso de que el fichero .mat no se genere, o se
                   %genere en otra ruta no accesible, podría habilitarse
                   %las siguients dos líneas:
                   %************************************
%                    assignin('base','vFBMC_PSD',vFBMC_PSD);%Almacenamiento en el Workspace
%                    assignin('base','fFBMC',fFBMC);
                   %************************************
                   save('vTX_FBMC.mat','vFBMC_PSD');%Almacenamiento vector PSD para FBMC
                   save('vTX_FBMC.mat','fFBMC','-append');%Almacenamiento vector frecuencias normalizadas
                           
                otherwise
                   disp('Opción no esperada')
            end

            h=plot(fFBMC-0.5,10*log10(vFBMC_PSD),'-r','DisplayName',fOnda);
            h.Color(4)=0.7;%ajuste de transparencia al 70%

    
        case "UFMC"
            disp('Implementación UFMC requerida')
           
            %Verifica si ya existe el archivo con la respuesta del vector
            %UFMC a transmitir. Sólo se crea en el primer llamado, y en los
            %demás se espera hacer uso del resultado ya obtenido y grabado
            opc=exist('vTX_UFMC.mat','file');%2(existe), %0(no existe)
            
            switch opc
                
               case 2 %Archivo existente
               disp('Vector ya creado, sólo se cargará resultado')
               load('vTX_UFMC.mat');
 
               case 0 %Se debe generar el archivo de reuso
               disp('Vector en proceso de creación')
               
               tamSub = round(parametros.numSub/parametros.numSubBandas);%Tamaño subbanda
               bGIzq= floor((parametros.tamFFT-parametros.numSub)/2);%Banda de guarda izquierda
               
               %Filtro Chebyshev
               filtroCheb=chebwin(parametros.longFiltro,parametros.SLL);%Generación coeficientes filtros en DT
               
               DatIn = zeros(2*tamSub,parametros.numSubBandas);%Datos ingresados
               txSig = complex(zeros(parametros.tamFFT+parametros.longFiltro-1, 1));%Señal a transmitir
               sumPxxUFMCTot=zeros(2*parametros.tamFFT,1);%vector almacenamiento periodograma UFMC total
                 
               %Los gráficos a recrear no están hechos a partir de un sólo
               %símbolo a transmitir, sino de un conjunto, cuyo resultado
               %se promedia antes de graficar. Se asumió el valor
               %almacenado en la estructura parametros.numTotSimb
               
               for i=1:parametros.numTotSimb 
               
                  sumPxxUFMCporSim=zeros(2*parametros.tamFFT,1);%vector almacenamiento periodograma UFMC/simbolo 
                  
                  for bandIdx=1:parametros.numSubBandas
                  
                    [datos,vecConv]= TX_UFMC(parametros,tamSub,bGIzq,bandIdx,filtroCheb);%Llamado a la función transmisión para UFMC
                    
                    DatIn(:,bandIdx)=datos;%registro de bits para comparación en gráficos BER
                    txSig=txSig+vecConv; %Suma de la señal a transmitir
                    
                    [PxxUFMC,fUFMC]=periodogram(vecConv,[],parametros.tamFFT*2,[],'centered');
%                     plot(fUFMC,10*log10(PxxUFMC))%  <------Habilitar esta línea en caso de que se quiera apreciar el banco de filtros
                    
                    sumPxxUFMCporSim=sumPxxUFMCporSim+PxxUFMC;%Suma de las subbandas por cada simbolo
                  end
                  
                    sumPxxUFMCTot=sumPxxUFMCTot+sumPxxUFMCporSim;%Suma de los símbolos totales simulados               
                  
               end
               
                    sumPxxUFMCTot=sumPxxUFMCTot/mean(sumPxxUFMCTot(1+2*bGIzq:end-2*bGIzq));%Valor de la media sólo sobre los valores
                                                                                 %donde está confinada la señal
                    vUFMC_PSD=sumPxxUFMCTot; %Vector transmisión UFMC obtenido para PSD
                    
                    vUFMC_PSDc=corValInf(vUFMC_PSD); %corrección valores infinitos en vector
                   
                   %En caso de que el fichero .mat no se genere, o se
                   %genere en otra ruta no accesible, podría habilitarse
                   %las siguients dos líneas:
                   %************************************
%                    assignin('base','vUFMC_PSD',vUFMC_PSD);%Almacenamiento en el Workspace
%                    assignin('base','fUFMC',fUFMC);
                   %************************************
                   save('vTX_UFMC.mat','vUFMC_PSDc');%Almacenamiento vector PSD para UFMC
                   save('vTX_UFMC.mat','fUFMC','-append');%Almacenamiento vector frecuencias normalizadas
                           
                otherwise
                   disp('Opción no esperada')
            end
           
            h2=plot(fUFMC,10*log10(vUFMC_PSDc),'-g','DisplayName',fOnda);
            h2.Color(4)=0.7;%ajuste de transparencia al 70%
            h2.LineWidth=1.2;
           
          case "GFDM"
            disp('Implementación GFDM requerida')
           
            %Verifica si ya existe el archivo con la respuesta del vector
            %GFDM a transmitir. Sólo se crea en el primer llamado, y en los
            %demás se espera hacer uso del resultado ya obtenido y grabado
            opc=exist('vTX_GFDM.mat','file');%2(existe), %0(no existe)
            
            switch opc
                
               case 2 %Archivo existente
               disp('Vector ya creado, sólo se cargará resultado')
               load('vTX_GFDM.mat');
 
               case 0 %Se debe generar el archivo de reuso
               disp('Vector en proceso de creación')
               
               %Los gráficos a recrear no están hechos a partir de un sólo
               %símbolo a transmitir, sino de un conjunto cuyo resultado
               %se promedia antes de graficar. Se asumió una cantidad de
               %bits equivalentes a 32 bloques
               
                [sumPxxGFDM,fGFDM,bGlat,nBloq]= TX_GFDM(parametros);%Llamado a la función transmisión para GFDM
                
                sumPxxGFDM=sumPxxGFDM/mean(sumPxxGFDM(bGlat*nBloq:end-bGlat*nBloq));
               
                vGFDM_PSD=sumPxxGFDM; %Vector transmisión GFDM obtenido para PSD
               
               %En caso de que el fichero .mat no se genere, o se
               %genere en otra ruta no accesible, podría habilitarse
               %las siguients dos líneas:
               %************************************
%                 assignin('base','vGFDM_PSD',vGFDM_PSD);%Almacenamiento en el Workspace
%                 assignin('base','fGFDM',fGFDM);
               %************************************
               save('vTX_GFDM.mat','vGFDM_PSD');%Almacenamiento vector PSD para GFDM
               save('vTX_GFDM.mat','fGFDM','-append');%Almacenamiento vector frecuencias normalizadas
               otherwise
                    disp('Opción no esperada')
            end
            h3=plot(fGFDM-0.5,10*log10(vGFDM_PSD),'-m','DisplayName',fOnda);
            h3.Color(4)=0.7;%ajuste de transparencia al 70%
            h3.LineWidth=1.2;
 
    end

end
        asVert=(parametros.BW/parametros.fmFFT)*(1/2)*[-1 1];%Asíntotas verticales
        pAsIzq=plot(asVert(1)*[1 1],pGraf.yLim,'--','color',[0.3010 0.7450 0.9330],'DisplayName','-BW/2');%Asíntota izquierda
        pAsDer=plot(asVert(2)*[1 1],pGraf.yLim,'--','color',[0.3010 0.7450 0.9330],'DisplayName','BW/2');%Asíntota derecha
        pAsIzq.LineWidth=1.2;
        pAsDer.LineWidth=1.2;
        hold off
   
end



