private double ComputePositionWeight(double solutionUncertaintyArcSec, SingleMultiFrameMeasurement measurement, double minUncertainty, WeightingMode mode) { return(FlyByMotionFitter.ComputeWeight(mode, solutionUncertaintyArcSec, measurement.FWHMArcSec, measurement.SNR, measurement.Detection, minUncertainty)); }
public void RunEmbeddedTestCases(int testCaseId) { var data = LoadTestCaseData(testCaseId); var fitter = new FlyByMotionFitter(); double motionRate; if (data.TestConfig.Motion == MovementExpectation.SlowFlyby) { var raFit = fitter.FitAndPlotSlowFlyby( data.Measurements.ToDictionary(x => x.FrameNo, y => y), data.MeasurementContext, data.FittingContext, FittingValue.RA, null, null, null, 0, 0, 0, 0, out motionRate); Assert.AreEqual(data.TestConfig.RA * 15.0 * 3600, raFit.FittedValue * 3600, 0.1); Assert.AreEqual(data.TestConfig.Rate, motionRate, 0.01); TimeSpan timeDiff = data.TestConfig.Time - raFit.FittedValueTime; Assert.AreEqual(0, timeDiff.TotalMilliseconds, 0.5, string.Format("Normal Time Difference. Expected: {0:0.0000000}, Actual: {1:0.0000000}", GetFractionalDays(data.TestConfig.Time), GetFractionalDays(raFit.FittedValueTime))); var deFit = fitter.FitAndPlotSlowFlyby( data.Measurements.ToDictionary(x => x.FrameNo, y => y), data.MeasurementContext, data.FittingContext, FittingValue.DEC, null, null, null, 0, 0, 0, 0, out motionRate); Assert.AreEqual(data.TestConfig.DE * 3600, deFit.FittedValue * 3600, 0.1); #region Derive motion rate, coordinates on the first frame and compute expected position at returned normal time double ra0 = 0; double de0 = 0; int count = 0; int frameIdFromIntPeriodOfMinFrame = (data.MeasurementContext.MinFrameNo - data.FittingContext.FirstFrameIdInIntegrationPeroid) % data.FittingContext.IntegratedFramesCount; int lastFrameIdFromFirstIntPeriod = data.MeasurementContext.MinFrameNo - frameIdFromIntPeriodOfMinFrame + data.FittingContext.IntegratedFramesCount; for (int i = 0; i < data.FittingContext.IntegratedFramesCount - frameIdFromIntPeriodOfMinFrame; i++) { if (data.Measurements[i].FrameNo <= lastFrameIdFromFirstIntPeriod) { ra0 += data.Measurements[i].RADeg; de0 += data.Measurements[i].DEDeg; count++; } } // Use Mean rather than Median ra0 /= count; de0 /= count; double ra1 = 0; double de1 = 0; int count1 = 0; double ra2 = 0; double de2 = 0; int count2 = 0; int? lastIntervalId = null; int? secondLastIntervalId = null; for (int i = data.Measurements.Count - 1; i >= 0; i--) { int interval = (data.Measurements[i].FrameNo - data.FittingContext.FirstFrameIdInIntegrationPeroid) / data.FittingContext.IntegratedFramesCount; if (lastIntervalId == null || lastIntervalId.Value == interval) { ra1 += data.Measurements[i].RADeg; de1 += data.Measurements[i].DEDeg; lastIntervalId = interval; count1++; } else if (secondLastIntervalId == null || secondLastIntervalId.Value == interval) { ra2 += data.Measurements[i].RADeg; de2 += data.Measurements[i].DEDeg; secondLastIntervalId = interval; count2++; } else break; } if (lastIntervalId != null && secondLastIntervalId != null) { ra1 /= count1; de1 /= count1; ra2 /= count2; de2 /= count2; int numIntervals = lastIntervalId.Value - (data.MeasurementContext.MinFrameNo - data.FittingContext.FirstFrameIdInIntegrationPeroid) / data.FittingContext.IntegratedFramesCount; if (count2 > count1) { ra1 = ra2; de1 = de2; numIntervals = secondLastIntervalId.Value - (data.MeasurementContext.MinFrameNo - data.FittingContext.FirstFrameIdInIntegrationPeroid) / data.FittingContext.IntegratedFramesCount; } double secondsDiff = numIntervals * data.FittingContext.IntegratedFramesCount * (1.0 / data.FittingContext.FrameRate); double raRateArcSecPerSec = (ra1 - ra0) * 3600 / secondsDiff; double deRateArcSecPerSec = (de1 - de0) * 3600 / secondsDiff; TimeSpan diffNormalMinusStartTime = raFit.FittedValueTime - data.FittingContext.FirstFrameUtcTime.AddSeconds(-1 * data.FittingContext.InstrumentalDelay); double raAtNormalTimeArcSec = ra0 * 3600 + raRateArcSecPerSec * diffNormalMinusStartTime.TotalSeconds; double deAtNormalTimeArcSec = de0 * 3600 + deRateArcSecPerSec * diffNormalMinusStartTime.TotalSeconds; double fittedRaArcSec = raFit.FittedValue * 3600; double fittedDecArcSec = deFit.FittedValue * 3600; Trace.WriteLine(string.Format("RA-Diff={0}\", DEC-Diff-{1}\"", Math.Abs(raAtNormalTimeArcSec - fittedRaArcSec), Math.Abs(deAtNormalTimeArcSec - fittedDecArcSec))); // TODO: Improve this to have more meaningful sigmas for asserting equal results double oneSigmaRA = Math.Sqrt(data.Measurements.Sum(x => x.StdDevRAArcSec * x.StdDevRAArcSec) / data.Measurements.Count); double oneSigmaDE = Math.Sqrt(data.Measurements.Sum(x => x.StdDevDEArcSec * x.StdDevDEArcSec) / data.Measurements.Count); Assert.AreEqual(raAtNormalTimeArcSec, fittedRaArcSec, oneSigmaRA); Assert.AreEqual(deAtNormalTimeArcSec, fittedDecArcSec, oneSigmaDE); } #endregion } }
private double CalulateWeight(MeasurementPositionEntry entry, double solutionUncertaintyArcSec) { return(FlyByMotionFitter.ComputeWeight(m_Weighting, solutionUncertaintyArcSec, entry.FWHMArcSec, entry.SNR, entry.DetectionCertainty, m_MinSinglePositionUncertainty)); }
public void TestInstrumentalDelayInAVI(int integratedFrames, int measureFramesPerInterval, double frameRate, double instrumentalDelaySec, bool missFirstFrame, int? clickedFrameIndex) { // Simulated 10 integrated frames with integration starting at frame 100 // Simulated motion in RA with rate 2.34567s per minute // Simulated motion in DEC with rate 34.5678" per minute double frameDurationSec = 1.0 / frameRate; const double raArcSecRatePerMinute = 2.34567; double raArcSecRatePerIntegrationPeriod = integratedFrames * frameDurationSec * raArcSecRatePerMinute / 60.0; const double startingRaDeg = 123.0; const int firstFrameId = 100; const int numIntegrationIntervalsMeasured = 10; DateTime firstIntegratedFrameRealMidExposureUT = DateTime.ParseExact("2016 09 08 13:45:04.718", "yyyy MM dd HH:mm:ss.fff", CultureInfo.InvariantCulture); const double decArcSecRatePerMinute = 34.5678; double decArcSecRatePerIntegrationPeriod = integratedFrames * frameDurationSec * decArcSecRatePerMinute / 60.0; const double startingDecDeg = 42.0; DateTime midExpWithDelay = firstIntegratedFrameRealMidExposureUT.AddSeconds(instrumentalDelaySec); DateTime endFirstFieldTimeStamp = midExpWithDelay; var measurements = new Dictionary<int, SingleMultiFrameMeasurement>(); var fittingContext = new FittingContext() { AavStackedMode = false, FirstFrameIdInIntegrationPeroid = firstFrameId, FirstFrameUtcTime = endFirstFieldTimeStamp, FrameRate = frameRate, FrameTimeType = FrameTimeType.TimeStampOfFirstIntegratedFrame, InstrumentalDelay = instrumentalDelaySec, InstrumentalDelayUnits = InstrumentalDelayUnits.Seconds, IntegratedFramesCount = integratedFrames, MovementExpectation = MovementExpectation.SlowFlyby, NativeVideoFormat = null, ObjectExposureQuality = ObjectExposureQuality.GoodSignal }; var meaContext = new FlybyMeasurementContext() { FirstVideoFrame = 0, /* First frame is in the whole video file */ MaxStdDev = 0, UserMidValue = 0 /* This is used for plotting only */ }; for (int i = 0; i < numIntegrationIntervalsMeasured; i++) { double de = startingDecDeg + (decArcSecRatePerIntegrationPeriod * i) / 3600; double ra = startingRaDeg + (raArcSecRatePerIntegrationPeriod * i) / 3600; for (int f = 0; f < measureFramesPerInterval; f++) { var mea = new SingleMultiFrameMeasurement() { RADeg = ra, DEDeg = de, FrameNo = firstFrameId + i * integratedFrames + f, Mag = 14 }; measurements.Add(mea.FrameNo, mea); } } if (missFirstFrame) // Simulate a prevoous buggy condition: Missed first frame measurements.Remove(firstFrameId); meaContext.MinFrameNo = measurements.Keys.Min(); meaContext.MaxFrameNo = measurements.Keys.Max(); if (clickedFrameIndex == null) // When not specified explicitely compute a normal position close to the last measured frame meaContext.UserMidFrame = meaContext.MaxFrameNo; else meaContext.UserMidFrame = meaContext.MinFrameNo + clickedFrameIndex.Value; var fitter = new FlyByMotionFitter(); double motionRate; var raFit = fitter.FitAndPlotSlowFlyby( measurements, meaContext, fittingContext, FittingValue.RA, null, null, null, 0, 0, 0, 0, out motionRate); var deFit = fitter.FitAndPlotSlowFlyby( measurements, meaContext, fittingContext, FittingValue.DEC, null, null, null, 0, 0, 0, 0, out motionRate); Assert.IsNotNull(raFit); Assert.IsNotNull(deFit); Assert.IsTrue(raFit.IsVideoNormalPosition); Assert.IsTrue(deFit.IsVideoNormalPosition); #region Compute Expected Normal Position and Time of Normal Position int userFrameIntegrationInterval = (meaContext.UserMidFrame - firstFrameId) / integratedFrames; double userFrameIntegrationIntervalMidFrame = firstFrameId + userFrameIntegrationInterval * integratedFrames + integratedFrames / 2 - (frameDurationSec / 2 /* Correction for finding the middle even frames block */); DateTime userFrameIntegrationIntervalMidExposureRealTimeStamp = firstIntegratedFrameRealMidExposureUT.AddSeconds(userFrameIntegrationInterval * integratedFrames * frameDurationSec); double userFrameOffsetFromMidExposureSec = (meaContext.UserMidFrame - userFrameIntegrationIntervalMidFrame) * frameDurationSec; DateTime userFrameRealProjectedTimeStamp = userFrameIntegrationIntervalMidExposureRealTimeStamp.AddSeconds(userFrameOffsetFromMidExposureSec); double fractionalDaysProjectedTimeStamp = GetFractionalDays(userFrameRealProjectedTimeStamp); double fractionalDaysClosestNormalTimeStamp = Math.Round(fractionalDaysProjectedTimeStamp * 1E6) / 1E6; DateTime closestNormalTimeStamp = new DateTime(userFrameRealProjectedTimeStamp.Year, userFrameRealProjectedTimeStamp.Month, userFrameRealProjectedTimeStamp.Day).AddDays(fractionalDaysClosestNormalTimeStamp); #endregion TimeSpan diffExpectedMinusFitted = closestNormalTimeStamp - raFit.FittedValueTime; if (diffExpectedMinusFitted.TotalMilliseconds > 0.5) { diffExpectedMinusFitted = closestNormalTimeStamp.AddDays(0.000001) - raFit.FittedValueTime; if (diffExpectedMinusFitted.TotalMilliseconds > 0.5) { diffExpectedMinusFitted = closestNormalTimeStamp.AddDays(-0.000001) - raFit.FittedValueTime; if (diffExpectedMinusFitted.TotalMilliseconds > 0.5) { Assert.Fail("Normal Time Difference. Expected: {0:0.0000000}, Actual: {1:0.0000000}", GetFractionalDays(closestNormalTimeStamp), GetFractionalDays(raFit.FittedValueTime)); } } } // Make sure we calculate the position for the selected normal frame by the fitter, which may be 1 microday away from ours closestNormalTimeStamp = raFit.FittedValueTime; TimeSpan diffNormalMinusStartTime = closestNormalTimeStamp - firstIntegratedFrameRealMidExposureUT; double raAtNormalTimeArcSec = startingRaDeg * 3600 + raArcSecRatePerMinute * diffNormalMinusStartTime.TotalMinutes; double deAtNormalTimeArcSec = startingDecDeg * 3600 + decArcSecRatePerMinute * diffNormalMinusStartTime.TotalMinutes; double fittedRaArcSec = raFit.FittedValue * 3600; double fittedDecArcSec = deFit.FittedValue * 3600; Trace.WriteLine(string.Format("RA-Diff={0}\", DEC-Diff-{1}\"", Math.Abs(raAtNormalTimeArcSec - fittedRaArcSec), Math.Abs(deAtNormalTimeArcSec - fittedDecArcSec))); Assert.AreEqual(raAtNormalTimeArcSec, fittedRaArcSec, 0.1 /* 0.1 arcsec */); Assert.AreEqual(deAtNormalTimeArcSec, fittedDecArcSec, 0.1 /* 0.1 arcsec */); }