function expOut = channelEstReference(...
    numOFDMSymToBeAvg,interpFac,numActSCs,numSymbols,...
    dataIn,validIn,...
    refData,refValid,numactscs)
% getting the mask parameter values

timeAvgCheckBox = get_param('genhdlOFDMChannelEstimatorModel/HDL Algorithm/OFDM Channel Estimator','timeAvgCheckBox');
enableInterpCheckBox = get_param('genhdlOFDMChannelEstimatorModel/HDL Algorithm/OFDM Channel Estimator','enableInterpCheckBox');

% baseline, Non-Std
% Estimation
lsOut = zeros(size(dataIn));
lsVldOut = refValid.*validIn;
lsOut(lsVldOut==1) = dataIn(lsVldOut==1)./refData(lsVldOut==1);
% Averaging
if strcmp(timeAvgCheckBox,'on')
    % expected average output for each numSymAvg
    numIter = floor(numSymbols*numel(numActSCs)/numOFDMSymToBeAvg); avgOut = struct();
    idx = 1;
    numactscs = sum(reshape(numactscs,numOFDMSymToBeAvg,numel(numactscs)/numOFDMSymToBeAvg),1);
    for ii = 1:numIter
        % taking respective indices for numSymAvg
        temp = idx:(idx+numactscs(ii)-1);
        
        lsOutii = lsOut(temp);
        lsVldOutii = lsVldOut(temp);
        % reshaping so as to do "averaging"
        avgInp = reshape(lsOutii,numactscs(ii)/numOFDMSymToBeAvg,numOFDMSymToBeAvg);
        avgInpVld = reshape(lsVldOutii,numactscs(ii)/numOFDMSymToBeAvg,numOFDMSymToBeAvg);
        % averaging
        avgDataOut = sum(avgInp.*avgInpVld,2)./sum(avgInpVld,2); % 1 - each column is added, 2 - each row  is added
        avgDataOut(isnan(avgDataOut)) = 0;
        avgVldOut = sum(avgInpVld,2) >0;
        % creating the boundaries for numSymAvg
        idxVldOut = find(avgVldOut);
        startAvgOut = false*(avgVldOut); startAvgOut(idxVldOut(1)) = true;
        endAvgOut = false*(avgVldOut); endAvgOut(idxVldOut(end)) = true;
        % storing the values
        avgOut(ii).dataOut = avgDataOut;
        avgOut(ii).validOut = avgVldOut;
        avgOut(ii).startOut = startAvgOut;
        avgOut(ii).endOut = endAvgOut;
        
        idx = idx + numactscs(ii);
    end
else
    % expected output without averaging
    numIter = numSymbols*numel(numActSCs); avgOut = struct();
    idx = 1;
    for ii = 1:numIter
        temp = idx:(idx+numactscs(ii)-1);
        % taking the estimated output
        lsDataOutii = lsOut(temp);
        lsVldOutii = lsVldOut(temp);
        % creating the boundaries
        idxVldOut = find(lsVldOutii);
        lsStartOut = false*(lsVldOutii); lsStartOut(idxVldOut(1)) = true;
        lsEndOut = false*(lsVldOutii); lsEndOut(idxVldOut(end)) = true;
        % storing the values
        avgOut(ii).dataOut = lsDataOutii;
        avgOut(ii).validOut = lsVldOutii;
        avgOut(ii).startOut = lsStartOut;
        avgOut(ii).endOut = lsEndOut;
        
        idx = idx + numactscs(ii);
    end
end

% Interpolation
interPolOut = struct();
for ii = 1:numel(avgOut)
    if strcmp(enableInterpCheckBox,'on')
        % expected interpolation output for each symbol
        
        % taking values for each symbol
        intInp = avgOut(ii).dataOut;
        intVldInp = avgOut(ii).validOut;
        
        % calculating the interpolated values
        ls = intInp(intVldInp==1); % only at valid values
        y=[];
        for elem = 1:numel(ls)-1
            x = ls(elem:elem+1);
            for i = 0:1:interpFac
                y(i+1,elem) = (((interpFac-i)/interpFac)*(x(1)))+((i/interpFac)*(x(2)));%#ok
            end
            if ~isequal(elem,numel(ls)-1)
                y(end,elem) = NaN;%#ok
            end
        end
        outputIF = y(:);
        outputIF(isnan(outputIF))=[];
        
        % checking for any extrapolation values and
        % calculating the extrapolation values
        validIdx = find(intVldInp);
        if (validIdx(1)-1)>0
            outputEF = [ls(1)*ones((validIdx(1)-1),1); outputIF];
        else
            outputEF = outputIF;
        end
        % calculating the extrapolation values
        if (validIdx(end)-numel(intVldInp)) < 0
            outputEF = [outputEF; ls(end)*ones(abs((validIdx(end)-numel(intVldInp))),1)]; %#ok
        else
            outputEF = outputEF;%#ok
        end
        % storing the expected output for each symbol
        interPolOut(ii).dataOut = outputEF;
        interPolOut(ii).validOut = true(size(outputEF));
        
    else
        % expected test output for each symbol
        interPolOut(ii).dataOut = avgOut(ii).dataOut;
        interPolOut(ii).validOut = avgOut(ii).validOut;
    end
end
expOut = interPolOut;
end
