function [SssResult, SssCorr] = SssSearch(TimeDataIn,PssResult,ConfigPara,DebugPara)
%**********************************************************************
% 函数名称:SssSearch
% 功能描述: SSS 相关搜索 接收天线数可配置
% 输入参数:
% TimeDataIn: 时域采样信号 默认为1.92MSas/s
% 输出参数:
% SssResult : SSS搜索结果
% 修改日期 版本号 修改人 修改内容
%-----------------------------------------------
% 2018/10/23 V1.0 liangyao 创建
%**********************************************************************
SssThr = ConfigPara.SssThr;
FixTOCompEn = ConfigPara.FixTOCompEn;%固定补偿FFT定时提前FftDelay引起的相位差
DownSampleRate = ConfigPara.DownSampleRate;
FftDelay = ConfigPara.FftDelay/DownSampleRate;
CompPhasor = exp(1j*2*pi*FftDelay/128*[0:127]);
frameType = ConfigPara.frameType;
rxAntNum = size(TimeDataIn,1);
fftNum = 128;
PssLoc = PssResult.PeakPos;
PssPower = PssResult.PeakPower;
% PssCE = PssResult.PssCE;
nID2Success = PssResult.nID2Success;
% PssNi = PssResult.PssNi;
% FftDelay = ConfigPara.FftDelay/ConfigPara.DownSampleRate;
%提取SSS的频域数据
if isequal(frameType,'TDD')
SssDist(1) = round((2048*3 + 144*2 + 160)/16); %TDD normal CP
% SssDist(2) = round((2048*3 + 512*3)/16); %TDD Extended CP
else
SssDist(1) = round((2048 + 144)/16); %FDD normal CP
% SssDist(4) = round((2048 + 512)/16);%FDD Extended CP
end
CellValidNum = 0;
for cellIdx=1:length(nID2Success)
if nID2Success(cellIdx)
SssLoc = PssLoc{cellIdx} - SssDist - FftDelay;%
SssCorr = [];
for candIdx=1:length(SssLoc)
if SssLoc(candIdx)>0
%提取频域数据
SssTimeData = TimeDataIn(:,SssLoc(candIdx):SssLoc(candIdx)+fftNum-1);
FreqData = zeros(rxAntNum,fftNum);
SssFreqData = zeros(rxAntNum,72-10);
for rxAntIdx=1:rxAntNum
freqDataTemp = fft(SssTimeData(rxAntIdx,:));
if FixTOCompEn
freqDataTemp = freqDataTemp .* CompPhasor;
end
FreqData(rxAntIdx,:) = fftshift(freqDataTemp);
SssFreqData(rxAntIdx,:) = FreqData(rxAntIdx,[ 34:64 66:96]);
end
if isfield(DebugPara,'SssEqEn') && DebugPara.SssEqEn
%利用PSS信道估计信息对SSS进行均衡
H = permute(PssResult.PssCE(cellIdx,:,:),[3,2,1]);
sigma2 = PssResult.PssNi(cellIdx);
for rxAntIdx=1:rxAntNum
HAnt = H(rxAntIdx,:);
HConj = conj(HAnt);
Yh(rxAntIdx,:) = SssFreqData(rxAntIdx,:) .* HConj;
HHconj(rxAntIdx,:) = HAnt.*HConj;
end
SssFreqData = sum(Yh,1)./(sum(HHconj,1) + sigma2);
else
SssFreqData = SssFreqData;
end
%168种小区组号以及两种半帧号进行盲搜索
SssCorrTemp = SssCorrCal(SssFreqData,cellIdx);
SssCorr(candIdx,:,:,:) = SssCorrTemp;
end
end
%SSS搜索结果整理
TimeLoc = PssLoc{cellIdx};
PssPowerSave = PssPower{cellIdx};
SssResultTemp = SssSearchPeak(SssCorr,SssThr,cellIdx,TimeLoc,PssPowerSave,ConfigPara,DebugPara);
if ~isempty(SssResultTemp)
Len = length(SssResultTemp);
SssResult(CellValidNum+1:CellValidNum+Len) = SssResultTemp;
CellValidNum = CellValidNum + Len;
end
end
end
if CellValidNum==0
SssResult = [];
SssCorr = [];
end
end
function [SssCorr] = SssCorrCal(SssFreqData,SectorId)
CellGroupNum = 168;
RxAntNum = size(SssFreqData,1);
SssCorr = zeros(2,CellGroupNum,RxAntNum);
for GroupIdx=1:CellGroupNum
for AntIdx=1:RxAntNum
%产生本地SSS序列
[~, sss_sf0, sss_sf5] = SyncSymbGen(GroupIdx-1, SectorId-1);
%correlation between local sequence and recieval sequence
pwrIn = mean(abs(SssFreqData(AntIdx,:)).^2);
SssCorr(1,GroupIdx,AntIdx) = mean(bsxfun(@times,SssFreqData(AntIdx,:)/sqrt(pwrIn), sss_sf0));
SssCorr(2,GroupIdx,AntIdx) = mean(bsxfun(@times,SssFreqData(AntIdx,:)/sqrt(pwrIn), sss_sf5));
end
end
end
function [SssSeq] = LocalSss(SectorId)
CellGroupNum = 168;
SssSeq = zeros(CellGroupNum,2,62);
for GroupIdx=1:CellGroupNum
%产生本地SSS序列
[~, sss_sf0, sss_sf5] = SyncSymbGen(GroupIdx-1, SectorId-1);
SssSeq(GroupIdx,1,:) = sss_sf0;
SssSeq(GroupIdx,2,:) = sss_sf5;
end
end
function Exp = SaveSssFreqData(FreqDataIn,AntNum)
[mantissa, Exp] = Float2Fixed(FreqDataIn,15,2);
fid = fopen('../SaveFile/matlab/FreqDataIn.txt','w');
FreqDataFixed = mantissa;
if AntNum == 2
for Idx=1:size(FreqDataFixed,2)
fprintf( fid,'%d %d %d %d\n',real(FreqDataFixed(1,Idx)),imag(FreqDataFixed(1,Idx)),real(FreqDataFixed(2,Idx)),imag(FreqDataFixed(2,Idx)));
end
else
for Idx=1:size(FreqDataFixed,2)
fprintf( fid,'%d %d\n',real(FreqDataFixed(1,Idx)),imag(FreqDataFixed(1,Idx)));
end
end
fclose(fid);
fid = fopen('../SaveFile/matlab/FreqDataScaleIn.txt','w');
for antIdx = 1:length(Exp)
fprintf(fid,'%d ',Exp(antIdx));
end
fclose(fid);
end
function [SssResult] = SssSearchPeak(SssCorr,SssThr,cellIdx,TimeLoc,PssPower,ConfigPara,DebugPara)
SssResult = [];
cellValid = 1;
for candIdx=1:size(SssCorr,1)
PssTimeLoc = TimeLoc(candIdx);
PssPowerTemp = PssPower(candIdx);
candiMetric0 = sqrt(squeeze(mean(abs(SssCorr(candIdx,1,:,:)).^2,4)));
candiMetric1 = sqrt(squeeze(mean(abs(SssCorr(candIdx,2,:,:)).^2,4)));
if max(candiMetric0)>max(candiMetric1)
halfFrame = 1;
candiMetric = candiMetric0;
else
halfFrame = 2;
candiMetric = candiMetric1;
end
Idx = find(candiMetric>=SssThr);
if ~isempty(Idx)
for cIdx=1:length(Idx)
GroupId = Idx(cIdx)-1;
SssResult(cellValid).sssCorr = candiMetric(Idx(cIdx));
SssResult(cellValid).GroupId = GroupId;
SssResult(cellValid).CellId = GroupId*3+(cellIdx-1);
SssResult(cellValid).NsubFrame = (halfFrame-1)*5;
SssResult(cellValid).PssTimeLoc = PssTimeLoc;
SssResult(cellValid).PssPower = PssPowerTemp;
SssResult(cellValid).FrameStartPos = PssTimeLoc - (ConfigPara.PssTimeLoc(halfFrame) + 10);% 10 is the length of CP 9 + 1
cellValid = cellValid + 1;
end
end
end
% for debug
if ~isempty(DebugPara) && DebugPara.SssCorPlotEn ==1
for candIdx=1:size(SssCorr,1)
figure;
subplot(2,1,1);
candiMetric = sqrt(mean(abs(SssCorr(candIdx,1,:,:)).^2,4));
plot(reshape(candiMetric,1,[]));
title('The amplitude of SSS correlation for Sf=0');
subplot(2,1,2);
candiMetric = sqrt(mean(abs(SssCorr(candIdx,2,:,:)).^2,4));
plot(reshape(candiMetric,1,[]));
title('The amplitude of SSS correlation for Sf=5');
end
end
end