Пример #1
0
        public static PyramidStarsDensityDistributor BuildPyramidMatchingByMagnitude(
            List<IStar> pyramidStars, 
			AstroPlate image, 
			IAstrometrySettings settings,
            Dictionary<int, ulong> debugResolvedStarsWithAppliedExclusions,
            List<ulong> alwaysIncludeStars,
            out List<DistanceEntry> distancesByMagnitude,
            out Dictionary<ulong, Dictionary<ulonglong, DistanceEntry>> starsDistanceCache)
		{
			// 1) This should be the first N brightest (or all stars) 
			// 2) The memory structure should be a dictionary of Pairs with values all other pairs that include one of the pair
			// 3) The dictionary should be sorted by brightness i.e. brightest pairs should be on the top/ NOTE: Exclude the brightest
			//    stars until the mag difference between the next 2 bright stars becomes less than 1 mag
			// 4) Matching should be done by searching the distance match checking the brightest pairs first. 

            distancesByMagnitude = new List<DistanceEntry>();
            starsDistanceCache = new Dictionary<ulong, Dictionary<ulonglong, DistanceEntry>>();

            if (pyramidStars.Count == 0)
				return null;

            PyramidStarsDensityDistributor distributor;

            pyramidStars.Sort((s1, s2) => s1.Mag.CompareTo(s2.Mag));

            int n = pyramidStars.Count;
            double maxFovInDeg = image.GetMaxFOVInArcSec() / 3600.0;

			distributor = new PyramidStarsDensityDistributor(pyramidStars, image, settings);
            distributor.DebugResolvedStarsWithAppliedExclusions = debugResolvedStarsWithAppliedExclusions;
            distributor.Initialize(alwaysIncludeStars);

            distancesByMagnitude.Clear();
            starsDistanceCache.Clear();

            List<ulong> resolvedDebugStarsNos = null;
            if (debugResolvedStarsWithAppliedExclusions != null)
            {

				// This is disabled at the moment
                resolvedDebugStarsNos = debugResolvedStarsWithAppliedExclusions.Values.ToList();
                int pyramidStarsLocated = 0;
                for (int i = resolvedDebugStarsNos.Count - 1; i >= 0 ; i--)
                {
                    ulong starNo = resolvedDebugStarsNos[i];

                    IStar star = pyramidStars.FirstOrDefault(s => s.StarNo == starNo);
                    if (star != null)
                        pyramidStarsLocated++;
                    else
                        resolvedDebugStarsNos.Remove(starNo);
                    Trace.Assert(star != null, string.Format("Debug Star {0} not found in the pyramid stars!", starNo));
                }

                if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose())
                    Trace.WriteLine(
					    string.Format("DEBUG ALIGN: {0} out of {1} Debug Stars found among the pyramid stars ({2})",
					    pyramidStarsLocated, resolvedDebugStarsNos.Count,
					    resolvedDebugStarsNos.Count > 1 
						    ? resolvedDebugStarsNos.Select(s => s.ToString()).Aggregate((a, b) => string.Concat(a, " ", b))
						    : ""));
            }

			// Start building the pairs
			for (int j = 0; j < n; j++)
			{
                IStar jStar = pyramidStars[j];
                if (!distributor.CheckStar(jStar))
                {
                    if (resolvedDebugStarsNos != null)
                    {
                        if (resolvedDebugStarsNos.Contains(jStar.StarNo))
                        {
                            //Trace.Assert(false, "DebugResolved star pair not added to the pyramid areas because the distributor rejected it.");
                        }
                    }
                    continue;
                }

				for (int i = j + 1; i < n; i++)
				{
                    IStar iStar = pyramidStars[i];
						
					double distDeg = AngleUtility.Elongation(iStar.RADeg, iStar.DEDeg, jStar.RADeg, jStar.DEDeg);

					if (distDeg > maxFovInDeg)
					{
                        if (resolvedDebugStarsNos != null)
                        {
                            if (resolvedDebugStarsNos.Contains(iStar.StarNo) &&
                                resolvedDebugStarsNos.Contains(jStar.StarNo))
                            {
                                //Trace.Assert(false, "DebugResolved star pair not added to the pyramid areas because the distance is too large.");
                            }
                        }
					    continue;
					}

				    if (!distributor.CheckStar(iStar))
				    {
                        if (resolvedDebugStarsNos != null)
                        {
                            if (resolvedDebugStarsNos.Contains(iStar.StarNo))
                            {
                                //Trace.Assert(false, string.Format("DebugResolved star {0} not added to the pyramid areas because the distributor rejected it.", iStar.StarNo));
                            }
                        }
				        continue;
				    }

					distributor.MarkStar(iStar);
					distributor.MarkStar(jStar);
						
					DistanceEntry entry = new DistanceEntry(iStar, jStar, distDeg * 3600);
                    distancesByMagnitude.Add(entry);

					#region PerStar distance cache
                    ulonglong id1 = new ulonglong(iStar.StarNo, jStar.StarNo);
                    ulonglong id2 = new ulonglong(jStar.StarNo, iStar.StarNo);

					Dictionary<ulonglong, DistanceEntry> map;
                    if (!starsDistanceCache.TryGetValue(iStar.StarNo, out map))
					{
                        map = new Dictionary<ulonglong, DistanceEntry>();
                        starsDistanceCache.Add(iStar.StarNo, map);
					}
					map.Add(id1, entry);

                    if (!starsDistanceCache.TryGetValue(jStar.StarNo, out map))
					{
                        map = new Dictionary<ulonglong, DistanceEntry>();
                        starsDistanceCache.Add(jStar.StarNo, map);
					}
					map.Add(id2, entry);
					#endregion
				}
			}

			//if (resolvedDebugStarsNos != null)
			//{
			//    foreach(uint starNo in resolvedDebugStarsNos)
			//    {
			//        DensityArea area = distributor.m_Areas.FirstOrDefault(a => a.m_IncludedStarNos.Contains(starNo));
			//        if (area != null)
			//            Trace.WriteLine(string.Format("DEBUG ALIGN: Star {0} located to area [{1:0.00}, {2:0.0}]", starNo, area.XMiddle, area.YMiddle));
			//        Trace.Assert(area != null);
			//    }
			//}

            return distributor;
		}
Пример #2
0
        private void BuildPyramidMatchingByMagnitude()
        {
        	Stopwatch sw = new Stopwatch();
        	sw.Start();
            try
            {
                Dictionary<int, ulong> debugResolvesdStarsWithAppliedExclusions =
            		DebugResolvedStars == null
            			? null
            			: DebugResolvedStars
            			  	.Where(kvp => DebugExcludeStars == null || !DebugExcludeStars.ContainsKey(kvp.Key))
            			  	.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

                List<ulong> alwaysIncludeStars = null;
                if (m_ManualPairs != null && m_ManualPairs.Count > 0)
                    alwaysIncludeStars = m_ManualPairs.Values.Select(x => x.StarNo).ToList();

                m_Distributor = BuildPyramidMatchingByMagnitude(
                    m_CelestialPyramidStars, 
                    m_PlateConfig,
					m_Settings,
					debugResolvesdStarsWithAppliedExclusions,
                    alwaysIncludeStars,
                    out m_DistancesByMagnitude, 
                    out m_StarsDistanceCache);
            }
			finally
			{
				sw.Stop();

                if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose())
				    Trace.WriteLine(string.Format(
					    "Building pyramid pairs from a total of {0} stars. Time taken: {1:0}ms", 
					    m_CelestialAllStars.Count, sw.ElapsedMilliseconds));

				if (m_Distributor != null)
				{
                    if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose())
					    Trace.WriteLine(string.Format(
						    "{0} stars used in {1} zones and {2} pairs.",
						    m_StarsDistanceCache.Count,
						    m_Distributor.Areas.Count,
						    m_DistancesByMagnitude.Count));
				}
			}
        }