/// <summary> /// Perfrom Y-factor calibration /// </summary> /// <param name="calParams"></param> /// <param name="sysMessage"></param> /// <param name="yFactorCal"></param> public void PerformCal(SweepParams calParams, SysMessage sysMessage, out YfactorCal yFactorCal) { List <double> powerListNdOn = new List <double>(); List <double> powerListNdOff = new List <double>(); calParams.MinAtten = calParams.Attenuation; calParams.MaxAtten = calParams.Attenuation; // set filter bool err = SetFilter(calParams.sys2Detect); if (err) { yFactorCal = null; return; } sysMessage.calibration.temp = preselector.GetTemp(); // perfrom cal for number of attenuations // IS THIS necessary??? //int iterations = 1 + // (measParams.MaxAtten - measParams.Attenuation) // / measParams.StepAtten; //for (int i = 0; i < iterations; i++) //{ FFTParams fftParams = new FFTParams(sensorCapabilities, calParams, possibleSampleRates, possibleSpans); if (fftParams.Error) { Utilites.LogMessage("error calculating FFT Params"); yFactorCal = null; return; } // load sysMessage with fftParams and perfrom sweep for cal fftParams.LoadMessage(sysMessage); // Perform sweep with calibrated noise source on preselector.SetNdIn(); preselector.PowerOnNd(); err = DetectSpan(fftParams, calParams, powerListNdOn, null, null); if (err) { yFactorCal = null; return; } // perfrom sweep with calibrated noise source off preselector.PowerOffNd(); err = DetectSpan(fftParams, calParams, powerListNdOff, null, null); if (err) { yFactorCal = null; return; } // Y-Factor Calibration if (powerListNdOff.Count != powerListNdOn.Count) // sanity check { Utilites.LogMessage("Error getting sweep data. " + "Noise diode on and off power list are different sizes"); yFactorCal = null; return; } yFactorCal = new YfactorCal(powerListNdOn, powerListNdOff, (double)sysMessage.calibration.measurementParameters.resolutionBw, (double)sysMessage.calibration.measurementParameters.equivalentNoiseBw, calParams.DwellTime, sysMessage.preselector.excessNoiseRatio, sysMessage.antenna.cableLoss, sysMessage.antenna.gain); sysMessage.calibration.processed = true; sysMessage.gain = yFactorCal.GainDbw; sysMessage.noiseFigure = yFactorCal.NoseFigureDbw; }
//} /// <summary> /// Performs a multi-segment detection with a Keysight N6841A sensor /// and applies variable attenuation when overload occurs. /// </summary> /// <param name="sweepParams"></param> /// <param name="dataMessage"></param> public bool PerformMeasurement(SweepParams sweepParams, DataMessage dataMessage, YfactorCal yFactorCal) { SetFilter(sweepParams.sys2Detect); preselector.SetRfIn(); preselector.PowerOffNd(); FFTParams fftParams = new FFTParams(sensorCapabilities, sweepParams, possibleSampleRates, possibleSpans); if (fftParams.Error) { Utilites.LogMessage("error calculating FFT Params"); return(true); } fftParams.LoadMessage(dataMessage); // set filter bool err = SetFilter(sweepParams.sys2Detect); List <double> powerList = new List <double>(); List <double> frequencyList = new List <double>(); List <int> attenList = Enumerable.Repeat(sweepParams.Attenuation, (int)fftParams.NumSegments).ToList(); // detect over span for (int i = 0; i < fftParams.NumSegments; i++) { double cf = fftParams.CenterFrequencies[i]; uint numFftsToCopy; if (i == fftParams.NumFullSegments) { numFftsToCopy = fftParams.NumBinsLastSegment; } else { numFftsToCopy = fftParams.NumValidFftBins; } sweepParams.Attenuation = 0; // set attenuation back to its initial value. Hardcodded to 0 for testing purpose if (sweepParams.DynamicAttenuation) { bool overload = true; while (overload && attenList[i] <= MAX_ATTEN) { err = DetectSegment(sweepParams, fftParams, powerList, frequencyList, cf, numFftsToCopy, ref overload); if (err) { return(true); } if (overload) { dataMessage.overloadFlag = true; sweepParams.Attenuation += sweepParams.StepAtten; attenList[i] = sweepParams.Attenuation; } // remove previous duplicated segment int indexDuplicate = 0; foreach (double number in frequencyList) { if (number == frequencyList[frequencyList.Count - 1]) { indexDuplicate = frequencyList.IndexOf(number); if (indexDuplicate == frequencyList.Count - 1) { indexDuplicate = 0; } break; } } if (indexDuplicate != 0) { frequencyList.RemoveRange(indexDuplicate - Convert.ToInt32(numFftsToCopy) + 1, Convert.ToInt32(numFftsToCopy)); powerList.RemoveRange(indexDuplicate - Convert.ToInt32(numFftsToCopy) + 1, Convert.ToInt32(numFftsToCopy)); } // end removing } } else { bool overload = false; err = DetectSegment(sweepParams, fftParams, powerList, frequencyList, cf, numFftsToCopy, ref overload); if (err) { return(true); } if (overload) { dataMessage.overloadFlag = true; } } } List <double> measuredPowers = new List <double>(); // Init antenna class to access cable loss and antenna gain string antennaString = File.ReadAllText(Constants.AntennaFile); SysMessage.Antenna antenna = new JavaScriptSerializer().Deserialize <SysMessage.Antenna>( antennaString); // reference power levels to input of isotropic antenna for (int i = 0; i < powerList.Count; i++) { measuredPowers.Add( powerList[i] + antenna.cableLoss - antenna.gain - yFactorCal.GainDbw[i]); } dataMessage.processed = true; dataMessage.measuredPowers = measuredPowers; return(false); }