Пример #1
0
        internal frmIdentifyObjects(IAstrometricFit fit, VideoController videoController, double fovArcMin, DateTime utcTime, double magLimit, string obsCode)
            : this()
        {
            m_Fit = fit;
            m_FovArcMin = fovArcMin;
            m_UtcTime = utcTime;
            m_MagLimit = magLimit;
            m_ObsCode = obsCode;

            pnlProgress.Visible = false;
            pnlEnterTime.Visible = true;

            if (m_UtcTime != DateTime.MinValue && m_UtcTime.Year != 1)
            {
                dtTime.Value = m_UtcTime;
                dtDate.Value = m_UtcTime;
            }
            else
            {
                DateTime? timeStamp = videoController.GetCurrentFrameTime();
                if (timeStamp != null && timeStamp != DateTime.MinValue && timeStamp.Value.Year != 1 /* Has a day component */)
                {
                    dtTime.Value = timeStamp.Value;
                    dtDate.Value = timeStamp.Value;
                }
                else
                {
                    DateTime dt = TangraConfig.Settings.LastUsed.LastIdentifyObjectsDate;
                    if (dt == DateTime.MinValue) dt = DateTime.Now.ToUniversalTime();
                    dtTime.Value = dt;
                    dtDate.Value = dt;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Does the second step of the plate calibration: Least Square with the mapped celestrial stars (from step 1)
        /// </summary>
        /// <param name="fitOrder"></param>
        /// <returns></returns>
        public bool SolvePlateConstantsPhase2(FitOrder fitOrder, bool fineFit)
        {
            LeastSquareFittedAstrometry firstSolution;

            m_SolvedPlate = m_ConstantsSolver.SolveWithLinearRegression(m_AstrometrySettings, out firstSolution);

            if (firstSolution != null)
            {
                if (fineFit)
                {
                    m_Context.InitialSecondAstrometricFit = LeastSquareFittedAstrometry.FromReflectedObject(firstSolution);
                    m_Context.InitialSecondAstrometricFit.FitInfo.AllStarPairs.AddRange(firstSolution.FitInfo.AllStarPairs);
                }
                else
                {
                    m_Context.InitialFirstAstrometricFit = LeastSquareFittedAstrometry.FromReflectedObject(firstSolution);
                    m_Context.InitialFirstAstrometricFit.FitInfo.AllStarPairs.AddRange(firstSolution.FitInfo.AllStarPairs);
                }
            }

            if (m_SolvedPlate != null)
            {
                // TODO: Make this configurable
                if (m_ConstantsSolver.ExcludedForBadResidualsCount < 2 * m_ConstantsSolver.IncludedInSolutionCount)
                {
                    LeastSquareFittedAstrometry lsfa = m_SolvedPlate as LeastSquareFittedAstrometry;
                    // At least 33% of the stars should be included in the solution
                    if (fineFit)
                    {
                        m_Context.SecondAstrometricFit = lsfa;
                    }
                    else
                    {
                        m_Context.FirstAstrometricFit = LeastSquareFittedAstrometry.FromReflectedObject(lsfa);
                        m_Context.FirstAstrometricFit.FitInfo.AllStarPairs.AddRange(lsfa.FitInfo.AllStarPairs);
                    }

#if ASTROMETRY_DEBUG
                    //foreach (PlateConstStarPair pair in lsfa.FitInfo.AllStarPairs)
                    //{
                    //    double x, y;
                    //    lsfa.GetImageCoordsFromRADE(pair.RADeg, pair.DEDeg, out x, out y);
                    //    double dist = lsfa.GetDistanceInArcSec(x, y, pair.x, pair.y);
                    //    Trace.Assert(Math.Abs(dist) < pair.FitInfo.ResidualArcSec*1.1);
                    //}
#endif

                    return(true);
                }
            }

            return(false);
        }
Пример #3
0
        protected virtual void ReinitializePlateConstants()
        {
            m_Image = m_AstrometryController.GetCurrentAstroPlate();
            m_Image.EffectiveFocalLength = m_FLength;

            if (m_SolvedPlate is LeastSquareFittedAstrometry)
            {
                m_SolvedPlate = new LeastSquareFittedAstrometry(m_Image, m_RADegCenter, m_DEDegCenter, null /*m_SolvePlateConts*/);
            }
            else if (m_SolvedPlate is TangentalTransRotAstrometry)
            {
                m_SolvedPlate = new TangentalTransRotAstrometry(m_SolvedPlate as TangentalTransRotAstrometry, m_Image, m_RADegCenter, m_DEDegCenter, m_Eta);
            }
            else
            {
                m_SolvedPlate = new DirectTransRotAstrometry(m_Image, m_RADegCenter, m_DEDegCenter, m_Eta, m_Aspect);
            }
        }
Пример #4
0
        internal frmIdentifyObjects(IAstrometricFit fit, VideoController videoController, double fovArcMin, DateTime utcTime, double magLimit, string obsCode)
            : this()
        {
            m_Fit       = fit;
            m_FovArcMin = fovArcMin;
            m_UtcTime   = utcTime;
            m_MagLimit  = magLimit;
            m_ObsCode   = obsCode;

            pnlProgress.Visible  = false;
            pnlEnterTime.Visible = true;

            if (m_UtcTime != DateTime.MinValue && m_UtcTime.Year != 1)
            {
                dtTime.Value = m_UtcTime;
                dtDate.Value = m_UtcTime;
            }
            else
            {
                DateTime?timeStamp = videoController.GetCurrentFrameTime();
                if (timeStamp != null && timeStamp != DateTime.MinValue && timeStamp.Value.Year != 1 /* Has a day component */)
                {
                    dtTime.Value = timeStamp.Value;
                    dtDate.Value = timeStamp.Value;
                }
                else
                {
                    DateTime dt = TangraConfig.Settings.LastUsed.LastIdentifyObjectsDate;
                    if (dt == DateTime.MinValue)
                    {
                        dt = DateTime.Now.ToUniversalTime();
                    }
                    dtTime.Value = dt;
                    dtDate.Value = dt;
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Does the second step of the plate calibration: Least Square with the mapped celestrial stars (from step 1)
        /// </summary>
        /// <param name="fitOrder"></param>
        /// <returns></returns>
        public bool SolvePlateConstantsPhase2(FitOrder fitOrder, bool fineFit)
        {
            LeastSquareFittedAstrometry firstSolution;
            m_SolvedPlate = m_ConstantsSolver.SolveWithLinearRegression(m_AstrometrySettings, out firstSolution);

            if (firstSolution != null)
            {
                if (fineFit)
                {
                    m_Context.InitialSecondAstrometricFit = LeastSquareFittedAstrometry.FromReflectedObject(firstSolution);
                    m_Context.InitialSecondAstrometricFit.FitInfo.AllStarPairs.AddRange(firstSolution.FitInfo.AllStarPairs);
                }
                else
                {
                    m_Context.InitialFirstAstrometricFit = LeastSquareFittedAstrometry.FromReflectedObject(firstSolution);
                    m_Context.InitialFirstAstrometricFit.FitInfo.AllStarPairs.AddRange(firstSolution.FitInfo.AllStarPairs);
                }
            }

            if (m_SolvedPlate != null)
            {
                // TODO: Make this configurable
                if (m_ConstantsSolver.ExcludedForBadResidualsCount < 2 * m_ConstantsSolver.IncludedInSolutionCount)
                {
                    LeastSquareFittedAstrometry lsfa = m_SolvedPlate as LeastSquareFittedAstrometry;
                    // At least 33% of the stars should be included in the solution
                    if (fineFit)
                        m_Context.SecondAstrometricFit = lsfa;
                    else
                    {
                        m_Context.FirstAstrometricFit = LeastSquareFittedAstrometry.FromReflectedObject(lsfa);
                        m_Context.FirstAstrometricFit.FitInfo.AllStarPairs.AddRange(lsfa.FitInfo.AllStarPairs);
                    }

            #if ASTROMETRY_DEBUG
                    //foreach (PlateConstStarPair pair in lsfa.FitInfo.AllStarPairs)
                    //{
                    //    double x, y;
                    //    lsfa.GetImageCoordsFromRADE(pair.RADeg, pair.DEDeg, out x, out y);
                    //    double dist = lsfa.GetDistanceInArcSec(x, y, pair.x, pair.y);
                    //    Trace.Assert(Math.Abs(dist) < pair.FitInfo.ResidualArcSec*1.1);
                    //}
            #endif

                    return true;
                }
            }

            return false;
        }
Пример #6
0
		private bool CheckTriangle(int i, int j, int k, double dij, double dik, double djk, double toleranceInArcSec)
		{
			// Candidates for the matches
			int idxIJLower = m_IndexLower[Math.Min(Math.Max((int)Math.Round(dij - toleranceInArcSec) - 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxIJUpper = m_IndexUpper[Math.Min(Math.Max((int)Math.Round(dij + toleranceInArcSec) + 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxIKLower = m_IndexLower[Math.Min(Math.Max((int)Math.Round(dik - toleranceInArcSec) - 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxIKUpper = m_IndexUpper[Math.Min(Math.Max((int)Math.Round(dik + toleranceInArcSec) + 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxJKLower = m_IndexLower[Math.Min(Math.Max((int)Math.Round(djk - toleranceInArcSec) - 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxJKUpper = m_IndexUpper[Math.Min(Math.Max((int)Math.Round(djk + toleranceInArcSec) + 1, 0), m_IndexUpper.Keys.Count - 1)];

			DistanceEntry ijEntry = null;
			DistanceEntry ikEntry = null;
			DistanceEntry jkEntry = null;

			for (int ij = idxIJLower; ij <= idxIJUpper; ij++)
			{
				ijEntry = m_Entries[ij];
				if (ijEntry.DistanceArcSec + toleranceInArcSec < dij) continue;
				if (ijEntry.DistanceArcSec - toleranceInArcSec > dij) continue;

				for (int ik = idxIKLower; ik <= idxIKUpper; ik++)
				{
					ikEntry = m_Entries[ik];
					if (ikEntry.DistanceArcSec + toleranceInArcSec < dik) continue;
					if (ikEntry.DistanceArcSec - toleranceInArcSec > dik) continue;

                    ulong foundIdx0 = uint.MaxValue;
                    ulong needIdx1 = uint.MaxValue;
                    ulong needIdx2 = uint.MaxValue;
					if (ikEntry.Star1.StarNo == ijEntry.Star1.StarNo)
					{
						// ik_1 = ij_1 = (i)
						foundIdx0 = ikEntry.Star1.StarNo;
						needIdx1 = ikEntry.Star2.StarNo;
						needIdx2 = ijEntry.Star2.StarNo;
					}
					else if (ikEntry.Star1.StarNo == ijEntry.Star2.StarNo)
					{
						// ik_1 = ij_2 = (i)
						foundIdx0 = ikEntry.Star1.StarNo;
						needIdx1 = ikEntry.Star2.StarNo; // (k)
						needIdx2 = ijEntry.Star1.StarNo; // (j)
					}
					else if (ikEntry.Star2.StarNo == ijEntry.Star1.StarNo)
					{
						// ik_2 = ij_1 = (i)
						foundIdx0 = ikEntry.Star2.StarNo;
						needIdx1 = ikEntry.Star1.StarNo; // (k)
						needIdx2 = ijEntry.Star2.StarNo; // (j)
					}
					else if (ikEntry.Star2.StarNo == ijEntry.Star2.StarNo)
					{
						// ik_2 = ij_2 = (i)
						foundIdx0 = ikEntry.Star2.StarNo;
						needIdx1 = ikEntry.Star1.StarNo; // (k)
						needIdx2 = ijEntry.Star1.StarNo; // (j)
					}
					else
						continue;

					if (needIdx1 == needIdx2) continue;

#if DEBUG
                                int bestKId = -1;
                                double bestDiff = double.MaxValue;
#endif
					for (int jk = idxJKLower; jk <= idxJKUpper; jk++)
					{
						jkEntry = m_Entries[jk];
#if DEBUG

                                    double diff = Math.Abs(jkEntry.DistanceArcSec - djk);
                                    if (diff < bestDiff)
                                    {
                                        bestDiff = diff;
                                        bestKId = jk;
                                    }
#endif

						if (jkEntry.DistanceArcSec + toleranceInArcSec < djk) continue;
						if (jkEntry.DistanceArcSec - toleranceInArcSec > djk) continue;

						if (jkEntry.Star1.StarNo == needIdx1 &&
							jkEntry.Star2.StarNo == needIdx2)
						{
#if PYRAMID_DEBUG
                                        Trace.WriteLine(
                                            string.Format("Match: {0} - {1} - {2} ({3}-{4}-{5}) {6}\" {7}\" {8}\"",
                                                          foundIdx0, needIdx1, needIdx2, i, j, k, dij.ToString("0.0"),
                                                          dik.ToString("0.0"), djk.ToString("0.0")));
#endif

							m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
														   foundIdx0, needIdx1, needIdx2, toleranceInArcSec);
							if (m_Solution != null) return true;
						}

						if (jkEntry.Star1.StarNo == needIdx2 &&
							jkEntry.Star2.StarNo == needIdx1)
						{
#if PYRAMID_DEBUG
                                        Trace.WriteLine(
                                            string.Format("Match: {0} - {1} - {2} ({3}-{4}-{5}) {6}\" {7}\" {8}\"",
                                                          foundIdx0, needIdx1, needIdx2, i, j, k, dij.ToString("0.0"),
                                                          dik.ToString("0.0"), djk.ToString("0.0")));
#endif
							m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
														   foundIdx0, needIdx1, needIdx2, toleranceInArcSec);
							if (m_Solution != null) return true;
						}
					}

#if DEBUG
                                jkEntry = m_Entries[bestKId];

                                if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose())
                                    Debug.WriteLine(
                                        string.Format("3-rd star match failed by {0}\" ({1}, {2}, {3}) -> ({4}: {5}, {6}); [{7},{8}]",
                                        bestDiff, i, j, k,
                                        foundIdx0, needIdx1, needIdx2,
                                        jkEntry.Star1.StarNo, jkEntry.Star2.StarNo));
#endif
				}
			}


			return false;			
		}
Пример #7
0
		private bool CheckTriangleWithRatios(int i, int j, int k, ImagePixel iCenter, ImagePixel jCenter, ImagePixel kCenter, double toleranceInArcSec)
		{
			double dijMax = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, jCenter.XDouble, jCenter.YDouble, (1 - m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double dijMin = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, jCenter.XDouble, jCenter.YDouble, (1 + m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double dikMax = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 - m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double dikMin = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 + m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double djkMax = m_PlateConfig.GetDistanceInArcSec(jCenter.XDouble, jCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 - m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double djkMin = m_PlateConfig.GetDistanceInArcSec(jCenter.XDouble, jCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 + m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
			
			
			// Candidates for the matches
			int idxIJLower = m_IndexLower[Math.Min(Math.Max((int)Math.Round(dijMin - toleranceInArcSec) - 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxIJUpper = m_IndexUpper[Math.Min(Math.Max((int)Math.Round(dijMax + toleranceInArcSec) + 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxIKLower = m_IndexLower[Math.Min(Math.Max((int)Math.Round(dikMin - toleranceInArcSec) - 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxIKUpper = m_IndexUpper[Math.Min(Math.Max((int)Math.Round(dikMax + toleranceInArcSec) + 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxJKLower = m_IndexLower[Math.Min(Math.Max((int)Math.Round(djkMin - toleranceInArcSec) - 1, 0), m_IndexUpper.Keys.Count - 1)];
			int idxJKUpper = m_IndexUpper[Math.Min(Math.Max((int)Math.Round(djkMax + toleranceInArcSec) + 1, 0), m_IndexUpper.Keys.Count - 1)];

            ulong iDebugStarNo = 0, jDebugStarNo = 0, kDebugStarNo = 0;
			bool debugStarMatch = false;
			if (DebugResolvedStars != null)
			{
				if (DebugResolvedStars.TryGetValue(i, out iDebugStarNo) &&
					DebugResolvedStars.TryGetValue(j, out jDebugStarNo) &&
					DebugResolvedStars.TryGetValue(k, out kDebugStarNo))
				{
                    IStar iStarAllDbg = m_CelestialAllStars.FirstOrDefault(s => s.StarNo == iDebugStarNo);
                    IStar jStarAllDbg = m_CelestialAllStars.FirstOrDefault(s => s.StarNo == jDebugStarNo);
                    IStar kStarAllDbg = m_CelestialAllStars.FirstOrDefault(s => s.StarNo == kDebugStarNo);

#if ASTROMETRY_DEBUG
                    Trace.Assert(iStarAllDbg != null);
                    Trace.Assert(jStarAllDbg != null);
                    Trace.Assert(kStarAllDbg != null);
#endif

                    IStar iStarDbg = m_CelestialPyramidStars.FirstOrDefault(s => s.StarNo == iDebugStarNo);
                    IStar jStarDbg = m_CelestialPyramidStars.FirstOrDefault(s => s.StarNo == jDebugStarNo);
                    IStar kStarDbg = m_CelestialPyramidStars.FirstOrDefault(s => s.StarNo == kDebugStarNo);

                    if (iStarDbg != null && jStarDbg != null && kStarDbg != null)
                    {
                        debugStarMatch = true;

                        DistanceEntry deIJDbg = m_Entries.FirstOrDefault(e => (e.Star1.StarNo == iDebugStarNo && e.Star2.StarNo == jDebugStarNo) || (e.Star1.StarNo == jDebugStarNo && e.Star2.StarNo == iDebugStarNo));
                        DistanceEntry deIKDbg = m_Entries.FirstOrDefault(e => (e.Star1.StarNo == iDebugStarNo && e.Star2.StarNo == kDebugStarNo) || (e.Star1.StarNo == kDebugStarNo && e.Star2.StarNo == iDebugStarNo));
                        DistanceEntry deJKDbg = m_Entries.FirstOrDefault(e => (e.Star1.StarNo == kDebugStarNo && e.Star2.StarNo == jDebugStarNo) || (e.Star1.StarNo == jDebugStarNo && e.Star2.StarNo == kDebugStarNo));

#if ASTROMETRY_DEBUG
                        Trace.Assert(deIJDbg != null);
                        Trace.Assert(deIKDbg != null);
                        Trace.Assert(deJKDbg != null);
#endif

                        double dijDbg = AngleUtility.Elongation(iStarDbg.RADeg, iStarDbg.DEDeg, jStarDbg.RADeg, jStarDbg.DEDeg) * 3600;
                        double dikDbg = AngleUtility.Elongation(iStarDbg.RADeg, iStarDbg.DEDeg, kStarDbg.RADeg, kStarDbg.DEDeg) * 3600;
                        double djkDbg = AngleUtility.Elongation(kStarDbg.RADeg, kStarDbg.DEDeg, jStarDbg.RADeg, jStarDbg.DEDeg) * 3600;

#if ASTROMETRY_DEBUG
                        Trace.Assert(Math.Abs(dijDbg - deIJDbg.DistanceArcSec) < 1);
                        Trace.Assert(Math.Abs(dikDbg - deIKDbg.DistanceArcSec) < 1);
                        Trace.Assert(Math.Abs(djkDbg - deJKDbg.DistanceArcSec) < 1);
#endif
                        //TODO: Find the real focal length, then find the difference in percentages

                        //NOTE: Stars are not included because initial focal length is not correct !!!
#if ASTROMETRY_DEBUG
                        Trace.Assert(dijMax > dijDbg);
                        Trace.Assert(dijMin < dijDbg);
                        Trace.Assert(dikMax > dikDbg);
                        Trace.Assert(dikMin < dikDbg);
                        Trace.Assert(djkMax > djkDbg);
                        Trace.Assert(djkMin < djkDbg);
#endif                        
                    }
                    else
                    {
#if ASTROMETRY_DEBUG
                        if (iStarDbg == null)
                            Trace.Assert((iStarAllDbg.Mag > m_PyramidMaxMag) || (iStarAllDbg.Mag < m_PyramidMinMag));

                        if (jStarDbg == null)
                            Trace.Assert((jStarAllDbg.Mag > m_PyramidMaxMag) || (jStarAllDbg.Mag < m_PyramidMinMag));

                        if (kStarDbg == null)
                            Trace.Assert((kStarAllDbg.Mag > m_PyramidMaxMag) || (kStarAllDbg.Mag < m_PyramidMinMag));
#endif
                    }
				}
			}

			DistanceEntry ijEntry = null;
			DistanceEntry ikEntry = null;
			DistanceEntry jkEntry = null;

			for (int ij = idxIJLower; ij <= idxIJUpper; ij++)
			{
				ijEntry = m_Entries[ij];

				if (debugStarMatch)
				{
					if ((ijEntry.Star1.StarNo == iDebugStarNo && ijEntry.Star2.StarNo == jDebugStarNo) ||
						(ijEntry.Star1.StarNo == jDebugStarNo && ijEntry.Star2.StarNo == iDebugStarNo))
					{
#if ASTROMETRY_DEBUG
						Trace.Assert(ijEntry.DistanceArcSec + toleranceInArcSec >= dijMin);
						Trace.Assert(ijEntry.DistanceArcSec - toleranceInArcSec <= dijMax);
#endif
					}
				}

				if (ijEntry.DistanceArcSec + toleranceInArcSec < dijMin) continue;
				if (ijEntry.DistanceArcSec - toleranceInArcSec > dijMax) continue;

				for (int ik = idxIKLower; ik <= idxIKUpper; ik++)
				{
					ikEntry = m_Entries[ik];

				    bool debugIKPairFound = false;
					if (debugStarMatch)
					{
						if ((ikEntry.Star1.StarNo == iDebugStarNo && ikEntry.Star2.StarNo == kDebugStarNo) ||
							(ikEntry.Star1.StarNo == kDebugStarNo && ikEntry.Star2.StarNo == iDebugStarNo))
						{
#if ASTROMETRY_DEBUG
							Trace.Assert(ikEntry.DistanceArcSec + toleranceInArcSec >= dikMin);
							Trace.Assert(ikEntry.DistanceArcSec - toleranceInArcSec <= dikMax);
							Trace.Assert(Math.Abs(ijEntry.DistanceArcSec - (dijMin / dikMin) * ikEntry.DistanceArcSec) < toleranceInArcSec);
#endif
						    debugIKPairFound = true;
						}
					}

					if (ikEntry.DistanceArcSec + toleranceInArcSec < dikMin) continue;
					if (ikEntry.DistanceArcSec - toleranceInArcSec > dikMax) continue;

					if (ikEntry.Star1.StarNo != ijEntry.Star1.StarNo &&
						ikEntry.Star1.StarNo != ijEntry.Star2.StarNo &&
						ikEntry.Star2.StarNo != ijEntry.Star1.StarNo &&
						ikEntry.Star2.StarNo != ijEntry.Star2.StarNo)
					{
						// There is no possible (i, j, k) configuration that involves the same 3 stars
						continue;
					}

					double ratioDifference = Math.Abs(ijEntry.DistanceArcSec - (dijMin/dikMin) * ikEntry.DistanceArcSec);
					if (ratioDifference > toleranceInArcSec) continue;
					

					// Ratios are preserved when changing the focal length (with linear fit) so check the ratios here
					double fittedFocalLength = 
						m_PlateConfig.GetFocalLengthFromMatch(
							ijEntry.DistanceArcSec, ikEntry.DistanceArcSec, 
							iCenter, jCenter, kCenter, 
							toleranceInArcSec, m_Settings.PyramidFocalLengthAllowance);

                    if (debugIKPairFound)
					{
#if ASTROMETRY_DEBUG
					    Trace.Assert(!double.IsNaN(fittedFocalLength));
#endif
					}

					if (double.IsNaN(fittedFocalLength)) continue;

					double djk = m_PlateConfig.GetDistanceInArcSec(jCenter.XDouble, jCenter.YDouble, kCenter.XDouble, kCenter.YDouble, fittedFocalLength);

                    ulong iStarNo = uint.MaxValue;
                    ulong needIdx1 = uint.MaxValue;
                    ulong needIdx2 = uint.MaxValue;
					if (ikEntry.Star1.StarNo == ijEntry.Star1.StarNo)
					{
						// ik_1 = ij_1 = (i)
						iStarNo = ikEntry.Star1.StarNo;
						needIdx1 = ikEntry.Star2.StarNo;
						needIdx2 = ijEntry.Star2.StarNo;
					}
					else if (ikEntry.Star1.StarNo == ijEntry.Star2.StarNo)
					{
						// ik_1 = ij_2 = (i)
						iStarNo = ikEntry.Star1.StarNo;
						needIdx1 = ikEntry.Star2.StarNo; // (k)
						needIdx2 = ijEntry.Star1.StarNo; // (j)
					}
					else if (ikEntry.Star2.StarNo == ijEntry.Star1.StarNo)
					{
						// ik_2 = ij_1 = (i)
						iStarNo = ikEntry.Star2.StarNo;
						needIdx1 = ikEntry.Star1.StarNo; // (k)
						needIdx2 = ijEntry.Star2.StarNo; // (j)
					}
					else if (ikEntry.Star2.StarNo == ijEntry.Star2.StarNo)
					{
						// ik_2 = ij_2 = (i)
						iStarNo = ikEntry.Star2.StarNo;
						needIdx1 = ikEntry.Star1.StarNo; // (k)
						needIdx2 = ijEntry.Star1.StarNo; // (j)
					}
					else
						continue;

					if (needIdx1 == needIdx2) continue;

					jkEntry = m_Entries.Where(e => 
						(e.Star1.StarNo == needIdx1 && e.Star2.StarNo == needIdx2) ||
						(e.Star1.StarNo == needIdx2 && e.Star2.StarNo == needIdx1)).FirstOrDefault();

                    if (debugIKPairFound)
                    {
#if ASTROMETRY_DEBUG
                        Trace.Assert(jkEntry != null);
#endif

                        if (jkEntry != null)
                        {
#if ASTROMETRY_DEBUG
                            Trace.Assert(jkEntry.DistanceArcSec + toleranceInArcSec >= djk);
                            Trace.Assert(jkEntry.DistanceArcSec - toleranceInArcSec <= djk);

                            Trace.Assert(jkEntry.DistanceArcSec + toleranceInArcSec >= djkMin);
                            Trace.Assert(jkEntry.DistanceArcSec - toleranceInArcSec <= djkMax);                            
#endif
                        }
                    }

                    if (jkEntry != null)
                    {
                        ulong jStarNo = ulong.MinValue;
                        ulong kStarNo = ulong.MinValue;

                        if (jkEntry.DistanceArcSec + toleranceInArcSec < djkMin) continue;
                        if (jkEntry.DistanceArcSec - toleranceInArcSec > djkMax) continue;

                        if (jkEntry.DistanceArcSec + toleranceInArcSec < djk) continue;
                        if (jkEntry.DistanceArcSec - toleranceInArcSec > djk) continue;

                        if (jkEntry.Star1.StarNo == needIdx1 &&
                            jkEntry.Star2.StarNo == needIdx2)
                        {
							
                            m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
														   iStarNo, needIdx1, needIdx2, fittedFocalLength, true, toleranceInArcSec);
                            if (m_Solution == null)
                                continue;

                            jStarNo = needIdx1;
                            kStarNo = needIdx2;
                        }

                        if (jkEntry.Star1.StarNo == needIdx2 &&
                            jkEntry.Star2.StarNo == needIdx1)
                        {
                            m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
														   iStarNo, needIdx1, needIdx2, fittedFocalLength, true, toleranceInArcSec);
                            if (m_Solution == null)
                                continue;

                            jStarNo = needIdx2;
                            kStarNo = needIdx1;
                        }

                        if (m_Solution != null)
                        {
                            if (TangraConfig.Settings.Astrometry.PyramidNumberOfPivots == 3)
                                // Exist the initial alignment with only 3 candidate pivots
                                return true;

                            for (int l = 0; l < m_StarMap.Features.Count; l++)
                            {
                                var piramid = m_StarMap.Features[l];
                                if (piramid.FeatureId == i || piramid.FeatureId == j || piramid.FeatureId == k)
                                    continue;

                                var lCenter = piramid.GetCenter();

                                // NOTE: Continue until a set of distances is found in the cache for the 4-th pivot
                                double dli = m_PlateConfig.GetDistanceInArcSec(lCenter.XDouble, lCenter.YDouble, iCenter.XDouble, iCenter.YDouble, fittedFocalLength);
                                double dlj = m_PlateConfig.GetDistanceInArcSec(lCenter.XDouble, lCenter.YDouble, jCenter.XDouble, jCenter.YDouble, fittedFocalLength);
                                double dlk = m_PlateConfig.GetDistanceInArcSec(lCenter.XDouble, lCenter.YDouble, kCenter.XDouble, kCenter.YDouble, fittedFocalLength);

                                List<DistanceEntry> ilCandidates = m_DistancesByMagnitude
                                    .Where(e =>
                                        (e.Star1.StarNo == iStarNo || e.Star2.StarNo == iStarNo) &&
                                        e.DistanceArcSec < dli + toleranceInArcSec && e.DistanceArcSec > dli - toleranceInArcSec)
                                    .ToList();

                                foreach (var cand_il in ilCandidates)
                                {
                                    var lStar = cand_il.Star1.StarNo == iStarNo ? cand_il.Star2 : cand_il.Star1;

                                    List<DistanceEntry> jlCandidates = m_DistancesByMagnitude
                                    .Where(e =>
                                        ((e.Star1.StarNo == jStarNo && e.Star2.StarNo == lStar.StarNo) ||
                                         (e.Star1.StarNo == lStar.StarNo && e.Star2.StarNo == jStarNo)) &&
                                        e.DistanceArcSec < dlj + toleranceInArcSec && e.DistanceArcSec > dlj - toleranceInArcSec)
                                    .ToList();

                                    List<DistanceEntry> klCandidates = m_DistancesByMagnitude
                                        .Where(e =>
                                            ((e.Star1.StarNo == kStarNo && e.Star2.StarNo == lStar.StarNo) ||
                                             (e.Star1.StarNo == lStar.StarNo && e.Star2.StarNo == kStarNo)) &&
                                            e.DistanceArcSec < dlk + toleranceInArcSec && e.DistanceArcSec > dlk - toleranceInArcSec)
                                        .ToList();

                                    if (jlCandidates.Count > 0 && klCandidates.Count > 0)
                                    {
                                        if (klCandidates.Count > 0)
                                            return true;
                                    }
                                }
                            }
                        }
                    }
//#if DEBUG
//                                int bestKId = -1;
//                                double bestDiff = double.MaxValue;
//#endif
//                    for (int jk = idxJKLower; jk <= idxJKUpper; jk++)
//                    {
//                        jkEntry = m_Entries[jk];
//#if DEBUG

//                                    double diff = Math.Abs(jkEntry.DistanceArcSec - djk);
//                                    if (diff < bestDiff)
//                                    {
//                                        bestDiff = diff;
//                                        bestKId = jk;
//                                    }
//#endif


//                    }

//#if DEBUG
//                                jkEntry = m_Entries[bestKId];
//                                Debug.WriteLine(
//                                    string.Format("3-rd star match failed by {0}\" ({1}, {2}, {3}) -> ({4}: {5}, {6}); [{7},{8}]",
//                                    bestDiff, i, j, k,
//                                    foundIdx0, needIdx1, needIdx2,
//                                    jkEntry.Star1.StarNo, jkEntry.Star2.StarNo));
//#endif
				}
			}


			return false;
		}
Пример #8
0
		private bool TryMatchingPairsFromPreviousFit(IStarMap starMap)
		{
			ThreeStarFit.StarPair[] pairs = new ThreeStarFit.StarPair[3];
			Dictionary<ImagePixel, IStar> matchedPairs = new Dictionary<ImagePixel, IStar>();
            Dictionary<int, ulong> matchedFeatureIdToStarIdIndexes = new Dictionary<int, ulong>();

			int idx = 0;
			foreach (PlateConstStarPair pair in m_PreviousFit.AllStarPairs)
			{
				if (pair.FitInfo.ExcludedForHighResidual) continue;
                StarMapFeature ftr = starMap.GetFeatureInRadius((int)pair.x, (int)pair.y, (int)CoreAstrometrySettings.Default.SearchArea);
				if (ftr != null)
				{
					ImagePixel center = starMap.GetCentroid(
                        (int)pair.x, (int)pair.y, (int)CoreAstrometrySettings.Default.SearchArea);
					IStar star = null;

					foreach (IStar s in m_CelestialPyramidStars)
					{
						if (s.StarNo == pair.StarNo)
						{
							star = s;
							break;
						}
					}

					if (star != null &&
						center != null &&
						!matchedFeatureIdToStarIdIndexes.ContainsKey(ftr.FeatureId))
					{
						if (idx < 3)
						{
							pairs[idx] = new ThreeStarFit.StarPair(center.X, center.Y);
							pairs[idx].RADeg = star.RADeg;
							pairs[idx].DEDeg = star.DEDeg;
							pairs[idx].Star = star;
							idx++;
						}

						matchedPairs.Add(center, star);
						matchedFeatureIdToStarIdIndexes.Add(ftr.FeatureId, star.StarNo);
					}
				}
			}

			// Shortcurcuit to FeautreId - StarNo detection
			if (matchedPairs.Count >= m_Settings.MinimumNumberOfStars)
			{
                // When there was a previous fit and we have sufficient stars from the current star map
                // then don't require % of the bright features to approve the solution. Do it as a calibration fit (not too precise)
                LeastSquareFittedAstrometry fit = SolveStarPairs(
                    starMap, matchedPairs,
                    matchedFeatureIdToStarIdIndexes,
                    pairs[0], pairs[1], pairs[2], m_PreviousFit.FittedFocalLength, null, 
                    TangraConfig.Settings.Astrometry.MinimumNumberOfStars);

                if (fit != null)
                {
                    m_Solution = fit;
                    m_MatchedPairs = matchedPairs;
                    m_MatchedFeatureIdToStarIdIndexes = matchedFeatureIdToStarIdIndexes;
                    return true;
                }
            }

			return false;
		}
Пример #9
0
		private bool TryMatchingPairsFromManualPairs(IStarMap starMap)
		{
			ThreeStarFit.StarPair[] pairs = new ThreeStarFit.StarPair[3];
			Dictionary<ImagePixel, IStar> matchedPairs = new Dictionary<ImagePixel, IStar>();
            Dictionary<int, ulong> matchedFeatureIdToStarIdIndexes = new Dictionary<int, ulong>();

			int idx = 0;
			foreach (StarMapFeature feature in m_ManualPairs.Keys)
			{
				IStar star = m_ManualPairs[feature];
				ImagePixel center = feature.GetCenter();

                StarMapFeature ftr = starMap.GetFeatureInRadius((int)center.X, (int)center.Y, (int)CoreAstrometrySettings.Default.SearchArea);
				if (ftr != null)
				{
					if (!matchedFeatureIdToStarIdIndexes.ContainsKey(ftr.FeatureId))
					{
						if (idx < 3)
						{
							pairs[idx] = new ThreeStarFit.StarPair(center.X, center.Y);
							pairs[idx].RADeg = star.RADeg;
							pairs[idx].DEDeg = star.DEDeg;
							pairs[idx].Star = star;
							idx++;
						}

						matchedPairs.Add(center, star);
						matchedFeatureIdToStarIdIndexes.Add(ftr.FeatureId, star.StarNo);
					}
				}
			}

			if (matchedPairs.Count >= m_Settings.MinimumNumberOfStars)
			{
                // When there was a previous fit and we have sufficient stars from the current star map
                // then don't require % of the bright features to approve the solution. Do it as a calibration fit (not too precise)
                LeastSquareFittedAstrometry fit = SolveStarPairs(
                    starMap, matchedPairs,
                    matchedFeatureIdToStarIdIndexes,
                    pairs[0], pairs[1], pairs[2], m_PlateConfig.EffectiveFocalLength, null, 
                    TangraConfig.Settings.Astrometry.MinimumNumberOfStars);

                if (fit != null)
                {
                    m_Solution = fit;
                    m_MatchedPairs = matchedPairs;
                    m_MatchedFeatureIdToStarIdIndexes = matchedFeatureIdToStarIdIndexes;
                    return true;
                }
            }

			return false;
		}
Пример #10
0
		private bool CheckTrianglesWithRatiosByMagnitude(int i, int j, int k, ImagePixel iCenter, ImagePixel jCenter, ImagePixel kCenter, double toleranceInArcSec)
		{
		    if (iCenter == null || jCenter == null || kCenter == null) return false;

			double dijMax = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, jCenter.XDouble, jCenter.YDouble, (1 - m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double dijMin = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, jCenter.XDouble, jCenter.YDouble, (1 + m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double dikMax = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 - m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double dikMin = m_PlateConfig.GetDistanceInArcSec(iCenter.XDouble, iCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 + m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double djkMax = m_PlateConfig.GetDistanceInArcSec(jCenter.XDouble, jCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 - m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
            double djkMin = m_PlateConfig.GetDistanceInArcSec(jCenter.XDouble, jCenter.YDouble, kCenter.XDouble, kCenter.YDouble, (1 + m_Settings.PyramidFocalLengthAllowance) * m_PlateConfig.EffectiveFocalLength);
			
			List<DistanceEntry> ijCandidates = m_DistancesByMagnitude
				.Where(e => e.DistanceArcSec > dijMin && e.DistanceArcSec < dijMax).ToList();

		    if (m_ManualPairs != null && m_ManualPairs.Count <= 3) 
                LimitIJtoManualPairs(ijCandidates);

			bool debugFieldIdentified = true;
			bool debug = false;
            ulong debugiStarNo = 0;
            ulong debugjStarNo = 0;
            ulong debugkStarNo = 0;
			if (DebugResolvedStars != null)
			{
				if (DebugResolvedStars.ContainsKey(i) &&
					DebugResolvedStars.ContainsKey(j) &&
					DebugResolvedStars.ContainsKey(k))
				{
					debugiStarNo = DebugResolvedStars[i];
					debugjStarNo = DebugResolvedStars[j];
					debugkStarNo = DebugResolvedStars[k];

					debug = true;
					debugFieldIdentified = false;
				}
			}

			try
			{
				if (debug)
				{
					// The ijCandidates must contain the IJ pair
					DistanceEntry rightijEntry = ijCandidates.FirstOrDefault(c =>
						(c.Star1.StarNo == debugiStarNo && c.Star2.StarNo == debugjStarNo) ||
						(c.Star1.StarNo == debugjStarNo && c.Star2.StarNo == debugiStarNo));

					if(rightijEntry == null)
					{
						DistanceEntry masterijEntry = 
							m_DistancesByMagnitude.FirstOrDefault(c =>
						        (c.Star1.StarNo == debugiStarNo && c.Star2.StarNo == debugjStarNo) ||
						        (c.Star1.StarNo == debugjStarNo && c.Star2.StarNo == debugiStarNo));

						Trace.Assert(masterijEntry != null);
					}
				}

				foreach (DistanceEntry ijEntry in ijCandidates)
				{
					List<DistanceEntry> ikCandidates = m_DistancesByMagnitude
						.Where(e =>
							(e.Star1.StarNo == ijEntry.Star1.StarNo || e.Star2.StarNo == ijEntry.Star1.StarNo ||
							 e.Star1.StarNo == ijEntry.Star2.StarNo || e.Star2.StarNo == ijEntry.Star2.StarNo) &&
							 e.DistanceArcSec > dikMin && e.DistanceArcSec < dikMax)
						.ToList();

                    if (m_ManualPairs != null && m_ManualPairs.Count == 3)
                        LimitIKtoManualPairs(ikCandidates);

					if (debug && (
							(debugiStarNo == ijEntry.Star1.StarNo && debugjStarNo == ijEntry.Star2.StarNo) ||
							(debugiStarNo == ijEntry.Star2.StarNo && debugjStarNo == ijEntry.Star1.StarNo)))
					{
						// The ikCandidates must contain the IK pair
						DistanceEntry rightikEntry = ikCandidates.FirstOrDefault(c =>
							(c.Star1.StarNo == debugkStarNo || c.Star2.StarNo == debugkStarNo));

						if (rightikEntry == null)
						{
							rightikEntry = m_DistancesByMagnitude.FirstOrDefault(c =>
								(c.Star1.StarNo == debugiStarNo && c.Star2.StarNo == debugkStarNo) ||
								(c.Star1.StarNo == debugkStarNo && c.Star2.StarNo == debugiStarNo));

							if (rightikEntry != null)
								Trace.Assert(rightikEntry.DistanceArcSec > dikMin && rightikEntry.DistanceArcSec < dikMax);
							else
								Trace.Assert(false, string.Format("Cannot find the ik pair ({0}, {1}) in the area distances.", debugiStarNo, debugkStarNo));
						}

					}



					foreach (DistanceEntry ikEntry in ikCandidates)
					{
						bool debugTrippleFound = false;
						if (debug && 
							((debugiStarNo == ijEntry.Star1.StarNo && debugjStarNo == ijEntry.Star2.StarNo) ||
							(debugiStarNo == ijEntry.Star2.StarNo && debugjStarNo == ijEntry.Star1.StarNo)) &&
							(debugkStarNo == ikEntry.Star1.StarNo || debugkStarNo == ikEntry.Star2.StarNo))
						{
							debugTrippleFound = true;
						}
					
						// Ratios are preserved when changing the focal length (with linear fit) so check the ratios here
						double fittedFocalLength =
							m_PlateConfig.GetFocalLengthFromMatch(
								ijEntry.DistanceArcSec, ikEntry.DistanceArcSec,
								iCenter, jCenter, kCenter,
								toleranceInArcSec, m_Settings.PyramidFocalLengthAllowance);

						if (double.IsNaN(fittedFocalLength))
						{
							Trace.Assert(!debugTrippleFound);
							continue;
						}

						double djk = m_PlateConfig.GetDistanceInArcSec(jCenter.XDouble, jCenter.YDouble, kCenter.XDouble, kCenter.YDouble, fittedFocalLength);

                        ulong iStarNo = uint.MaxValue;
                        ulong needIdx1 = uint.MaxValue;
                        ulong needIdx2 = uint.MaxValue;

						if (ikEntry.Star1.StarNo == ijEntry.Star1.StarNo)
						{
							// ik_1 = ij_1 = (i)
							iStarNo = ikEntry.Star1.StarNo;
							needIdx1 = ikEntry.Star2.StarNo;
							needIdx2 = ijEntry.Star2.StarNo;
						}
						else if (ikEntry.Star1.StarNo == ijEntry.Star2.StarNo)
						{
							// ik_1 = ij_2 = (i)
							iStarNo = ikEntry.Star1.StarNo;
							needIdx1 = ikEntry.Star2.StarNo; // (k)
							needIdx2 = ijEntry.Star1.StarNo; // (j)
						}
						else if (ikEntry.Star2.StarNo == ijEntry.Star1.StarNo)
						{
							// ik_2 = ij_1 = (i)
							iStarNo = ikEntry.Star2.StarNo;
							needIdx1 = ikEntry.Star1.StarNo; // (k)
							needIdx2 = ijEntry.Star2.StarNo; // (j)
						}
						else if (ikEntry.Star2.StarNo == ijEntry.Star2.StarNo)
						{
							// ik_2 = ij_2 = (i)
							iStarNo = ikEntry.Star2.StarNo;
							needIdx1 = ikEntry.Star1.StarNo; // (k)
							needIdx2 = ijEntry.Star1.StarNo; // (j)
						}
						else
						{
							Trace.Assert(!debugTrippleFound);
							continue;
						}
							

						if (needIdx1 == needIdx2)
						{
							Trace.Assert(!debugTrippleFound);
							continue;
						}

						DistanceEntry jkEntry = m_DistancesByMagnitude.Where(e =>
							(e.Star1.StarNo == needIdx1 && e.Star2.StarNo == needIdx2) ||
							(e.Star1.StarNo == needIdx2 && e.Star2.StarNo == needIdx1)).FirstOrDefault();

						if (jkEntry != null)
						{
                            ulong jStarNo = uint.MaxValue;
                            ulong kStarNo = uint.MaxValue;
                        
							if (jkEntry.DistanceArcSec + toleranceInArcSec < djkMin)
							{
								Trace.Assert(!debugTrippleFound);
								continue;
							}
							if (jkEntry.DistanceArcSec - toleranceInArcSec > djkMax)
							{
								Trace.Assert(!debugTrippleFound);
								continue;
							}

							if (jkEntry.DistanceArcSec + toleranceInArcSec < djk)
							{
								Trace.Assert(!debugTrippleFound);
								continue;
							}
							if (jkEntry.DistanceArcSec - toleranceInArcSec > djk)
							{
								Trace.Assert(!debugTrippleFound);
								continue;
							}

							if (jkEntry.Star1.StarNo == needIdx1 &&
								jkEntry.Star2.StarNo == needIdx2)
							{

								m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
															   iStarNo, needIdx1, needIdx2, fittedFocalLength, true, toleranceInArcSec);
							    if (m_Solution != null)
							    {
							        jStarNo = needIdx1;
							        kStarNo = needIdx2;
							        debugFieldIdentified = true;
							    }
							    else
							    {
                                    Trace.Assert(!debugTrippleFound);
                                    continue;
							    }
									
							}

							if (jkEntry.Star1.StarNo == needIdx2 &&
								jkEntry.Star2.StarNo == needIdx1)
							{
								m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
															   iStarNo, needIdx1, needIdx2, fittedFocalLength, true, toleranceInArcSec);
							    if (m_Solution != null)
							    {
							        jStarNo = needIdx2;
							        kStarNo = needIdx1;
							        debugFieldIdentified = true;
							    }
							    else
							    {
                                    Trace.Assert(!debugTrippleFound);
							        continue;
							    }
							}

						    if (m_Solution != null)
						    {
						        if (TangraConfig.Settings.Astrometry.PyramidNumberOfPivots == 3)
                                    // Exist the initial alignment with only 3 candidate pivots
						            return true;

                                for (int l = 0; l < m_StarMap.Features.Count; l++)
                                {
                                    var piramid = m_StarMap.Features[l];
                                    if (piramid.FeatureId == i || piramid.FeatureId == j || piramid.FeatureId == k)
                                        continue;

                                    var lCenter = piramid.GetCenter();

                                    // NOTE: Continue until a set of distances is found in the cache for the 4-th pivot
                                    double dli = m_PlateConfig.GetDistanceInArcSec(lCenter.XDouble, lCenter.YDouble, iCenter.XDouble, iCenter.YDouble, fittedFocalLength);
                                    double dlj = m_PlateConfig.GetDistanceInArcSec(lCenter.XDouble, lCenter.YDouble, jCenter.XDouble, jCenter.YDouble, fittedFocalLength);
                                    double dlk = m_PlateConfig.GetDistanceInArcSec(lCenter.XDouble, lCenter.YDouble, kCenter.XDouble, kCenter.YDouble, fittedFocalLength);

                                    List<DistanceEntry> ilCandidates = m_DistancesByMagnitude
						                .Where(e =>
							                (e.Star1.StarNo == iStarNo || e.Star2.StarNo == iStarNo) &&
                                            e.DistanceArcSec < dli + toleranceInArcSec && e.DistanceArcSec > dli - toleranceInArcSec)
						                .ToList();

                                    foreach (var cand_il in ilCandidates)
                                    {
                                        var lStar = cand_il.Star1.StarNo == iStarNo ? cand_il.Star2 : cand_il.Star1;

                                        List<DistanceEntry> jlCandidates = m_DistancesByMagnitude
                                        .Where(e =>
                                            ((e.Star1.StarNo == jStarNo && e.Star2.StarNo == lStar.StarNo) ||
                                             (e.Star1.StarNo == lStar.StarNo && e.Star2.StarNo == jStarNo)) &&
                                            e.DistanceArcSec < dlj + toleranceInArcSec && e.DistanceArcSec > dlj - toleranceInArcSec)
                                        .ToList();

                                        List<DistanceEntry> klCandidates = m_DistancesByMagnitude
                                            .Where(e =>
                                                ((e.Star1.StarNo == kStarNo && e.Star2.StarNo == lStar.StarNo) ||
                                                 (e.Star1.StarNo == lStar.StarNo && e.Star2.StarNo == kStarNo)) &&
                                                e.DistanceArcSec < dlk + toleranceInArcSec && e.DistanceArcSec > dlk - toleranceInArcSec)
                                            .ToList();

                                        if (jlCandidates.Count > 0 && klCandidates.Count > 0)
                                        {
                                            if (klCandidates.Count > 0)
                                                return true;        
                                        }
                                    }                                    
                                }
						    }
						}
					}
				}
			}
			finally
			{
				if (debug && !debugFieldIdentified)
				{
					DebugCheckUnidentifiedStars(
						dijMin, dijMax, dikMin, dikMax, djkMin, djkMax,
						debugiStarNo, debugjStarNo, debugkStarNo, i, j, k);
				}
					
			}

			return false;
		}
Пример #11
0
		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;
		}
Пример #12
0
        public override void MouseDown(Point location)
        {
            if (m_SelectedCalibrationStar != null)
            {
                frmIdentifyCalibrationStar frmIdentifyCalibrationStar = new frmIdentifyCalibrationStar(m_CatalogueStars, m_UserStarIdentification);
                DialogResult res = m_VideoController.ShowDialog(frmIdentifyCalibrationStar);
                if (res == DialogResult.Abort)
                {
                    m_UserStarIdentification.Clear();
                }
                else if (res == DialogResult.OK &&
                    frmIdentifyCalibrationStar.SelectedStar != null)
                {
                    m_UserStarIdentification.Add(m_SelectedCalibrationStar, frmIdentifyCalibrationStar.SelectedStar);
                    if (m_UserStarIdentification.Keys.Count > 0 &&
                        m_UserStarIdentification.Keys.Count < 3)
                    {
                        m_VideoController.ShowMessageBox(
                            string.Format("Identify another {0} star(s) to attempt calibration", 3 - m_UserStarIdentification.Keys.Count),
                            "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }

                    if (m_UserStarIdentification.Keys.Count > 2)
                    {
                        List<PSFFit> keysList = m_UserStarIdentification.Keys.ToList();
                        IStar star1 = m_UserStarIdentification[keysList[0]];
                        IStar star2 = m_UserStarIdentification[keysList[1]];
                        IStar star3 = m_UserStarIdentification[keysList[2]];
                        double ArcSec1 = 1 / 3600.0;
                        bool badRA = false;
                        bool badDE = false;
                        if (Math.Abs(star1.RADeg - star2.RADeg) < ArcSec1 || Math.Abs(star1.RADeg - star3.RADeg) < ArcSec1 || Math.Abs(star2.RADeg - star3.RADeg) < ArcSec1)
                        {
                            badRA = true;
                        }

                        if (Math.Abs(star1.DEDeg - star2.DEDeg) < ArcSec1 || Math.Abs(star1.DEDeg - star3.DEDeg) < ArcSec1 || Math.Abs(star2.DEDeg - star3.DEDeg) < ArcSec1)
                        {
                            badDE = true;
                        }

                        if (badRA)
                        {
                            m_VideoController.ShowMessageBox(
                                "Two of the stars have almost identical Right Ascension. Please try again with different stars.",
                                "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Error);

                            m_UserStarIdentification.Clear();
                        }
                        else if (badDE)
                        {
                            m_VideoController.ShowMessageBox(
                                "Two of the stars have almost identical Declination. Please try again with different stars.",
                                "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Error);

                            m_UserStarIdentification.Clear();
                        }
                        else
                        {
                            ThreeStarAstrometry threeStarSolution = ThreeStarAstrometry.SolveByThreeStars(m_Image, m_UserStarIdentification, m_Tolerance);
                            if (threeStarSolution != null)
                            {
                                m_SolvedPlate = threeStarSolution;

                                m_PlatesolveController.UpdateFocalLength((int)Math.Round(threeStarSolution.Image.EffectiveFocalLength));
                                m_RADegCenter = threeStarSolution.RA0Deg;
                                m_DEDegCenter = threeStarSolution.DE0Deg;
                                m_Image.EffectiveFocalLength = threeStarSolution.Image.EffectiveFocalLength;

                                m_UserStarIdentification.Clear();

                                m_AstrometryController.RunCalibrationWithCurrentPreliminaryFit();
                            }
                            else
                            {
                                m_VideoController.ShowMessageBox(
                                    "Cannot complete calibration. Please try again with higher initial fit tolerance and/or with different stars. Be sure that the stars are well separated.",
                                    "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Error);

                                m_UserStarIdentification.Remove(m_UserStarIdentification.Keys.ToList()[2]);
                            }
                        }
                    }
                }

                DrawCatalogStarsFit();
            }
            else
            {
                m_StarPoint = new Point(location.X, location.Y);
                m_Panning = true;
                m_VideoController.SetPictureBoxCursor(CustomCursors.PanEnabledCursor);
            }
        }
Пример #13
0
		private bool CheckTriangleByMagnitude(int i, int j, int k, double dij, double dik, double djk, double toleranceInArcSec)
		{
			List<DistanceEntry> ijCandidates = m_DistancesByMagnitude
                .Where(e => e.DistanceArcSec > dij - toleranceInArcSec && e.DistanceArcSec < dij + toleranceInArcSec).ToList();

            if (m_ManualPairs != null && m_ManualPairs.Count <= 3)
                LimitIJtoManualPairs(ijCandidates);

			foreach (DistanceEntry ijEntry in ijCandidates)
			{
				List<DistanceEntry> ikCandidates = m_DistancesByMagnitude
					.Where(e =>
						(e.Star1.StarNo == ijEntry.Star1.StarNo || e.Star2.StarNo == ijEntry.Star1.StarNo) &&
                         e.DistanceArcSec > dik - toleranceInArcSec && e.DistanceArcSec < dik + toleranceInArcSec)
					.ToList();

				foreach (DistanceEntry ikEntry in ikCandidates)
				{
                    ulong foundIdx0 = uint.MaxValue;
                    ulong needIdx1 = uint.MaxValue;
                    ulong needIdx2 = uint.MaxValue;
					if (ikEntry.Star1.StarNo == ijEntry.Star1.StarNo)
					{
						// ik_1 = ij_1 = (i)
						foundIdx0 = ikEntry.Star1.StarNo;
						needIdx1 = ikEntry.Star2.StarNo;
						needIdx2 = ijEntry.Star2.StarNo;
					}
					else if (ikEntry.Star1.StarNo == ijEntry.Star2.StarNo)
					{
						// ik_1 = ij_2 = (i)
						foundIdx0 = ikEntry.Star1.StarNo;
						needIdx1 = ikEntry.Star2.StarNo; // (k)
						needIdx2 = ijEntry.Star1.StarNo; // (j)
					}
					else if (ikEntry.Star2.StarNo == ijEntry.Star1.StarNo)
					{
						// ik_2 = ij_1 = (i)
						foundIdx0 = ikEntry.Star2.StarNo;
						needIdx1 = ikEntry.Star1.StarNo; // (k)
						needIdx2 = ijEntry.Star2.StarNo; // (j)
					}
					else if (ikEntry.Star2.StarNo == ijEntry.Star2.StarNo)
					{
						// ik_2 = ij_2 = (i)
						foundIdx0 = ikEntry.Star2.StarNo;
						needIdx1 = ikEntry.Star1.StarNo; // (k)
						needIdx2 = ijEntry.Star1.StarNo; // (j)
					}
					else
						continue;

					if (needIdx1 == needIdx2) continue;

					DistanceEntry jkEntry = m_DistancesByMagnitude.Where(e =>
						(e.Star1.StarNo == needIdx1 && e.Star2.StarNo == needIdx2) ||
						(e.Star1.StarNo == needIdx2 && e.Star2.StarNo == needIdx1)).FirstOrDefault();

					if (jkEntry != null)
					{
						if (jkEntry.DistanceArcSec + toleranceInArcSec < djk) continue;
						if (jkEntry.DistanceArcSec - toleranceInArcSec > djk) continue;

						if (jkEntry.Star1.StarNo == needIdx1 &&
							jkEntry.Star2.StarNo == needIdx2)
						{
							m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
														   foundIdx0, needIdx1, needIdx2, toleranceInArcSec);
							if (m_Solution != null)
								return true;
						}

						if (jkEntry.Star1.StarNo == needIdx2 &&
							jkEntry.Star2.StarNo == needIdx1)
						{
							m_Solution = IsSuccessfulMatch(m_StarMap, i, j, k, ijEntry, ikEntry, jkEntry,
														   foundIdx0, needIdx1, needIdx2, toleranceInArcSec);
							if (m_Solution != null)
								return true;
						}
					}
				}
			}

			return false;
		}
Пример #14
0
        public override void MouseMove(Point location)
        {
            bool dirty = false;

            int posX = location.X < 16
                                                   ? 16
                                                   : (location.X > TangraContext.Current.FrameWidth - 17
                                                                  ? TangraContext.Current.FrameWidth - 17
                                                                  : location.X);
            int posY = location.Y < 16
                                                   ? 16
                                                   : (location.Y > TangraContext.Current.FrameHeight - 17
                                                                  ? TangraContext.Current.FrameHeight - 17
                                                                  : location.Y);

            m_VideoController.DisplayCursorPositionDetails(location);

            m_SelectedCalibrationStar = null;

            if (!m_Panning)
            {
                if (m_Is3StarIdMode)
                {
                    StarMapFeature closestFeature = AstrometryContext.Current.StarMap.GetFeatureInRadius(posX, posY, 2);
                    if (closestFeature != null)
                    {
                        if (m_Is3StarIdMode)
                        {
                            m_VideoController.SetPictureBoxCursor(Cursors.Hand);
                            PSFFit psfFit;
                            AstrometryContext.Current.StarMap.GetPSFFit(posX, posY, 13, out psfFit);
                            m_SelectedCalibrationStar = psfFit;
                        }
                    }
                    else
                    {
                        m_VideoController.SetPictureBoxCursor(Cursors.Arrow);
                    }
                }
                else
                {
                    m_VideoController.SetPictureBoxCursor(CustomCursors.PanCursor);
                }
            }
            else if (m_Panning &&
                     m_StarPoint != Point.Empty)
            {
                ResetPreviousStar();

                if (m_SolvedPlate != null)
                {
                    double raDeg1, deDeg1, raDeg2, deDeg2;
                    m_SolvedPlate.GetRADEFromImageCoords(location.X, location.Y, out raDeg1, out deDeg1);
                    m_SolvedPlate.GetRADEFromImageCoords(m_StarPoint.X, m_StarPoint.Y, out raDeg2, out deDeg2);

                    double ra = m_RADegCenter + (raDeg2 - raDeg1);
                    double de = m_DEDegCenter + (deDeg2 - deDeg1);

                    if (m_SolvedPlate is LeastSquareFittedAstrometry)
                    {
                        m_SolvedPlate = new LeastSquareFittedAstrometry(m_Image, ra, de, null /*m_SolvePlateConts*/);
                    }
                    else if (m_SolvedPlate is TangentalTransRotAstrometry)
                    {
                        m_SolvedPlate = new TangentalTransRotAstrometry(m_SolvedPlate as TangentalTransRotAstrometry, m_Image, ra, de, m_Eta);
                    }
                    else
                    {
                        m_SolvedPlate = new DirectTransRotAstrometry(m_Image, ra, de, m_Eta, m_Aspect);
                    }
                }

                dirty = true;
            }

            if (dirty)
            {
                DrawCatalogStarsFit();
            }
        }
Пример #15
0
        public override void MouseDown(Point location)
        {
            if (m_SelectedCalibrationStar != null)
            {
                frmIdentifyCalibrationStar frmIdentifyCalibrationStar = new frmIdentifyCalibrationStar(m_CatalogueStars, m_UserStarIdentification);
                DialogResult res = m_VideoController.ShowDialog(frmIdentifyCalibrationStar);
                if (res == DialogResult.Abort)
                {
                    m_UserStarIdentification.Clear();
                }
                else if (res == DialogResult.OK &&
                         frmIdentifyCalibrationStar.SelectedStar != null)
                {
                    m_UserStarIdentification.Add(m_SelectedCalibrationStar, frmIdentifyCalibrationStar.SelectedStar);
                    if (m_UserStarIdentification.Keys.Count > 0 &&
                        m_UserStarIdentification.Keys.Count < 3)
                    {
                        m_VideoController.ShowMessageBox(
                            string.Format("Identify another {0} star(s) to attempt calibration", 3 - m_UserStarIdentification.Keys.Count),
                            "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }

                    if (m_UserStarIdentification.Keys.Count > 2)
                    {
                        List <PSFFit> keysList = m_UserStarIdentification.Keys.ToList();
                        IStar         star1    = m_UserStarIdentification[keysList[0]];
                        IStar         star2    = m_UserStarIdentification[keysList[1]];
                        IStar         star3    = m_UserStarIdentification[keysList[2]];
                        double        ArcSec1  = 1 / 3600.0;
                        bool          badRA    = false;
                        bool          badDE    = false;
                        if (Math.Abs(star1.RADeg - star2.RADeg) < ArcSec1 || Math.Abs(star1.RADeg - star3.RADeg) < ArcSec1 || Math.Abs(star2.RADeg - star3.RADeg) < ArcSec1)
                        {
                            badRA = true;
                        }

                        if (Math.Abs(star1.DEDeg - star2.DEDeg) < ArcSec1 || Math.Abs(star1.DEDeg - star3.DEDeg) < ArcSec1 || Math.Abs(star2.DEDeg - star3.DEDeg) < ArcSec1)
                        {
                            badDE = true;
                        }

                        if (badRA)
                        {
                            m_VideoController.ShowMessageBox(
                                "Two of the stars have almost identical Right Ascension. Please try again with different stars.",
                                "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Error);

                            m_UserStarIdentification.Clear();
                        }
                        else if (badDE)
                        {
                            m_VideoController.ShowMessageBox(
                                "Two of the stars have almost identical Declination. Please try again with different stars.",
                                "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Error);

                            m_UserStarIdentification.Clear();
                        }
                        else
                        {
                            ThreeStarAstrometry threeStarSolution = ThreeStarAstrometry.SolveByThreeStars(m_Image, m_UserStarIdentification, m_Tolerance);
                            if (threeStarSolution != null)
                            {
                                m_SolvedPlate = threeStarSolution;

                                m_PlatesolveController.UpdateFocalLength((int)Math.Round(threeStarSolution.Image.EffectiveFocalLength));
                                m_RADegCenter = threeStarSolution.RA0Deg;
                                m_DEDegCenter = threeStarSolution.DE0Deg;
                                m_Image.EffectiveFocalLength = threeStarSolution.Image.EffectiveFocalLength;

                                m_UserStarIdentification.Clear();

                                m_AstrometryController.RunCalibrationWithCurrentPreliminaryFit();
                            }
                            else
                            {
                                m_VideoController.ShowMessageBox(
                                    "Cannot complete calibration. Please try again with higher initial fit tolerance and/or with different stars. Be sure that the stars are well separated.",
                                    "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Error);

                                m_UserStarIdentification.Remove(m_UserStarIdentification.Keys.ToList()[2]);
                            }
                        }
                    }
                }

                DrawCatalogStarsFit();
            }
            else
            {
                m_StarPoint = new Point(location.X, location.Y);
                m_Panning   = true;
                m_VideoController.SetPictureBoxCursor(CustomCursors.PanEnabledCursor);
            }
        }
Пример #16
0
        public void DrawCatalogStarsFit(Graphics g)
        {
            if (m_CatalogueStars == null)
            {
                m_LimitMag = -100;
                return;
            }

            bool hasManualStars =
                m_Is3StarIdMode &&
                m_UserStarIdentification != null &&
                m_UserStarIdentification.Count > 0;

            LeastSquareFittedAstrometry astrometry = null;

            astrometry = FittedAstrometryFromUserSelectedFitGrade();
            IAstrometricFit fit = null;

            if (astrometry != null)
            {
                fit = astrometry;
            }
            else
            {
                fit = m_SolvedPlate;
            }

            if (fit != null)
            {
                double limitMag = (astrometry != null && astrometry.FitInfo.AllStarPairs.Count > 0)
                                        ? astrometry.FitInfo.AllStarPairs.Max(p => p.Mag)
                                        : m_LimitMag;

                foreach (IStar star in m_CatalogueStars)
                {
                    if (star.Mag > limitMag)
                    {
                        continue;
                    }

                    double x, y;
                    fit.GetImageCoordsFromRADE(star.RADeg, star.DEDeg, out x, out y);

                    Pen   starPen     = catalogStarPen;
                    Brush labelBruish = catalogBrushUnrecognized;

                    if (astrometry != null)
                    {
                        PlateConstStarPair pair = astrometry.FitInfo.AllStarPairs.Find((p) => p.StarNo == star.StarNo);

                        if (pair != null && pair.FitInfo.UsedInSolution)
                        {
                            starPen     = referenceStarPen;
                            labelBruish = catalogBrushReference;
                        }
                        else if (pair != null && pair.FitInfo.ExcludedForHighResidual)
                        {
                            starPen     = rejectedStarPen;
                            labelBruish = catalogBrushRejected;
                        }
                        else
                        {
                            starPen     = unrecognizedStarPen;
                            labelBruish = catalogBrushUnrecognized;
                        }

                        if (pair != null)
                        {
                            g.DrawLine(starPen, (float)x, (float)y, (float)pair.x, (float)pair.y);
                        }
                    }

                    if (!m_Is3StarIdMode || astrometry != null)
                    {
                        float rad = (float)GetStarDiameter(m_LimitMag, 5, star.Mag) / 2;
                        g.DrawEllipse(starPen, (float)x - rad, (float)y - rad, 2 * rad, 2 * rad);
                    }

                    if (m_ShowLabels || m_ShowMagnitudes)
                    {
                        string label;
                        if (m_ShowLabels && m_ShowMagnitudes)
                        {
                            label = string.Format("{0} ({1}m)", star.GetStarDesignation(0), star.Mag);
                        }
                        else if (m_ShowLabels)
                        {
                            label = string.Format("{0}", star.GetStarDesignation(0));
                        }
                        else
                        {
                            label = string.Format("{0}m", star.Mag);
                        }

                        g.DrawString(label, m_StarInfoFont, labelBruish, (float)x + 10, (float)y + 10);
                    }
                }

                if (m_Is3StarIdMode && astrometry == null)
                {
                    // Draw all features from the starMap (unless the configuration has been solved)
                    if (AstrometryContext.Current.StarMap != null)
                    {
                        foreach (StarMapFeature feature in AstrometryContext.Current.StarMap.Features)
                        {
                            ImagePixel center = feature.GetCenter();

                            PSFFit psfFit;
                            AstrometryContext.Current.StarMap.GetPSFFit(center.X, center.Y, PSFFittingMethod.NonLinearAsymetricFit, out psfFit);

#if ASTROMETRY_DEBUG
                            PSFFit psfFit2;
                            AstrometryContext.Current.StarMap.GetPSFFit(center.X, center.Y, PSFFittingMethod.NonLinearFit, out psfFit2);
                            double elong     = psfFit.RX0 / psfFit.RY0;
                            double elongPerc = Math.Abs(1 - elong) * 100;
                            Trace.WriteLine(string.Format("({0:0}, {1:0}) Rx = {2:0.00} Ry = {3:0.00}, e = {4:0.000} ({5:0}%), FWHMxy = {6:0.0} | FWHMxx = {7:0.0}",
                                                          center.X, center.Y, psfFit.RX0, psfFit.RY0, elong, elongPerc,
                                                          psfFit.FWHM, psfFit2.FWHM));
#endif
                            Pen pen = catalogStarPen;

#if ASTROMETRY_DEBUG
                            if (psfFit.FWHM < TangraConfig.Settings.Astrometry.MinReferenceStarFWHM ||
                                psfFit.FWHM > TangraConfig.Settings.Astrometry.MaxReferenceStarFWHM ||
                                psfFit.ElongationPercentage > TangraConfig.Settings.Astrometry.MaximumPSFElongation)
                            {
                                pen = rejectedStarPen;
                            }
#endif

                            g.DrawLine(pen, (float)center.XDouble - 9, (float)center.YDouble, (float)center.XDouble - 5, (float)center.YDouble);
                            g.DrawLine(pen, (float)center.XDouble + 5, (float)center.YDouble, (float)center.XDouble + 9, (float)center.YDouble);
                            g.DrawLine(pen, (float)center.XDouble, (float)center.YDouble - 9, (float)center.XDouble, (float)center.YDouble - 5);
                            g.DrawLine(pen, (float)center.XDouble, (float)center.YDouble + 5, (float)center.XDouble, (float)center.YDouble + 9);
                        }
                    }
                }
                else
                {
                    if (m_Grid)
                    {
                        DrawEquatorialGrid(g);
                    }
                }

                #region Draw the manual single star identification
                if (hasManualStars)
                {
                    foreach (PSFFit psf in m_UserStarIdentification.Keys)
                    {
                        IStar star = m_UserStarIdentification[psf];

                        float rad = (float)GetStarDiameter(m_LimitMag, 5, star.Mag) / 2;

                        g.DrawEllipse(Pens.DarkRed, (float)psf.XCenter - rad, (float)psf.YCenter - rad, 2 * rad, 2 * rad);
                        g.DrawEllipse(Pens.DarkRed, (float)psf.XCenter - rad - 2, (float)psf.YCenter - rad - 2, 2 * rad + 4, 2 * rad + 4);
                    }
                }
                #endregion ;
            }

            UpdateToolControlDisplay();
        }
Пример #17
0
        public override void MouseMove(Point location)
        {
            bool dirty = false;

            int posX = location.X < 16
                           ? 16
                           : (location.X > TangraContext.Current.FrameWidth - 17
                                  ? TangraContext.Current.FrameWidth - 17
                                  : location.X);
            int posY = location.Y < 16
                           ? 16
                           : (location.Y > TangraContext.Current.FrameHeight - 17
                                  ? TangraContext.Current.FrameHeight - 17
                                  : location.Y);

            m_VideoController.DisplayCursorPositionDetails(location);

            m_SelectedCalibrationStar = null;

            if (!m_Panning)
            {
                if (m_Is3StarIdMode)
                {
                    StarMapFeature closestFeature = AstrometryContext.Current.StarMap.GetFeatureInRadius(posX, posY, 2);
                    if (closestFeature != null)
                    {
                        if (m_Is3StarIdMode)
                        {
                            m_VideoController.SetPictureBoxCursor(Cursors.Hand);
                            PSFFit psfFit;
                            AstrometryContext.Current.StarMap.GetPSFFit(posX, posY, 13, out psfFit);
                            m_SelectedCalibrationStar = psfFit;
                        }
                    }
                    else
                        m_VideoController.SetPictureBoxCursor(Cursors.Arrow);
                }
                else
                    m_VideoController.SetPictureBoxCursor(CustomCursors.PanCursor);
            }
            else if (m_Panning &&
                m_StarPoint != Point.Empty)
            {
                ResetPreviousStar();

                if (m_SolvedPlate != null)
                {
                    double raDeg1, deDeg1, raDeg2, deDeg2;
                    m_SolvedPlate.GetRADEFromImageCoords(location.X, location.Y, out raDeg1, out deDeg1);
                    m_SolvedPlate.GetRADEFromImageCoords(m_StarPoint.X, m_StarPoint.Y, out raDeg2, out deDeg2);

                    double ra = m_RADegCenter + (raDeg2 - raDeg1);
                    double de = m_DEDegCenter + (deDeg2 - deDeg1);

                    if (m_SolvedPlate is LeastSquareFittedAstrometry)
                        m_SolvedPlate = new LeastSquareFittedAstrometry(m_Image, ra, de, null /*m_SolvePlateConts*/);
                    else if (m_SolvedPlate is TangentalTransRotAstrometry)
                        m_SolvedPlate = new TangentalTransRotAstrometry(m_SolvedPlate as TangentalTransRotAstrometry, m_Image, ra, de, m_Eta);
                    else
                        m_SolvedPlate = new DirectTransRotAstrometry(m_Image, ra, de, m_Eta, m_Aspect);
                }

                dirty = true;
            }

            if (dirty)
            {
                DrawCatalogStarsFit();
            }
        }
Пример #18
0
        protected virtual void ReinitializePlateConstants()
        {
            m_Image = m_AstrometryController.GetCurrentAstroPlate();
            m_Image.EffectiveFocalLength = m_FLength;

            if (m_SolvedPlate is LeastSquareFittedAstrometry)
                m_SolvedPlate = new LeastSquareFittedAstrometry(m_Image, m_RADegCenter, m_DEDegCenter, null /*m_SolvePlateConts*/);
            else if (m_SolvedPlate is TangentalTransRotAstrometry)
                m_SolvedPlate = new TangentalTransRotAstrometry(m_SolvedPlate as TangentalTransRotAstrometry, m_Image, m_RADegCenter, m_DEDegCenter, m_Eta);
            else
            {
                m_SolvedPlate = new DirectTransRotAstrometry(m_Image, m_RADegCenter, m_DEDegCenter, m_Eta, m_Aspect);
            }
        }