예제 #1
0
        protected virtual void DrawEquatorialGrid(Graphics g)
        {
            // We want at least 5 but no more than 10 RA and DE lines to fit the diagonal
            double diagonalInArcSec = m_SolvedPlate.GetDistanceInArcSec(0, 0, m_Image.ImageWidth, m_Image.ImageHeight);

            double ra0, de0;

            m_SolvedPlate.GetRADEFromImageCoords(m_Image.CenterXImage, m_Image.CenterYImage, out ra0, out de0);
            Debug.Assert(Math.Abs(m_SolvedPlate.RA0Deg - ra0) < 1 / 3600.0);
            Debug.Assert(Math.Abs(m_SolvedPlate.DE0Deg - de0) < 1 / 3600.0);

            // We are not drawing lines when too close to the poles
            if (de0 + 2 * diagonalInArcSec / 3600.0 > 90)
            {
                return;
            }
            if (de0 - 2 * diagonalInArcSec / 3600.0 < -90)
            {
                return;
            }

            int MAX_GRID_LINES = 10;
            int MIN_GRID_LINES = 5;

            int[] intervals = new int[] { 1, 5, 10, 30, 60, 60 * 5, 60 * 10, 60 * 30, 60 * 60 };

            double deFrom, deTo;

            #region Calculating  the interval in declination
            double maxArcSec = diagonalInArcSec / MIN_GRID_LINES;
            double minArcSec = diagonalInArcSec / MAX_GRID_LINES;

            int deInterval = -1;
            for (int i = 0; i < intervals.Length; i++)
            {
                if (intervals[i] >= minArcSec &&
                    intervals[i] <= maxArcSec)
                {
                    deInterval = intervals[i];
                    break;
                }
                else if (intervals[i] < minArcSec)
                {
                    deInterval = intervals[i];
                }
            }
            #endregion

            double raFrom, raTo;
            #region Calculating  the interval in right accension

            double[] raArr = new double[4];
            double[] deArr = new double[4];
            m_SolvedPlate.GetRADEFromImageCoords(0, 0, out raArr[0], out deArr[0]);
            m_SolvedPlate.GetRADEFromImageCoords(0, m_Image.ImageHeight, out raArr[1], out deArr[1]);
            m_SolvedPlate.GetRADEFromImageCoords(m_Image.ImageWidth, 0, out raArr[2], out deArr[2]);
            m_SolvedPlate.GetRADEFromImageCoords(m_Image.ImageWidth, m_Image.ImageHeight, out raArr[3], out deArr[3]);

            // From the RA of the 4 corners we need to find the fromRA and toRA
            double raMin = double.MaxValue, raMax = double.MinValue;
            int    minIdx = 0, maxIdx = 0;
            for (int i = 0; i < 4; i++)
            {
                if (raArr[i] > raMax)
                {
                    raMax  = raArr[i];
                    maxIdx = i;
                }

                if (raArr[i] < raMin)
                {
                    raMin  = raArr[i];
                    minIdx = i;
                }
            }
            double shortestDistance = AngleUtility.Elongation(raArr[minIdx], 0, raArr[maxIdx], 0);
            if (shortestDistance < (raArr[maxIdx] - raArr[minIdx]) - 10 / 3600.0 /* tolerance 10" */)
            {
                // We are going accross the 0 point
                Debug.Assert(false, "This is not implemented yet");
                return;
                //raFrom = 0;
                //raTo = 0;
                //for (int i = 0; i < 4; i++)
                //{
                //    if (i == minIdx) continue;
                //    if (i == maxIdx) continue;

                //    if (raArr[0] > raMax)
                //    {
                //        raMax = raArr[0];
                //        maxIdx = 1;
                //    }

                //    if (raArr[0] < raMin)
                //    {
                //        raMin = raArr[0];
                //        minIdx = i;
                //    }
                //}
                //raTo = raArr[maxIdx];
            }
            else
            {
                raFrom = raArr[minIdx];
                raTo   = raArr[maxIdx];
            }

            minArcSec = 3600.0 * (raTo - raFrom) / (15 * MAX_GRID_LINES);
            maxArcSec = 3600.0 * (raTo - raFrom) / (15 * MIN_GRID_LINES);
            int raInterval = -1;
            for (int i = 0; i < intervals.Length; i++)
            {
                if (intervals[i] >= minArcSec &&
                    intervals[i] <= maxArcSec)
                {
                    raInterval = intervals[i];
                    break;
                }
                else if (intervals[i] < minArcSec)
                {
                    raInterval = intervals[i];
                }
            }
            #endregion

#if DEBUG
            if (raInterval == -1 || deInterval == -1)
            {
                Debug.Assert(false, "Problem with raInterval or deInterval");
                return;
            }
#endif

            raFrom = (Math.Floor((raFrom * 3600.0) / (15 * raInterval)) - 1) * 15 * raInterval / 3600.0;
            raTo   = (Math.Ceiling((raTo * 3600.0) / (15 * raInterval)) + 1) * 15 * raInterval / 3600.0;

            deFrom = (Math.Floor((de0 * 3600.0 - (diagonalInArcSec / 2)) / (deInterval)) - 1) * deInterval / 3600.0;
            deTo   = (Math.Ceiling((de0 * 3600.0 + (diagonalInArcSec / 2)) / (deInterval)) + 1) * deInterval / 3600.0;

            //Debug.WriteLine(string.Format("Draw Grid -> C: ({0}, {1}) F:({2}, {3}) T:({4}, {5})",
            //    AstroConvert.ToStringValue(ra0, "HH MM SS.T"), AstroConvert.ToStringValue(de0, "+DD MM SS.T"),
            //    AstroConvert.ToStringValue(raFrom, "HH MM SS.T"), AstroConvert.ToStringValue(raTo, "HH MM SS.T"),
            //    AstroConvert.ToStringValue(deFrom, "+DD MM SS.T"), AstroConvert.ToStringValue(deTo, "+DD MM SS.T")));

            double x1, y1, x2, y2;
            double stepRA = (15 * raInterval) / 3600.0;
            double stepDE = deInterval / 3600.0;

            for (double ra = raFrom; ra <= raTo; ra += stepRA)
            {
                x1 = double.NaN; y1 = double.NaN;
                for (double de = deFrom; de < deTo; de += stepDE / 10.0)
                {
                    m_SolvedPlate.GetImageCoordsFromRADE(ra, de, out x2, out y2);
                    if (x2 >= 0 && x2 <= m_Image.ImageWidth && y2 >= 0 && y2 <= m_Image.ImageHeight)
                    {
                        if (!double.IsNaN(x1))
                        {
                            g.DrawLine(Pens.Purple, (float)x1, (float)y1, (float)x2, (float)y2);
                        }

                        x1 = x2; y1 = y2;
                    }
                }
            }

            for (double de = deFrom; de <= deTo; de += stepDE)
            {
                x1 = double.NaN; y1 = double.NaN;
                for (double ra = raFrom; ra < raTo; ra += stepRA / 10.0)
                {
                    m_SolvedPlate.GetImageCoordsFromRADE(ra, de, out x2, out y2);
                    if (x2 >= 0 && x2 <= m_Image.ImageWidth && y2 >= 0 && y2 <= m_Image.ImageHeight)
                    {
                        if (!double.IsNaN(x1))
                        {
                            g.DrawLine(Pens.Purple, (float)x1, (float)y1, (float)x2, (float)y2);
                        }

                        x1 = x2; y1 = y2;
                    }
                }
            }
        }
예제 #2
0
        public LeastSquareFittedAstrometry SolvePlateConstantsPhase4(double pyramidLimitMag)
        {
            double ra0deg, de0Deg;

            m_SolvedPlate.GetRADEFromImageCoords(m_SolvedPlate.Image.CenterXImage, m_SolvedPlate.Image.CenterYImage, out ra0deg, out de0Deg);

            FocalLengthFit distFit = m_ConstantsSolver.ComputeFocalLengthFit();

            m_Context.PlateConfig.EffectiveFocalLength = m_Context.FieldSolveContext.FocalLength;
            distFit.GetFocalParameters(m_Context.PlateConfig.EffectiveFocalLength, out m_Context.PlateConfig.EffectivePixelWidth, out m_Context.PlateConfig.EffectivePixelHeight);

            DistanceBasedAstrometrySolver distMatch = new DistanceBasedAstrometrySolver(
                m_AstrometryController,
                m_Context.PlateConfig,
                m_AstrometrySettings,
                m_Context.FieldSolveContext.CatalogueStars,
                m_Context.FieldSolveContext.RADeg,
                m_Context.FieldSolveContext.DEDeg,
                m_Context.FieldSolveContext.DetermineAutoLimitMagnitude);

            distMatch.SetMinMaxMagOfStarsForAstrometry(CorePyramidConfig.Default.DefaultMinAstrometryMagnitude, 18);

            distMatch.SetMinMaxMagOfStarsForPyramidAlignment(CorePyramidConfig.Default.DefaultMinPyramidMagnitude, pyramidLimitMag);
            Trace.WriteLine(string.Format("Stars for alignment in range: {0:0.0} - {1:0.0} mag", CorePyramidConfig.Default.DefaultMinPyramidMagnitude, pyramidLimitMag));

            Dictionary <PSFFit, IStar> manualStars = null;
            var threeStarFit = m_Context.PreliminaryFit as ThreeStarAstrometry;

            if (threeStarFit != null)
            {
                manualStars = new Dictionary <PSFFit, IStar>();
                foreach (var kvp in threeStarFit.UserStars)
                {
                    PSFFit psfFit;
                    m_Context.StarMap.GetPSFFit(kvp.Key.X, kvp.Key.Y, PSFFittingMethod.NonLinearFit, out psfFit);
                    if (psfFit != null && psfFit.IsSolved)
                    {
                        manualStars.Add(psfFit, kvp.Value);
                    }
                }
            }

            distMatch.InitNewMatch(m_Context.StarMap, PyramidMatchType.PlateSolve, manualStars);

#if ASTROMETRY_DEBUG
            Dictionary <int, ulong> debugInfo = new Dictionary <int, ulong>();

            var starList = m_Context.SecondAstrometricFit.FitInfo.AllStarPairs
                           .Where(p => !p.FitInfo.ExcludedForHighResidual);

            foreach (var x in starList)
            {
                if (!debugInfo.ContainsKey(x.FeatureId))
                {
                    debugInfo.Add(x.FeatureId, x.StarNo);
                }
            }

            foreach (var f in m_Context.StarMap.Features)
            {
                Trace.WriteLine(string.Format("{0} - {1}", f.FeatureId, debugInfo.ContainsKey(f.FeatureId) ? "INCLUDED" : "MISSING"));
            }

            distMatch.SetDebugData(new DistanceBasedAstrometrySolver.PyramidDebugContext()
            {
                ResolvedStars       = debugInfo,
                ResolvedFocalLength = m_Context.SecondAstrometricFit.FitInfo.FittedFocalLength
            });
#endif

            LeastSquareFittedAstrometry fit         = null;
            LeastSquareFittedAstrometry improvedFit = null;
            PlateConstantsSolver        solver;
            distMatch.PerformMatch(out fit, out improvedFit, out solver);

            m_Context.DistanceBasedFit         = fit;
            m_Context.ImprovedDistanceBasedFit = improvedFit;

            if (fit != null)
            {
                m_Context.PlateConstants = new TangraConfig.PersistedPlateConstants
                {
                    EffectiveFocalLength = m_Context.PlateConfig.EffectiveFocalLength,
                    EffectivePixelWidth  = m_Context.PlateConfig.EffectivePixelWidth,
                    EffectivePixelHeight = m_Context.PlateConfig.EffectivePixelHeight
                };

                m_Context.ConstantsSolver = solver;

                if (improvedFit != null)
                {
                    foreach (var pair in improvedFit.FitInfo.AllStarPairs)
                    {
                        if (pair.FitInfo.ExcludedForHighResidual)
                        {
                            continue;
                        }

                        Trace.WriteLine(string.Format("{6}; {0}; {1}; {2}; {3}; ({4}\", {5}\")",
                                                      pair.RADeg, pair.DEDeg, pair.x.ToString("0.00"), pair.y.ToString("0.00"),
                                                      pair.FitInfo.ResidualRAArcSec.ToString("0.00"), pair.FitInfo.ResidualDEArcSec.ToString("0.00"),
                                                      pair.StarNo));

                        double x, y;
                        improvedFit.GetImageCoordsFromRADE(pair.RADeg, pair.DEDeg, out x, out y);
                        double dist = improvedFit.GetDistanceInArcSec(x, y, pair.x, pair.y);
                    }
                }
            }
            else
            {
                m_Context.PlateConstants = null;
            }

            return(fit);
        }