private void Measure() { // allocate space for the results int tracePointsPerStep = (int)(frequencyStep / 100E3); // truncates towards 0 results.numberOfTracePoints = rxFrequencyRamp.Length * tracePointsPerStep + 1; results.noiseFloorTraces = new double[bandwidths.Length][][]; results.maxHoldTraces = new double[bandwidths.Length][]; for (int i = 0; i < bandwidths.Length; i++) { results.noiseFloorTraces[i] = new double[numberOfRuns][]; for (int j = 0; j < numberOfRuns; j++) { results.noiseFloorTraces[i][j] = Enumerable.Repeat(double.NegativeInfinity, results.numberOfTracePoints).ToArray(); } results.maxHoldTraces[i] = Enumerable.Repeat(double.NegativeInfinity, results.numberOfTracePoints).ToArray(); } // process data from producer for (int i = 0; i < numberOfRuns; i++) { for (int j = 0; j < rxFrequencyRamp.Length; j++) { ComplexWaveform <ComplexDouble> iqData; // for compatibility with pre c# 7 code if (queue.TryTake(out iqData, timeout.ToTimeSpan())) { double iqRate = 1 / iqData.PrecisionTiming.SampleInterval.TotalSeconds; /// Call LabVIEW built DLL for filtering the data. /// The VI is set to shared clone re-entrant, therefore we can manage execution thread from C#. Parallel.For(0, bandwidths.Length, bandwidthIndex => { double[] powerTrace = LVFilters.ComplexFilter(iqRate, vbw, 1000, bandwidths[bandwidthIndex], 70, iqData.GetScaledData()); // sort the trace from high to low int[] indexes = Enumerable.Range(0, powerTrace.Length).ToArray(); Array.Sort(powerTrace, indexes, Comparer <double> .Create(new Comparison <double>((i1, i2) => i2.CompareTo(i1)))); // sort decending // take the first (max) values of the sorted power trace and sort again according to index int recordTracePoints = tracePointsPerStep; if (j == rxFrequencyRamp.Length - 1) { recordTracePoints++; } Array.Sort(indexes, powerTrace, 0, recordTracePoints); // sorts just the points we are interested in // evaluate the max hold of the result for (int k = 0; k < recordTracePoints; k++) { int traceIndex = j * tracePointsPerStep + k; results.noiseFloorTraces[bandwidthIndex][i][traceIndex] = powerTrace[k]; results.maxHoldTraces[bandwidthIndex][traceIndex] = Math.Max(results.maxHoldTraces[bandwidthIndex][traceIndex], powerTrace[k]); } }); } } } measurementCompleteEvent.Set(); }
public NoiseFloorTest( Transceiver transceiver, string band, string waveformName, ComplexWaveform <ComplexDouble> waveform, double txStartFrequency = 1920E6, double txStopFrequency = 1980E6, double rxStartFrequency = 2110E6, double rxStopFrequency = 2170E6, double frequencyStep = 1E6, int numberOfRuns = 1, string referenceTriggerLine = "PXI_Trig0", double sgPowerLevel = -10, double saReferenceLevel = 10, double vbw = 10000, bool preSoakSweep = false, double soakFrequency = 1955E6, double soakTime = 0, double dwellTime = 1E-3, double idleTime = 300E-6, double referenceTriggerDelay = 15E-6, double timeout = 10) { this.transceiver = transceiver; this.band = band; this.waveformName = waveformName; this.waveform = waveform; this.txStartFrequency = txStartFrequency; this.txStopFrequency = txStopFrequency; this.rxStartFrequency = rxStartFrequency; this.rxStopFrequency = rxStopFrequency; this.frequencyStep = frequencyStep; this.numberOfRuns = numberOfRuns; this.referenceTriggerLine = referenceTriggerLine; this.sgPowerLevel = sgPowerLevel; this.saReferenceLevel = saReferenceLevel; this.vbw = vbw; this.preSoakSweep = preSoakSweep; this.soakFrequency = soakFrequency; this.soakTime = soakTime; this.dwellTime = dwellTime; this.idleTime = idleTime; this.referenceTriggerDelay = referenceTriggerDelay; this.timeout = new PrecisionTimeSpan(timeout); ThreadPool.QueueUserWorkItem(o => LVFilters.Initialize()); // this is launched asynchronously and will never be waited on transceiver.Initialize(); }