/// <summary>Configures common settings for memory polynomial based DPD.</summary> /// <param name="specAn">Specifies the SpecAn signal to configure.</param> /// <param name="mpConfig">Specifies the memory polynomial settings to apply.</param> /// <param name="selectorString">Pass an empty string. The signal name that is passed when creating the signal configuration is used. /// See the RFmx help for more documention of this parameter.</param> public static void ConfigureMemoryPolynomial(RFmxSpecAnMX specAn, MemoryPolynomialConfiguration mpConfig, string selectorString = "") { specAn.Dpd.Configuration.ConfigureDpdModel(selectorString, RFmxSpecAnMXDpdModel.GeneralizedMemoryPolynomial); specAn.Dpd.Configuration.ConfigureMemoryPolynomial(selectorString, mpConfig.Order, mpConfig.Depth); specAn.Dpd.Configuration.ConfigureGeneralizedMemoryPolynomialCrossTerms(selectorString, mpConfig.LeadOrder, mpConfig.LagOrder, mpConfig.LeadMemoryDepth, mpConfig.LagMemoryDepth, mpConfig.MaximumLead, mpConfig.MaximumLag); RFmxSpecAnMXDpdIterativeDpdEnabled iterativeDpdEnabled = mpConfig.NumberOfIterations > 1 ? RFmxSpecAnMXDpdIterativeDpdEnabled.True : RFmxSpecAnMXDpdIterativeDpdEnabled.False; specAn.Dpd.Configuration.ConfigureIterativeDpdEnabled(selectorString, iterativeDpdEnabled); specAn.Dpd.ApplyDpd.ConfigureMemoryModelCorrectionType(selectorString, mpConfig.CorrectionType); }
/// <summary>Acquires the incoming signal, trains the DPD model, applies the memory polynomial to the reference waveform, and downloads the predistorted waveform to the generator. /// If generation is in progress when this function is called, generation will resume with the predistorted waveform.</summary> /// <param name="specAn">Specifies the SpecAn signal to configure.</param> /// <param name="rfsgSession">Specifies the open RFSG session to configure.</param> /// <param name="referenceWaveform">Specifies the <see cref="Waveform"/> whose data defines the complex baseband equivalent of the RF signal applied at the input /// port of the device under test when performing the measurement. See the RFmx help for more documention of this parameter.</param> /// <param name="selectorString">Pass an empty string. The signal name that is passed when creating the signal configuration is used. /// See the RFmx help for more documention of this parameter.</param> /// <returns>Common results after the application of memory polynomial based DPD.</returns> public static MemoryPolynomialResults PerformMemoryPolynomial(RFmxSpecAnMX specAn, NIRfsg rfsgSession, MemoryPolynomialConfiguration mpConfig, Waveform referenceWaveform, string selectorString = "") { //Instantiate new waveform with reference waveform properties MemoryPolynomialResults mpResults = new MemoryPolynomialResults() { PredistortedWaveform = referenceWaveform }; mpResults.PredistortedWaveform.Data = referenceWaveform.Data.Clone(); // clone waveform so RFmx can't act on reference waveform mpResults.PredistortedWaveform.UpdateNameAndScript(referenceWaveform.Name + "postMpDpd"); RFmxSpecAnMXDpdApplyDpdIdleDurationPresent idlePresent = referenceWaveform.IdleDurationPresent ? RFmxSpecAnMXDpdApplyDpdIdleDurationPresent.True : RFmxSpecAnMXDpdApplyDpdIdleDurationPresent.False; RfsgGenerationStatus preDpdGenerationStatus = rfsgSession.CheckGenerationStatus(); rfsgSession.Abort(); // abort so we don't mess with the loop logic for (int i = 0; i < mpConfig.NumberOfIterations; i++) { specAn.Dpd.Configuration.ConfigurePreviousDpdPolynomial(selectorString, mpResults.Polynomial); rfsgSession.Initiate(); specAn.Initiate(selectorString, ""); specAn.WaitForMeasurementComplete(selectorString, 10.0); // wait for polynomial coefficients to be calculated //waveform data and PAPR are overwritten in post DPD waveform specAn.Dpd.ApplyDpd.ApplyDigitalPredistortion(selectorString, referenceWaveform.Data, idlePresent, 10.0, ref mpResults.PredistortedWaveform.Data, out mpResults.PowerResults.WaveformTruePapr_dB, out mpResults.PowerResults.WaveformPowerOffset_dB); //Waveform's PAPR is modified to adjust the output power of the waveform on a per waveform basis rather than changing the //user's configured output power on the instrument mpResults.PredistortedWaveform.PAPR_dB = mpResults.PowerResults.WaveformPowerOffset_dB + mpResults.PowerResults.WaveformTruePapr_dB; DownloadWaveform(rfsgSession, mpResults.PredistortedWaveform); // implicit abort ApplyWaveformAttributes(rfsgSession, mpResults.PredistortedWaveform); specAn.Dpd.Results.FetchDpdPolynomial(selectorString, 10.0, ref mpResults.Polynomial); } mpResults.PowerResults.TrainingPower_dBm = rfsgSession.RF.PowerLevel; if (preDpdGenerationStatus == RfsgGenerationStatus.InProgress) { rfsgSession.Initiate(); // restart generation if it was running on function call } return(mpResults); }