예제 #1
0
        public override void MouseClick(ObjectClickEventArgs e)
        {
            if (m_State == FittingsState.Configuring)
            {
                m_OSDExcluderTool.MouseClick(e);
            }
            if (m_State == FittingsState.Solved)
            {
                IStarMap starMap = AstrometryContext.Current.StarMap;
                if (starMap != null)
                {
                    int            x, y;
                    StarMapFeature feature = starMap.GetFeatureInRadius(e.Pixel.X, e.Pixel.Y, 5);
                    if (feature != null)
                    {
                        x = feature.GetCenter().X;
                        y = feature.GetCenter().Y;
                    }
                    else
                    {
                        x = e.Pixel.X;
                        y = e.Pixel.Y;
                    }

                    int searchArea = Control.ModifierKeys == Keys.Shift ? 5 : 10;

                    PSFFit     psfFit;
                    ImagePixel pixelCent = starMap.GetPSFFit(x, y, searchArea, out psfFit);
                    if (pixelCent != null && pixelCent != ImagePixel.Unspecified)
                    {
                        PlateConstStarPair          selectedPair = null;
                        LeastSquareFittedAstrometry astrometry   = FittedAstrometryFromUserSelectedFitGrade();
                        if (astrometry != null)
                        {
                            foreach (PlateConstStarPair pair in astrometry.FitInfo.AllStarPairs)
                            {
                                if (Math.Abs(pair.x - pixelCent.X) < 2 &&
                                    Math.Abs(pair.y - pixelCent.Y) < 2)
                                {
                                    selectedPair = pair;
                                    break;
                                }
                            }
                        }

                        DrawHighResFeature(pixelCent, selectedPair, astrometry);
                    }
                    else
                    {
                        ClearZoomImage();
                    }
                }
            }
        }
예제 #2
0
        protected virtual void IdentifyStar(StarMapFeature feature, IStar star)
        {
            if (m_SolvedPlate != null)
            {
                ImagePixel featureCenter = feature.GetCenter();

                if (m_PreviousStar == null ||
                    m_PreviousStar.StarNo == star.StarNo)
                {
                    // Translation only
                    double x, y;
                    m_SolvedPlate.GetImageCoordsFromRADE(star.RADeg, star.DEDeg, out x, out y);

                    double newCenterX = m_Image.FullFrame.Width / 2 - featureCenter.X + x;
                    double newCenterY = m_Image.FullFrame.Height / 2 - featureCenter.Y + y;

                    m_SolvedPlate.GetRADEFromImageCoords(newCenterX, newCenterY, out m_RADegCenter, out m_DEDegCenter);

                    m_PreviousFeature = feature;
                    m_PreviousStar    = star;
                }
                else
                {
                    // TODO: Rotate and streach until the feature fits
                }


                ReinitializePlateConstants();
                DrawCatalogStarsFit();

                // TODO: For now we only support 1 star centering
                m_PreviousStar = null;
                m_PreviousStar = null;
            }
        }
예제 #3
0
        public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit)
        {
            IsTrackedSuccessfully = false;
            int searchRadius = (int)Math.Ceiling(Math.Max(m_LastMovementPixels, CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius));

            PSFFit psfFit = null;

            int startingX = (int)TrackedObject.LastKnownX;
            int startingY = (int)TrackedObject.LastKnownY;

            if (m_RepeatedIntergationPositions * 4 < m_PastFrameNos.Count)
            {
                var expectedPos = GetExpectedPosition(frameNo);
                if (expectedPos != null)
                {
                    startingX = expectedPos.X;
                    startingY = expectedPos.Y;
                }
            }

            var nearbyFeatures = starMap.GetFeaturesInRadius(startingX, startingY, searchRadius).ToArray();

            var nonStarNearbyFeature = new List <StarMapFeature>();

            foreach (var feature in nearbyFeatures)
            {
                var center = feature.GetCenter();
                var referenceStarFeatures = astrometricFit.FitInfo.AllStarPairs.Where(x => x.FitInfo.UsedInSolution).ToList();
                var refStar = referenceStarFeatures.FirstOrDefault(s => Math.Sqrt((s.x - center.X) * (s.x - center.X) + (s.y - center.Y) * (s.y - center.Y)) < 2);

                double raf, def;
                astrometricFit.GetRADEFromImageCoords(center.XDouble, center.YDouble, out raf, out def);
                var pastKnownStar = m_LastFrameStars.FirstOrDefault(s => AngleUtility.Elongation(s.RADeg, s.DEDeg, raf, def) * 3600.0 < 2);

                if (refStar == null && pastKnownStar == null)
                {
                    nonStarNearbyFeature.Add(feature);
                }
            }

            if (nonStarNearbyFeature.Count > 0)
            {
                StarMapFeature closestFeature   = nonStarNearbyFeature[0];
                var            lastKnownCenter  = new ImagePixel(TrackedObject.LastKnownX, TrackedObject.LastKnownY);
                var            smallestDistance = lastKnownCenter.DistanceTo(closestFeature.GetCenter());

                for (int i = 1; i < nonStarNearbyFeature.Count; i++)
                {
                    var distance = lastKnownCenter.DistanceTo(nonStarNearbyFeature[i].GetCenter());
                    if (distance < smallestDistance)
                    {
                        smallestDistance = distance;
                        closestFeature   = nonStarNearbyFeature[i];
                    }
                }

                if (closestFeature != null)
                {
                    var center = closestFeature.GetCenter();
                    AstrometryContext.Current.StarMap.GetPSFFit(center.X, center.Y, PSFFittingMethod.NonLinearFit, out psfFit);
                }
            }

            if (psfFit == null)
            {
                // The expected location cannot be matched with any brighter feature so it is likely a faint object
                // with no brighter objects around. Lets find the brightest (faint) object in the are and use it
                ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid(startingX, startingY, searchRadius);

                if (centroid != null)
                {
                    AstrometryContext.Current.StarMap.GetPSFFit(centroid.X, centroid.Y, PSFFittingMethod.NonLinearFit, out psfFit);
                }
            }

            if (psfFit != null)
            {
                double ra, de;
                astrometricFit.GetRADEFromImageCoords(psfFit.XCenter, psfFit.YCenter, out ra, out de);

                double maxPosDiffArcSec =
                    astrometricFit.GetDistanceInArcSec(astrometricFit.Image.CenterXImage, astrometricFit.Image.CenterYImage,
                                                       astrometricFit.Image.CenterXImage + Math.Max(m_LastMovementPixels, CoreAstrometrySettings.Default.MaxAllowedDefaultMotionInPixels), astrometricFit.Image.CenterYImage);

                if (!double.IsNaN(TrackedObject.RAHours))
                {
                    double posDif = 3600 * AngleUtility.Elongation(15 * TrackedObject.RAHours, TrackedObject.DEDeg, ra, de);
                    if (posDif > maxPosDiffArcSec)
                    {
                        // NOTE: Not a valid measurement
                        Trace.WriteLine(string.Format("The target position is too far from the last measured position", posDif));
                        return;
                    }
                }

                TrackedObject.RAHours = ra / 15.0;
                TrackedObject.DEDeg   = de;

                if (TrackedObject.PSFFit != null)
                {
                    m_LastMovementPixels = 1.2 * ImagePixel.ComputeDistance(TrackedObject.LastKnownX, psfFit.XCenter, TrackedObject.LastKnownY, psfFit.YCenter);
                }
                TrackedObject.LastKnownX = psfFit.XCenter;
                TrackedObject.LastKnownY = psfFit.YCenter;
                TrackedObject.PSFFit     = psfFit;

                var lastKnownCenter = new ImagePixel(TrackedObject.LastKnownX, TrackedObject.LastKnownY);
                var thisFrameStars  = astrometricFit.FitInfo.AllStarPairs.Where(x => lastKnownCenter.DistanceTo(x.x, x.y) > 2 * psfFit.FWHM).ToList();
                if (thisFrameStars.Count > 0)
                {
                    m_LastFrameStars = thisFrameStars.Select(x => new Star(x.StarNo, x.RADeg, x.DEDeg, x.Mag) as IStar).ToList();
                }

                IsTrackedSuccessfully = true;
            }

            if (psfFit != null && psfFit.XCenter > 0 && psfFit.YCenter > 0)
            {
                m_PastFramePosX.Add(psfFit.XCenter);
                m_PastFramePosY.Add(psfFit.YCenter);
                m_PastFrameNos.Add(frameNo);
            }
        }
예제 #4
0
        public override void PostDraw(Graphics g)
        {
            if (m_CatalogueStars == null)
            {
                if (AstrometryContext.Current.StarMap != null)
                {
                    foreach (StarMapFeature feature in AstrometryContext.Current.StarMap.Features)
                    {
                        ImagePixel center = feature.GetCenter();

                        g.DrawEllipse(Pens.Red, center.X - 2, center.Y - 2, 5, 5);
                    }
                }
            }
            else if (m_CatalogueStars != null && m_State == FittingsState.Configuring)
            {
                if (m_SolvedPlate != null && m_PlateCalibrator.ConstantsSolver != null)
                {
                    foreach (IStar star in m_CatalogueStars)
                    {
                        if (star.Mag > m_LimitMag)
                        {
                            continue;
                        }

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

                        PlateConstStarPair pair = m_PlateCalibrator.ConstantsSolver.Pairs.FirstOrDefault((p) => p.StarNo == star.StarNo);

                        Pen starPen = catalogStarPen;
                        if (pair == null)
                        {
                            starPen = rejectedStarPen;
                        }
                        else if (!pair.FitInfo.ExcludedForHighResidual)
                        {
                            starPen = referenceStarPen;

                            if (AstrometryContext.Current.StarMap != null)
                            {
                                StarMapFeature feature =
                                    AstrometryContext.Current.StarMap.Features.FirstOrDefault((f) => f.FeatureId == pair.FeatureId);
                                if (feature != null)
                                {
                                    g.DrawLine(Pens.Beige, (float)x, (float)y, (float)feature.GetCenter().XDouble,
                                               (float)feature.GetCenter().YDouble);
                                }
                            }
                        }

                        g.DrawLine(starPen, (float)x - 3, (float)y, (float)x + 3, (float)y);
                        g.DrawLine(starPen, (float)x, (float)y - 3, (float)x, (float)y + 3);
                    }
                }
            }
            else
            {
                DrawCatalogStarsFit(g);
            }

            g.Save();
        }
예제 #5
0
        /// <summary>
        /// Used to calibrate a plate. Does the more precise astrometric fit
        /// Precondition: A coarser (m_PreliminaryFit) is required where the user has visually roughly fitted the stars to the plate
        /// </summary>
        /// <param name="limitMag">The faintest magnitude of a star to be used for the fit</param>
        /// <param name="fineFit">Used to determine the search area for the stars. When the fit is not a 'fine' fit then 2.5 times
        /// larger are is used for the fit</param>
        public bool SolvePlateConstantsPhase1(double limitMag, bool fineFit)
        {
            int             searchDistance = 10;
            IAstrometricFit previousFit;

            if (!fineFit)
            {
                searchDistance = ((int)Math.Ceiling(2.5 * CoreAstrometrySettings.Default.SearchArea) + 1);
                previousFit    = m_Context.PreliminaryFit;
            }
            else
            {
                searchDistance = (int)Math.Ceiling(CoreAstrometrySettings.Default.SearchArea) + 1;
                previousFit    = m_Context.FirstAstrometricFit;
            }

            m_ConstantsSolver = new PlateConstantsSolver(m_Context.PlateConfig);


            // NOTE: Get the coordinates of the center of the plate.
            double ra0deg, de0Deg;

            previousFit.GetRADEFromImageCoords(
                m_Context.PlateConfig.CenterXImage, m_Context.PlateConfig.CenterYImage, out ra0deg, out de0Deg);

            m_ConstantsSolver.InitPlateSolution(ra0deg, de0Deg);


            #region PASS 1 - Only using the stars down to limitMag

            int idx = -1;
            foreach (IStar star in m_Context.FieldSolveContext.CatalogueStars)
            {
                idx++;

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

                if (m_Context.FitExcludeArea.Contains((int)x, (int)y))
                {
                    continue;
                }

                if (x < 0 || x > m_Context.PlateConfig.ImageWidth || y < 0 || y > m_Context.PlateConfig.ImageHeight)
                {
                    continue;
                }

                if (limitMag < star.Mag)
                {
                    continue;
                }

                StarMapFeature feature = m_Context.StarMap.GetFeatureInRadius((int)x, (int)y, searchDistance);

                Trace.WriteLine(string.Format("Searching for {0} ({1:0.0} mag) at ({2:0.0},{3:0.0}).{4}Found!", star.GetStarDesignation(0), star.Mag, x, y, feature != null ? "" : "NOT "));

                if (fineFit)
                {
                    ImagePixel centroid = m_Context.StarMap.GetCentroid((int)x, (int)y, searchDistance);
                    if (centroid != null)
                    {
                        if (centroid.SignalNoise >= m_AstrometrySettings.DetectionLimit)
                        {
                            if (!m_Context.FitExcludeArea.Contains(centroid.X, centroid.Y))
                            {
                                // NOTE: Don't add a star if outside the selected area
                                m_ConstantsSolver.AddStar(centroid, star, feature);
                            }
                        }
                    }
                    else
                    {
                        //Trace.WriteLine("m_SolvePlateConts.NoMatch:" + star.StarNo);
                    }
                }
                else if (feature != null)
                {
                    ImagePixel plateStar = feature.GetCenter();
                    if (!m_Context.FitExcludeArea.Contains(plateStar.X, plateStar.Y))
                    {
                        // NOTE: Don't add a star if outside the selected area
                        m_ConstantsSolver.AddStar(plateStar, star, feature);
                    }
                }
                else
                {
                    //Trace.WriteLine("m_SolvePlateConts.NoMatch:" + star.StarNo);
                }
            }

            // TODO: Shouldn't this be comming from the settings??
            return(m_ConstantsSolver.Pairs.Count >= 4);

            #endregion
        }