public void InitNewMatch(IStarMap imageFeatures, PyramidMatchType matchType, Dictionary <PSFFit, IStar> manualStars) { m_StarMap = imageFeatures; if (manualStars != null) { SetManuallyIdentifiedHints(manualStars); } matchType = PyramidMatchType.PlateSolve; m_IsCalibration = matchType == PyramidMatchType.ConfigCalibration; Context.Initialize(m_RA0Deg, m_DE0Deg, m_CelestialStars, m_PyramidMinMag, m_PyramidMaxMag, m_DetermineAutoLimitMagnitude, m_ManualStarMatch); #if ASTROMETRY_DEBUG AstrometricFitDebugger.Init(m_FitSettings, m_PyramidMinMag, m_PyramidMaxMag, m_AstrometryMinMag, m_AstrometryMaxMag); #endif }
public PerformMatchResult PerformMatch( out LeastSquareFittedAstrometry distanceBasedSolution, out LeastSquareFittedAstrometry improvedSolution, out PlateConstantsSolver solver) { DistanceBasedContext.FieldAlignmentResult alignmentResult = null; improvedSolution = null; #if UNIT_TESTS Flags.Reset(); #endif m_PerformanceWatch.Reset(); m_PerformanceWatch.Start(); try { if (m_StarMap.FeaturesCount < TangraConfig.Settings.Astrometry.MinimumNumberOfStars) { distanceBasedSolution = null; solver = null; return(PerformMatchResult.FieldAlignmentFailed); } if (!m_IsCalibration && m_Solution != null) { // Try using the cache from the last time alignmentResult = Context.DoFieldAlignment(m_StarMap, m_Solution.FitInfo, false); m_Solution = GetSolution(alignmentResult); #if UNIT_TESTS Flags.CacheFromLastTimeAttempted = true; Flags.CacheFromLastTimeSuccessful = m_Solution != null; #endif } if (m_Solution == null && !m_IsCalibration && m_ManualStarMatch != null) { // Try using the manual star match alignmentResult = Context.DoFieldAlignment(m_StarMap, m_ManualStarMatch); m_Solution = GetSolution(alignmentResult); #if UNIT_TESTS Flags.ManualMatchAttempted = true; Flags.ManualMatchSuccessful = m_Solution != null; #endif } if (m_Solution == null && !m_RatioBasedFittedFocalLengthIsDerived && !m_FitSettings.PyramidForceFixedFocalLength && !m_IsCalibration) { m_OperationNotifier.NotifyBeginLongOperation("Performing a plate solve ..."); try { // If this is the first fit, then fit a focal length alignmentResult = Context.DoFieldAlignmentFitFocalLength(m_StarMap); m_Solution = GetSolution(alignmentResult); if (m_Solution != null) { m_RatioBasedFittedFocalLengthIsDerived = true; m_RatioBasedFittedFocalLength = m_Solution.FitInfo.FittedFocalLength; } else { if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceInfo()) { Trace.WriteLine(string.Format("No solution after reaching combination {0} with {1} features.", Context.CurrentCombination, m_StarMap.FeaturesCount)); } } } finally { m_OperationNotifier.NotifyEndLongOperation(); } #if UNIT_TESTS Flags.RatioBasedFocalLengthFitAttempted = true; Flags.RatioBasedFocalLengthFitSuccessful = m_RatioBasedFittedFocalLengthIsDerived; #endif } else { if (m_Solution == null) { if (m_RatioBasedFittedFocalLengthIsDerived && !m_IsCalibration) { alignmentResult = Context.DoFieldAlignment(m_StarMap, m_RatioBasedFittedFocalLength); m_Solution = GetSolution(alignmentResult); #if UNIT_TESTS Flags.FitWithPreFittedFocalLengthAttempted = true; Flags.FitWithPreFittedFocalLengthSuccessful = m_Solution != null; #endif } else { alignmentResult = Context.DoFieldAlignment(m_StarMap); m_Solution = GetSolution(alignmentResult); #if UNIT_TESTS Flags.FitWithFixedFocalLengthAttempted = true; Flags.FitWithFixedFocalLengthSuccessful = m_Solution != null; #endif } } } m_SearchAborted = Context.m_AbortSearch; if (alignmentResult != null) { distanceBasedSolution = (LeastSquareFittedAstrometry)alignmentResult.Solution; improvedSolution = (LeastSquareFittedAstrometry)alignmentResult.ImprovedSolution; m_Solution = GetSolution(alignmentResult); solver = alignmentResult.Solver; } else { distanceBasedSolution = m_Solution; solver = null; } if (m_SearchAborted) { return(PerformMatchResult.SearchAborted); } #if ASTROMETRY_DEBUG if (m_Solution != null) { // No need to keep the debug log any longer when the fit is successful AstrometricFitDebugger.Reset(); } #endif if (m_Solution != null) { // Clear manually identified starting position in a case of a successful plate solve m_ManualStarMatch = null; } return(m_Solution != null ? PerformMatchResult.FitSucceessfull : PerformMatchResult.FitImprovementFailed); } finally { // Reset the manually matched stars after every fit attempt m_ManualStarMatch = null; m_PerformanceWatch.Stop(); if (m_Solution != null) { if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceError()) { Trace.WriteLine(string.Format( "Pyramid Match Successful: {0} ms, {1} stars total, aligned on {2} stars, {3} stars matched {4}. Combination: {5}", m_PerformanceWatch.ElapsedMilliseconds, m_CelestialStars.Count, alignmentResult != null ? (alignmentResult.Solution as LeastSquareFittedAstrometry).FitInfo.NumberOfStarsUsedInSolution() : 0, improvedSolution != null ? improvedSolution.FitInfo.NumberOfStarsUsedInSolution().ToString() : "N/A", improvedSolution != null ? string.Format(" ({0}-{1} mag)", Context.ImprovedSolutionIncludedMinMag.ToString("0.00"), Context.ImprovedSolutionIncludedMaxMag.ToString("0.00")) : null, alignmentResult != null ? alignmentResult.MatchedTriangle : null)); } } else { if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceError()) { Trace.WriteLine(string.Format("Pyramid Match Failed: {0} ms, {1} stars total, NO MATCH", m_PerformanceWatch.ElapsedMilliseconds, m_CelestialStars.Count)); } if (Context.DebugResolvedStars != null) { foreach (DistanceBasedContext.DebugTripple tripple in Context.m_DebugTripples) { if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("DEBUG ALIGN: Missed alignment on {0}-{1}-{2}", tripple.Id1, tripple.Id2, tripple.Id3)); } } } } #if ASTROMETRY_DEBUG Trace.Assert(!m_DetermineAutoLimitMagnitude || m_Solution == null || m_Solution.FitInfo.DetectedLimitingMagnitude != 0); #endif } }