private bool CheckTriangleWithRatios(IStarMap starMap, CheckTriangleWithRatiosCallback callback, int i, int j, int k, double toleranceInArcSec) { m_Feature_i = starMap.Features[i - 1]; m_Feature_j = starMap.Features[j - 1]; m_Feature_k = starMap.Features[k - 1]; m_FeatureId_i = m_Feature_i.FeatureId; m_FeatureId_j = m_Feature_j.FeatureId; m_FeatureId_k = m_Feature_k.FeatureId; long idx_ij = (m_FeatureId_i << 32) + m_FeatureId_j; long idx_ik = (m_FeatureId_i << 32) + m_FeatureId_k; long idx_jk = (m_FeatureId_j << 32) + m_FeatureId_k; ImagePixel feature_i_Center = null; ImagePixel feature_j_Center = null; ImagePixel feature_k_Center = null; double dist_ij; if (!m_FeaturesDistanceCache.TryGetValue(idx_ij, out dist_ij)) { if (feature_i_Center == null) feature_i_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_i), starMap); if (feature_j_Center == null) feature_j_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_j), starMap); } double dist_ik; if (!m_FeaturesDistanceCache.TryGetValue(idx_ik, out dist_ik)) { if (feature_i_Center == null) feature_i_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_i), starMap); if (feature_k_Center == null) feature_k_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_k), starMap); } double dist_jk; if (!m_FeaturesDistanceCache.TryGetValue(idx_jk, out dist_jk)) { if (feature_j_Center == null) feature_j_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_j), starMap); if (feature_k_Center == null) feature_k_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_k), starMap); } if (callback(i, j, k, feature_i_Center, feature_j_Center, feature_k_Center, toleranceInArcSec)) // solution found return true; return false; }
private bool LoopThroghFeatureTriangles( IStarMap starMap, double toleranceInArcSec, CheckTriangleCallback callback, CheckTriangleWithRatiosCallback callbackWithRatios) { if (m_PreviousFit != null) { if (TryMatchingPairsFromPreviousFit(starMap)) { // Successfull fit from star to feature matching inferred from the previous fit was successfull if (ImproveAndRetestSolution(0, 0, 0, true)) return true; else { Trace.WriteLine("Could improve solution from previous fit"); } } else { Trace.WriteLine("Could not match stars from previous fit"); } } if (m_ManualPairs != null && TryMatchingPairsFromManualPairs(starMap)) { // Successfull fit from star to feature matching inferred from the previous fit was successfull if (ImproveAndRetestSolution(0, 0, 0)) return true; } int n = starMap.FeaturesCount; if (m_Settings.PyramidOptimumStarsToMatch < n) { // TODO: Need to extract only the largest m_Settings.PyramidOptimumStarsToMatch features. } int total = n * (n - 1) * (n - 2) / 6; int counter = 0; int maxCombinationsBeforeFail = CorePyramidConfig.Default.MaxNumberOfCombinations; Stopwatch timeTaken = new Stopwatch(); timeTaken.Start(); bool delayWarningSent = false; // if (DebugResolvedStars != null) // { // int numInmagRegion, numPyramidStars; // GetNumStarsInRegionAndPyramidSet( // m_PyramidMinMag, m_PyramidMaxMag, // out numInmagRegion, out numPyramidStars); //#if ASTROMETRY_DEBUG // Trace.Assert(numInmagRegion > 3); // Trace.Assert(numPyramidStars > 3); //#endif // } if (m_ManualPairs != null && m_ManualPairs.Count <= 3) { if (m_ManualPairs.Count == 1) { int fixedFeatureIndex = m_ManualPairs.Keys.ToList()[0].FeatureId + 1; for (int k = 2; k <= n; k++) { for (int j = 1; j < k; j++) { var rv = CheckCombination(fixedFeatureIndex, j, k, starMap, toleranceInArcSec, callback, callbackWithRatios, timeTaken, ref counter, ref delayWarningSent, maxCombinationsBeforeFail, total, n); if (rv != null) return rv.Value; } } } else if (m_ManualPairs.Count == 2) { int fixedFeatureIndex1 = m_ManualPairs.Keys.ToList()[0].FeatureId + 1; int fixedFeatureIndex2 = m_ManualPairs.Keys.ToList()[1].FeatureId + 1; for (int k = 1; k <= n; k++) { var rv = CheckCombination(fixedFeatureIndex1, fixedFeatureIndex2, k, starMap, toleranceInArcSec, callback, callbackWithRatios, timeTaken, ref counter, ref delayWarningSent, maxCombinationsBeforeFail, total, n); if (rv != null) return rv.Value; } } else if (m_ManualPairs.Count == 3) { var m_FeatureId_i = m_ManualPairs.Keys.ToList()[0].FeatureId; var m_FeatureId_j = m_ManualPairs.Keys.ToList()[1].FeatureId; var m_FeatureId_k = m_ManualPairs.Keys.ToList()[2].FeatureId; ulong starNo1 = m_ManualPairs.Values.ToList()[0].StarNo; ulong starNo2 = m_ManualPairs.Values.ToList()[1].StarNo; ulong starNo3 = m_ManualPairs.Values.ToList()[2].StarNo; int fixedFeatureIndex1 = m_FeatureId_i + 1; int fixedFeatureIndex2 = m_FeatureId_j + 1; int fixedFeatureIndex3 = m_FeatureId_k + 1; var ijEntry = m_DistancesByMagnitude.FirstOrDefault(x => (x.Star1.StarNo == starNo1 && x.Star2.StarNo == starNo2) || (x.Star1.StarNo == starNo2 && x.Star2.StarNo == starNo1)); var ikEntry = m_DistancesByMagnitude.FirstOrDefault(x => (x.Star1.StarNo == starNo1 && x.Star2.StarNo == starNo3) || (x.Star1.StarNo == starNo3 && x.Star2.StarNo == starNo1)); var jkEntry = m_DistancesByMagnitude.FirstOrDefault(x => (x.Star1.StarNo == starNo3 && x.Star2.StarNo == starNo2) || (x.Star1.StarNo == starNo2 && x.Star2.StarNo == starNo3)); m_Solution = IsSuccessfulMatch(m_StarMap, fixedFeatureIndex1, fixedFeatureIndex2, fixedFeatureIndex3, ijEntry, ikEntry, jkEntry, starNo1, starNo2, starNo3, toleranceInArcSec); if (m_Solution != null) { if (ImproveAndRetestSolution(fixedFeatureIndex1, fixedFeatureIndex2, fixedFeatureIndex3)) { m_MatchedTriangle = string.Format("{0}-{1}-{2}:{5}:[{3}/{4}]", fixedFeatureIndex1, fixedFeatureIndex2, fixedFeatureIndex3, counter, total, n); return true; } } } } for (int k = 3; k <= n; k++) { for (int j = 2; j < k; j++) { for (int i = 1; i < j; i++) { var rv = CheckCombination(i, j, k, starMap, toleranceInArcSec, callback, callbackWithRatios, timeTaken, ref counter, ref delayWarningSent, maxCombinationsBeforeFail, total, n); if (rv != null) return rv.Value; } } } return false; }
private bool? CheckCombination(int i, int j, int k, IStarMap starMap, double toleranceInArcSec, CheckTriangleCallback callback, CheckTriangleWithRatiosCallback callbackWithRatios, Stopwatch timeTaken, ref int counter, ref bool delayWarningSent, int maxCombinationsBeforeFail, int total, int n) { if (i == j || i == k || j == k) return null; counter++; if (DebugResolvedStars != null) { if (!DebugResolvedStars.ContainsKey(i)) return null; if (!DebugResolvedStars.ContainsKey(j)) return null; if (!DebugResolvedStars.ContainsKey(k)) return null; if (DebugExcludeStars != null) { if (DebugExcludeStars.ContainsKey(i)) return null; if (DebugExcludeStars.ContainsKey(j)) return null; if (DebugExcludeStars.ContainsKey(k)) return null; } } #if PYRAMID_DEBUG Trace.WriteLine(string.Format("Trying triangle {0}-{1}-{2}", i, j, k)); #endif if (counter >= maxCombinationsBeforeFail) return false; if (m_AbortSearch) return false; if (counter % 5000 == 0) m_OperationNotifier.SendNotification(new OperationNotifications(NotificationType.SearchProgressed, null)); if (!delayWarningSent && timeTaken.ElapsedMilliseconds > m_Settings.PyramidTimeoutInSeconds * 100 && timeTaken.ElapsedMilliseconds > 5000) { m_OperationNotifier.SendNotification(new OperationNotifications(NotificationType.SearchTakingLonger, timeTaken.ElapsedMilliseconds)); delayWarningSent = true; } if (timeTaken.ElapsedMilliseconds > m_Settings.PyramidTimeoutInSeconds * 1000) { if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceError()) Trace.WriteLine(string.Format("Timeout of {0}sec reached at {1}-{2}-{3}", m_Settings.PyramidTimeoutInSeconds, i, j, k)); return false; } if (callbackWithRatios != null) { if (CheckTriangleWithRatios(starMap, callbackWithRatios, i, j, k, toleranceInArcSec)) { if (ImproveAndRetestSolution(i, j, k)) { m_MatchedTriangle = string.Format("{0}-{1}-{2}:{5}:[{3}/{4}]", i, j, k, counter, total, n); return true; } } } else { if (CheckTriangle(starMap, callback, i, j, k, toleranceInArcSec)) { if (ImproveAndRetestSolution(i, j, k)) { m_MatchedTriangle = string.Format("{0}-{1}-{2}:{5}:[{3}/{4}]", i, j, k, counter, total, n); return true; } } } return null; }
internal bool LoopThroghFeatureTriangles(IStarMap starMap, double toleranceInArcSec, CheckTriangleWithRatiosCallback callback) { return LoopThroghFeatureTriangles(starMap, toleranceInArcSec, null, callback); }