Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ✨ support iq calibration #49

Merged
merged 1 commit into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/Qynit.PulseGen.Server/Models/ChannelInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ public sealed record ChannelInfo(
[property: Key(3)] double Delay,
[property: Key(4)] int Length,
[property: Key(5)] int AlignLevel,
[property: Key(6)] IList<BiquadDto> BiquadChain,
[property: Key(7)] IList<double> FirCoefficients);
[property: Key(6)] IqCalibration? IqCalibration,
[property: Key(7)] IList<BiquadDto> BiquadChain,
[property: Key(8)] IList<double> FirCoefficients);
20 changes: 20 additions & 0 deletions src/Qynit.PulseGen.Server/Models/IqCalibration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using MessagePack;

namespace Qynit.PulseGen.Server.Models;

[MessagePackObject]
public sealed class IqCalibration
{
[Key(0)]
public double A { get; init; }
[Key(1)]
public double B { get; init; }
[Key(2)]
public double C { get; init; }
[Key(3)]
public double D { get; init; }
[Key(4)]
public double IOffset { get; init; }
[Key(5)]
public double QOffset { get; init; }
}
10 changes: 9 additions & 1 deletion src/Qynit.PulseGen.Server/ScheduleRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,15 @@ public List<PooledComplexArray<double>> Run()
postProcessTransform.AddEdge(delayId, terminalId);
}
var pulseLists2 = postProcessTransform.Finish();
var result = pulseLists2.Zip(channels).Select(x => WaveformUtils.SampleWaveform<double>(x.First, x.Second.SampleRate, 0, x.Second.Length, x.Second.AlignLevel));
var result = pulseLists2.Zip(channels).Select(x =>
{
var waveform = WaveformUtils.SampleWaveform<double>(x.First, x.Second.SampleRate, 0, x.Second.Length, x.Second.AlignLevel);
if (x.Second.IqCalibration is { A: var a, B: var b, C: var c, D: var d, IOffset: var iOffset, QOffset: var qOffset })
{
WaveformUtils.IqTransform(waveform, a, b, c, d, iOffset, qOffset);
}
return waveform;
});
return result.ToList();
}
}
34 changes: 34 additions & 0 deletions src/Qynit.PulseGen/WaveformUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,40 @@ public static void ConvertDoubleToFloat(ComplexSpan<float> target, ComplexReadOn
}
}

public static void IqTransform<T>(ComplexSpan<T> target, T a, T b, T c, T d, T iOffset, T qOffset) where T : unmanaged, INumber<T>
{
var i = 0;
ref var targetI = ref MemoryMarshal.GetReference(target.DataI);
ref var targetQ = ref MemoryMarshal.GetReference(target.DataQ);
var vSize = Vector<T>.Count;
if (Vector.IsHardwareAccelerated)
{
var vA = new Vector<T>(a);
var vB = new Vector<T>(b);
var vC = new Vector<T>(c);
var vD = new Vector<T>(d);
var vIOffset = new Vector<T>(iOffset);
var vQOffset = new Vector<T>(qOffset);

for (; i < target.Length - vSize + 1; i += vSize)
{
var iVector = Unsafe.As<T, Vector<T>>(ref Unsafe.Add(ref targetI, i));
var qVector = Unsafe.As<T, Vector<T>>(ref Unsafe.Add(ref targetQ, i));
var iResult = vA * iVector + vB * qVector + vIOffset;
var qResult = vC * iVector + vD * qVector + vQOffset;
Unsafe.As<T, Vector<T>>(ref Unsafe.Add(ref targetI, i)) = iResult;
Unsafe.As<T, Vector<T>>(ref Unsafe.Add(ref targetQ, i)) = qResult;
}
}
for (; i < target.Length; i++)
{
var iResult = a * Unsafe.Add(ref targetI, i) + b * Unsafe.Add(ref targetQ, i) + iOffset;
var qResult = c * Unsafe.Add(ref targetI, i) + d * Unsafe.Add(ref targetQ, i) + qOffset;
Unsafe.Add(ref targetI, i) = iResult;
Unsafe.Add(ref targetQ, i) = qResult;
}
}

private static void MixAddEnvelope<T>(ComplexSpan<T> target, EnvelopeSample<T> envelopeSample, IqPair<T> complexAmplitude, IqPair<T> dragAmplitude, T dPhase) where T : unmanaged, IFloatingPointIeee754<T>
{
var currentIndex = 0;
Expand Down