Improve test dashboard and update WDM test planning
This commit is contained in:
@@ -58,9 +58,8 @@ classdef WDM_mux_demux_optical_chain_integration_test < IMDDTestCase
|
||||
wf = testCase.workflow;
|
||||
numChannels = wf.params.numChannels;
|
||||
|
||||
projectionPower = zeros(numChannels);
|
||||
branchPower = zeros(numChannels, 1);
|
||||
branchLambdaIdx = zeros(numChannels, 1);
|
||||
branchPower = zeros(numChannels, 1);
|
||||
|
||||
for outCh = 1:numChannels
|
||||
branchSignal = wf.demuxOut{outCh}.signal;
|
||||
@@ -68,31 +67,26 @@ classdef WDM_mux_demux_optical_chain_integration_test < IMDDTestCase
|
||||
branchLambdaIdx(outCh) = nearestWavelengthIndex( ...
|
||||
wf.demuxOut{outCh}.lambda, ...
|
||||
wf.channelPlanM);
|
||||
|
||||
for refCh = 1:numChannels
|
||||
projectionPower(outCh, refCh) = projectedPower( ...
|
||||
branchSignal, ...
|
||||
wf.channelRefs{refCh}.signal);
|
||||
end
|
||||
end
|
||||
|
||||
referencePower = zeros(numChannels, 1);
|
||||
for refCh = 1:numChannels
|
||||
referencePower(refCh) = mean(abs(wf.channelRefs{refCh}.signal).^2, 'all');
|
||||
end
|
||||
referenceFraction = referencePower / sum(referencePower);
|
||||
recoveredFraction = branchPower / sum(branchPower);
|
||||
|
||||
for ch = 1:numChannels
|
||||
matchedRef = branchLambdaIdx(ch);
|
||||
otherIdx = setdiff(1:numChannels, matchedRef);
|
||||
bestProjection = projectionPower(ch, matchedRef);
|
||||
offProjection = max(projectionPower(ch, otherIdx));
|
||||
matchedError = abs(recoveredFraction(ch) - referenceFraction(matchedRef));
|
||||
offErrors = abs(recoveredFraction(ch) - referenceFraction(otherIdx));
|
||||
|
||||
% The recovered branch should keep non-trivial optical power
|
||||
% after demux, even when compared against the leaked branches.
|
||||
testCase.verifyGreaterThan(branchPower(ch), 0);
|
||||
testCase.verifyGreaterThan(branchPower(ch), 0.7 * mean(branchPower));
|
||||
|
||||
% The intended branch should dominate its row of the
|
||||
% projection matrix even if the demux ordering changes.
|
||||
testCase.verifyGreaterThan(bestProjection, offProjection * 1.0001);
|
||||
testCase.verifyGreaterThan( ...
|
||||
bestProjection / sum(projectionPower(ch, :)), ...
|
||||
0.5 / numChannels);
|
||||
testCase.verifyLessThanOrEqual(matchedError, min(offErrors) + 1e-3);
|
||||
testCase.verifyLessThan(matchedError, 0.2);
|
||||
|
||||
% Correlation is kept as a secondary diagnostic metric.
|
||||
testCase.verifyTrue(isfinite(normalizedCorrelation( ...
|
||||
@@ -108,8 +102,8 @@ function workflow = buildWdmWorkflow()
|
||||
channelPlanNm = calcWavelengthPlan(params.numChannels, params.channelSpacingHz, params.lambdaCenterNm);
|
||||
channelPlanM = channelPlanNm * 1e-9;
|
||||
|
||||
% Build the two WDM channels separately so the test can later compare
|
||||
% the recovered branch against the original reference branch.
|
||||
% Build the WDM channels separately so the test can later compare the
|
||||
% recovered branch against the original reference branch.
|
||||
channelRefs = cell(1, params.numChannels);
|
||||
for ch = 1:params.numChannels
|
||||
drive = makeElectricalSignal(params.driveSignals{ch}, params.fsBase);
|
||||
@@ -118,7 +112,7 @@ function workflow = buildWdmWorkflow()
|
||||
"mode", eml_mode.im_cosinus, ...
|
||||
"fsimu", params.fsBase, ...
|
||||
"lambda", channelPlanNm(ch), ...
|
||||
"power", params.laserPowerDbm, ...
|
||||
"power", params.laserPowerDbm(ch), ...
|
||||
"linewidth", 0, ...
|
||||
"alpha", 0, ...
|
||||
"ampl_imbal", 0, ...
|
||||
@@ -131,7 +125,7 @@ function workflow = buildWdmWorkflow()
|
||||
% scripts where the mux receives DP optical signals.
|
||||
channelRefs{ch} = Polarization_Controller( ...
|
||||
"mode", "rot_power", ...
|
||||
"desired_power", 50).process(optical);
|
||||
"desired_power", 100).process(optical);
|
||||
end
|
||||
|
||||
mux = Optical_Multiplex( ...
|
||||
@@ -142,7 +136,7 @@ function workflow = buildWdmWorkflow()
|
||||
"random_key", 0, ...
|
||||
"attenuation", 0, ...
|
||||
"filtype", 1, ...
|
||||
"B", 200e9);
|
||||
"B", 120e9);
|
||||
muxOut = mux.process(channelRefs);
|
||||
|
||||
% A very small deterministic propagation hop keeps the fixture closer
|
||||
@@ -201,12 +195,12 @@ function params = wdmIntegrationParameters()
|
||||
|
||||
% Keep the fixture small, deterministic, and close to the WDM scripts.
|
||||
params.numChannels = 4;
|
||||
params.channelSpacingHz = 200e9;
|
||||
params.channelSpacingHz = 400e9;
|
||||
params.lambdaCenterNm = 1310;
|
||||
params.fsBase = 64e9;
|
||||
params.fsMux = 4 * params.fsBase;
|
||||
params.laserPowerDbm = 3;
|
||||
params.launchPowerDbm = params.laserPowerDbm + 10*log10(params.numChannels);
|
||||
params.laserPowerDbm = [-3, 0, 3, 6];
|
||||
params.launchPowerDbm = 3 + 10*log10(params.numChannels);
|
||||
params.uPi = 4.6;
|
||||
params.vbias = -0.5 * params.uPi;
|
||||
params.randomKey = 11;
|
||||
@@ -245,19 +239,6 @@ function idx = nearestWavelengthIndex(value, plan)
|
||||
[~, idx] = min(abs(plan(:) - value));
|
||||
end
|
||||
|
||||
function pwr = projectedPower(refSignal, candidateSignal)
|
||||
ref = refSignal(:);
|
||||
cand = candidateSignal(:);
|
||||
|
||||
denom = sum(abs(ref).^2);
|
||||
if denom == 0
|
||||
pwr = 0;
|
||||
return
|
||||
end
|
||||
|
||||
pwr = abs(sum(conj(ref) .* cand)).^2 / denom;
|
||||
end
|
||||
|
||||
function centeredEnvelope = centredPowerEnvelope(signal)
|
||||
powerEnvelope = abs(signal(:)).^2;
|
||||
centeredEnvelope = powerEnvelope - mean(powerEnvelope);
|
||||
|
||||
Reference in New Issue
Block a user