Example #1
0
        public override void BeginMeasurements(IAstroImage astroImage)
        {
            base.BeginMeasurements(astroImage);

            // We consider the first frame of the measurements successfully tracked (after the refining is completed)
            m_IsTrackedSuccessfully = true;
        }
Example #2
0
        public override void BeginMeasurements(IAstroImage astroImage)
        {
            base.BeginMeasurements(astroImage);

            // We consider the first frame of the measurements successfully tracked (after the refining is completed)
            m_IsTrackedSuccessfully = true;
        }
Example #3
0
        public bool InitializeNewTracking(IAstroImage astroImage)
        {
            RefinedAverageFWHM = float.NaN;
            MedianValue        = uint.MinValue;
            m_PastMeasuredRelativeDistances.Clear();
            m_PastAverageRelativeDistances.Clear();

            for (int i = 0; i < m_TrackedObjects.Count; i++)
            {
                ((TrackedObjectLight)m_TrackedObjects[i]).InitializeNewTracking();

                var averlist = new List <double>();
                var meaList  = new List <List <double> >();
                for (int j = 0; j < m_TrackedObjects.Count; j++)
                {
                    meaList.Add(new List <double>());
                    averlist.Add(double.NaN);
                }
                m_PastMeasuredRelativeDistances.Add(i, meaList);
                m_PastAverageRelativeDistances.Add(i, averlist);
            }

            // No preliminary refining used by the AdHockTracker
            RefiningPercentageWorkLeft = 0;
            return(true);
        }
Example #4
0
        private void LocateStarsWithStarRecognition(IAstroImage astroImage)
        {
            EnsureComputedRefinedData();

            if (m_MinLocateDistance > 8)
            {
                if (!LightCurveReductionContext.Instance.WindOrShaking)
                {
                    //TODO: If the wind flag is not set, then use a 3 frame binned integration to locate the stars on
                }

                uint[,] pixels = astroImage.GetPixelsCopy();

                List <PotentialStarStruct> peakPixels = new List <PotentialStarStruct>();
                AutoDiscoveredStars.Clear();
                AutoDiscoveredStars = StarFinder.GetStarsInArea(
                    ref pixels, astroImage.BitPix, astroImage.MaxSignalValue, TangraConfig.PreProcessingFilter.NoFilter, peakPixels, null,
                    (uint)Math.Round(TangraConfig.Settings.Special.LostTrackingMinSignalCoeff * m_MinLocateSignal),
                    TangraConfig.Settings.Special.LostTrackingMinDistance, false,
                    LightCurveReductionContext.Instance.OSDFrame, ReducePeakPixels);

                Stopwatch sw = new Stopwatch();
                sw.Start();
                if (m_LocateObjects.Count == 1 &&
                    AutoDiscoveredStars.Count == 1)
                {
                    LocateSingleStarsWithStarRecognition(AutoDiscoveredStars, astroImage);
                }
                else if (
                    m_LocateObjects.Count == 2 &&
                    peakPixels.Count > 1)
                {
                    LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels);
                }
                else if (
                    m_LocateObjects.Count > 2 &&
                    peakPixels.Count > 1)
                {
                    List <TrackedObject> goodTrackedObjects = TrackedObjects.Cast <TrackedObject>().ToList().FindAll(t => t.LastKnownGoodPosition != null);
                    if (goodTrackedObjects.Count < 2)
                    {
                        // We don't have at least one good pair. Fail.
                    }
                    else if (goodTrackedObjects.Count >= 2)
                    {
                        goodTrackedObjects.Sort((a, b) =>
                                                Math.Min(b.LastKnownGoodPosition.XDouble, b.LastKnownGoodPosition.YDouble).CompareTo(
                                                    Math.Min(a.LastKnownGoodPosition.XDouble, a.LastKnownGoodPosition.YDouble)));

                        Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: Using objects {0} and {1}", goodTrackedObjects[0].TargetNo, goodTrackedObjects[1].TargetNo));
                        // There is only 1 good pair so fallback to using 2 star recognition
                        LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels, goodTrackedObjects[0], goodTrackedObjects[1]);
                    }
                }

                sw.Stop();
                Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: {0} sec", sw.Elapsed.TotalSeconds.ToString("0.00")));
            }
        }
Example #5
0
        public void NextFrame(int frameNo, IAstroImage astroImage)
        {
            m_NativeTrackedObject.ForEach(x => x.NextFrame());

            uint[] pixels = astroImage.GetPixelmapPixels();

            IsTrackedSuccessfully = NativeTracking.TrackNextFrame(frameNo, pixels, m_NativeTrackedObject);
        }
Example #6
0
        private void LocateTwoStarsWithStarRecognition(
            List <PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels,
            TrackedObject trackedObject1, TrackedObject trackedObject2)
        {
            List <CandidatePair> candidates = LocateStarPairsWithStarRecognition(trackedObject1, trackedObject2, stars, pixels);

            LocateTwoStarsWithStarRecognition(candidates, astroImage, trackedObject1, trackedObject2);
        }
Example #7
0
 public override void NextFrame(int frameNo, IAstroImage astroImage)
 {
     // All objects are 'fixed' so always return the same positions
     foreach (TrackedObject trackedObject in TrackedObjects)
     {
         trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
         trackedObject.ThisFrameX         = trackedObject.OriginalObject.ApertureStartingX;
         trackedObject.ThisFrameY         = trackedObject.OriginalObject.ApertureStartingY;
         trackedObject.ThisFrameCertainty = trackedObject.OriginalObject.Gaussian != null ? (float)trackedObject.OriginalObject.Gaussian.Certainty : 0;
     }
 }
Example #8
0
        public override bool InitializeNewTracking(IAstroImage astroImage)
        {
            if (base.InitializeNewTracking(astroImage))
            {
                m_RefiningFramesLeft = TangraConfig.Settings.Tracking.RefiningFrames;

                return true;
            }
            else
                return false;
        }
Example #9
0
        public bool InitializeNewTracking(IAstroImage astroImage)
        {
            NativeTracking.InitialiseNewTracking();

            RefinedAverageFWHM = float.NaN;
            MedianValue        = uint.MinValue;

            m_NativeTrackedObject.ForEach(x => x.InitializeNewTracking());

            return(true);
        }
Example #10
0
 public override void NextFrame(int frameNo, IAstroImage astroImage)
 {
     // All objects are 'fixed' so always return the same positions
     foreach (TrackedObject trackedObject in TrackedObjects)
     {
         trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
         trackedObject.ThisFrameX = trackedObject.OriginalObject.ApertureStartingX;
         trackedObject.ThisFrameY = trackedObject.OriginalObject.ApertureStartingY;
         trackedObject.ThisFrameCertainty = trackedObject.OriginalObject.Gaussian != null ? (float)trackedObject.OriginalObject.Gaussian.Certainty : 0;
     }
 }
Example #11
0
 public override bool InitializeNewTracking(IAstroImage astroImage)
 {
     if (base.InitializeNewTracking(astroImage))
     {
         m_RefiningFramesLeft = TangraConfig.Settings.Tracking.RefiningFrames;
         return(true);
     }
     else
     {
         return(false);
     }
 }
Example #12
0
        public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack)
        {
            m_ObjectToTrack = objectToTrack;

            TrackedObject = new TrackedAstrometricObject()
            {
                LastKnownX = m_ObjectToTrack.StartingX,
                LastKnownY = m_ObjectToTrack.StartingY,
                RAHours    = m_ObjectToTrack.RADeg / 15.0,
                DEDeg      = m_ObjectToTrack.DEDeg
            };

            return(true);
        }
Example #13
0
        public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack)
        {
            m_ObjectToTrack = objectToTrack;

            TrackedObject = new TrackedAstrometricObject()
            {
                LastKnownX = m_ObjectToTrack.StartingX,
                LastKnownY = m_ObjectToTrack.StartingY,
                RAHours = m_ObjectToTrack.RADeg / 15.0,
                DEDeg = m_ObjectToTrack.DEDeg
            };

            return true;
        }
        public void NextFrame(int frameNo, IAstroImage astroImage)
        {
            m_FrameNo = frameNo;

            TrackSingleStar(frameNo, astroImage);

            m_IsTrackedSuccessfully = TrackedStar.IsLocated;

            if (TrackedStar.IsLocated)
            {
                TrackedStar.LastKnownGoodPosition = new ImagePixel(TrackedStar.Center);
                TrackedStar.LastKnownGoodPsfCertainty = TrackedStar.PSFFit != null ? TrackedStar.PSFFit.Certainty : 0;
            }
        }
Example #15
0
        public void NextFrame(int frameNo, IAstroImage astroImage)
        {
            m_FrameNo = frameNo;

            TrackSingleStar(frameNo, astroImage);

            m_IsTrackedSuccessfully = TrackedStar.IsLocated;

            if (TrackedStar.IsLocated)
            {
                TrackedStar.LastKnownGoodPosition     = new ImagePixel(TrackedStar.Center);
                TrackedStar.LastKnownGoodPsfCertainty = TrackedStar.PSFFit != null ? TrackedStar.PSFFit.Certainty : 0;
            }
        }
Example #16
0
        public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack)
        {
            m_ObjectToTrack = objectToTrack;

            TrackedObject = new TrackedAstrometricObject()
            {
                LastKnownX = m_ObjectToTrack.StartingX,
                LastKnownY = m_ObjectToTrack.StartingY,
                RAHours = m_ObjectToTrack.RADeg / 15.0,
                DEDeg = m_ObjectToTrack.DEDeg
            };

            m_RepeatedIntergationPositions = m_MeasurementContext.IntegratedFramesCount / m_MeasurementContext.FrameInterval;
            if (m_RepeatedIntergationPositions == 0) m_RepeatedIntergationPositions = 1;

            return true;
        }
Example #17
0
        public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit)
        {
            IsTrackedSuccessfully = false;

            ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid(
                (int)TrackedObject.LastKnownX,
                (int)TrackedObject.LastKnownY,
                CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius);

            if (centroid != null)
            {
                PSFFit psfFit;
                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 + CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius, 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;
                    TrackedObject.LastKnownX = psfFit.XCenter;
                    TrackedObject.LastKnownY = psfFit.YCenter;
                    TrackedObject.PSFFit     = psfFit;

                    IsTrackedSuccessfully = true;
                }
            }
        }
Example #18
0
        public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit)
        {
            IsTrackedSuccessfully = false;

            ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid(
                (int)TrackedObject.LastKnownX,
                (int)TrackedObject.LastKnownY,
                CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius);

            if (centroid != null)
            {
                PSFFit psfFit;
                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 + CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius, 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;
                    TrackedObject.LastKnownX = psfFit.XCenter;
                    TrackedObject.LastKnownY = psfFit.YCenter;
                    TrackedObject.PSFFit = psfFit;

                    IsTrackedSuccessfully = true;
                }
            }
        }
Example #19
0
        private void LocateSingleStarsWithStarRecognition(List <PSFFit> stars, IAstroImage astroImage)
        {
            TrackedObject trackedObject = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]);

            trackedObject.ThisFrameX         = (float)stars[0].XCenter;
            trackedObject.ThisFrameY         = (float)stars[0].YCenter;
            trackedObject.PSFFit             = stars[0];
            trackedObject.ThisFrameCertainty = (float)stars[0].Certainty;
            trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition);
            AutoDiscoveredStars.Clear();

            if (TrackedObjects.Count > 1 &&
                LocateFirstObjects.Contains(trackedObject))
            {
                // If guiding star then run the locate second objects again
                ReLocateNonGuidingObjects(astroImage);
            }
        }
Example #20
0
        public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack)
        {
            m_ObjectToTrack = objectToTrack;

            TrackedObject = new TrackedAstrometricObject()
            {
                LastKnownX = m_ObjectToTrack.StartingX,
                LastKnownY = m_ObjectToTrack.StartingY,
                RAHours    = m_ObjectToTrack.RADeg / 15.0,
                DEDeg      = m_ObjectToTrack.DEDeg
            };

            m_RepeatedIntergationPositions = m_MeasurementContext.IntegratedFramesCount / m_MeasurementContext.FrameInterval;
            if (m_RepeatedIntergationPositions == 0)
            {
                m_RepeatedIntergationPositions = 1;
            }

            m_LastMovementPixels = 0;

            return(true);
        }
Example #21
0
        private void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            TrackedStar.NewFrame();
            float expectedX;
            float expectedY;

            GetExpectedXY(out expectedX, out expectedY);

            uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, FIT_AREA);

            // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size
            PSFFit gaussian = new PSFFit((int)expectedX, (int)expectedY);

            gaussian.Fit(pixels, FIT_AREA);

            IImagePixel firstCenter = new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter);

            pixels   = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, FIT_AREA);
            gaussian = new PSFFit(firstCenter.X, firstCenter.Y);
            gaussian.Fit(pixels, TrackedStar.PsfFitMatrixSize);
            if (gaussian.IsSolved)
            {
                TrackedStar.PSFFit             = gaussian;
                TrackedStar.ThisFrameX         = (float)gaussian.XCenter;
                TrackedStar.ThisFrameY         = (float)gaussian.YCenter;
                TrackedStar.ThisSignalLevel    = (float)(gaussian.IMax - gaussian.I0);
                TrackedStar.ThisFrameCertainty = (float)gaussian.Certainty;
                TrackedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
            }
            else
            {
                TrackedStar.ThisFrameX         = expectedX;
                TrackedStar.ThisFrameY         = expectedY;
                TrackedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, TrackedStar.TargetNo));
                TrackedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }
        }
        private void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            TrackedStar.NewFrame();
            float expectedX;
            float expectedY;

            GetExpectedXY(out expectedX, out expectedY);

            uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, FIT_AREA);

            // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size
            PSFFit gaussian = new PSFFit((int)expectedX, (int)expectedY);
            gaussian.Fit(pixels, FIT_AREA);

            IImagePixel firstCenter = new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter);

            pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, FIT_AREA);
            gaussian = new PSFFit(firstCenter.X, firstCenter.Y);
            gaussian.Fit(pixels, TrackedStar.PsfFitMatrixSize);
            if (gaussian.IsSolved)
            {
                TrackedStar.PSFFit = gaussian;
                TrackedStar.ThisFrameX = (float)gaussian.XCenter;
                TrackedStar.ThisFrameY = (float)gaussian.YCenter;
                TrackedStar.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0);
                TrackedStar.ThisFrameCertainty = (float)gaussian.Certainty;
                TrackedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
            }
            else
            {
                TrackedStar.ThisFrameX = expectedX;
                TrackedStar.ThisFrameY = expectedY;
                TrackedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, TrackedStar.TargetNo));
                TrackedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }
        }
Example #23
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            m_FrameNo = frameNo;

            if (m_Refining)
            {
                // For refining use the base class
                base.NextFrame(frameNo, astroImage);
            }
            else
            {
                // And for measuring use
                TrackSingleStar(frameNo, astroImage);
            }

            if (m_RefiningFramesLeft > 0)
            {
                if (OccultedStar.IsLocated)
                {
                    m_RefiningFramesLeft--;
                }
            }
            else
            {
                m_IsTrackedSuccessfully = OccultedStar.IsLocated;
            }

            if (OccultedStar.IsLocated && !m_NotCertain)
            {
                AddPreviousPosition();
            }

            if (OccultedStar.IsLocated)
            {
                OccultedStar.LastKnownGoodPosition     = new ImagePixel(OccultedStar.Center);
                OccultedStar.LastKnownGoodPsfCertainty = OccultedStar.PSFFit != null ? OccultedStar.PSFFit.Certainty : 0;
            }
        }
Example #24
0
        private void LocateTwoStarsWithStarRecognition(
            List <CandidatePair> candidates, IAstroImage astroImage,
            TrackedObject trackedObject1, TrackedObject trackedObject2)
        {
            try
            {
                if (candidates.Count > 0)
                {
                    candidates.Sort((c1, c2) => c2.Weight.CompareTo(c1.Weight));
                    CandidatePair bestPair = candidates[0];

                    bestPair.Object1.PSFFit             = bestPair.Star1;
                    bestPair.Object1.ThisFrameX         = (float)bestPair.Star1.XCenter;
                    bestPair.Object1.ThisFrameY         = (float)bestPair.Star1.YCenter;
                    bestPair.Object1.ThisFrameCertainty = (float)bestPair.Star1.Certainty;
                    bestPair.Object1.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition);

                    bestPair.Object2.PSFFit             = bestPair.Star2;
                    bestPair.Object2.ThisFrameX         = (float)bestPair.Star2.XCenter;
                    bestPair.Object2.ThisFrameY         = (float)bestPair.Star2.YCenter;
                    bestPair.Object2.ThisFrameCertainty = (float)bestPair.Star2.Certainty;
                    bestPair.Object2.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition);

                    ReLocateNonGuidingObjects(astroImage);
                }
                else
                {
                    trackedObject1.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterStarRecognition);
                    trackedObject2.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterStarRecognition);
                }
            }
            finally
            {
                AutoDiscoveredStars.Clear();
            }
        }
Example #25
0
 private void LocateSingleNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
 {
     LocateNonGuidingObject(astroImage, trackedObject, newStaringPos);
 }
Example #26
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            base.NextFrame(frameNo, astroImage);

            #region run the full star recognition recovery if enabled
            if (TangraConfig.Settings.Tracking.RecoverFromLostTracking &&
                m_RefiningFramesLeft <= 0)
            {
                bool notAllStarsLocated = TrackedObjects.Exists(o => !o.IsLocated);
                bool notAllLocateFirstStarsLocated = LocateFirstObjects.Exists(o => !o.IsLocated);
                if (notAllLocateFirstStarsLocated && LocateFirstObjects.Count > 1)
                    LocateStarsWithStarRecognition(astroImage);

                // TODO: Use the notAllStarsLocated to troubleshoot the pattern recognition alignment
            }
            #endregion

            bool allGuidingStarsLocated = true;
            foreach (TrackedObject trackedObject in LocateFirstObjects)
            {
                if (!trackedObject.IsLocated && !trackedObject.IsOffScreen)
                    allGuidingStarsLocated = false;
            }

            if (m_RefiningFramesLeft > 0)
            {
                if (allGuidingStarsLocated)
                    m_RefiningFramesLeft--;
            }
            else
            {
               m_IsTrackedSuccessfully =
                    LocateFirstObjects.Count > 0
                            ? allGuidingStarsLocated
                            : OccultedStar.IsLocated;
            }

            if (!m_Refining &&
                (LocateFirstObjects.Count > 0 && allGuidingStarsLocated) &&
                (LightCurveReductionContext.Instance.FieldRotation || LightCurveReductionContext.Instance.LightCurveReductionType == LightCurveReductionType.MutualEvent))
            {
                for (int i = 0; i < TrackedObjects.Count; i++)
                {
                    TrackedObject obj1 = TrackedObjects[i] as TrackedObject;

                    for (int j = 0; j < TrackedObjects.Count; j++)
                    {
                        if (i == j) continue;

                        TrackedObject obj2 = TrackedObjects[j] as TrackedObject;

                        long pairId = (((long)obj1.TargetNo) << 32) + (long)obj2.TargetNo;

                        double oldDistance = m_RefinedDistances[pairId];
                        double newDistance = ImagePixel.ComputeDistance(
                            obj1.Center.XDouble, obj2.Center.XDouble,
                            obj1.Center.YDouble, obj2.Center.YDouble);

                        m_RefinedDistances[pairId] = (oldDistance + newDistance) / 2.0;

                        LocationVector vector = obj1.OtherGuidingStarsLocationVectors[obj2.TargetNo];
                        vector.DeltaXToAdd = (vector.DeltaXToAdd + obj2.Center.XDouble - obj1.Center.XDouble) / 2;
                        vector.DeltaYToAdd = (vector.DeltaYToAdd + obj2.Center.YDouble - obj1.Center.YDouble) / 2;
                    }
                }
            }

            if (!m_IsTrackedSuccessfully)
            {
                // If the tracking has failed, then some objects may be offscreen and have NaN position
                // So inherit the IsOffScreen flag from the previous position
                foreach (TrackedObject obj in TrackedObjects)
                    if (m_IsOffScreenPrev[obj.TargetNo] && double.IsNaN(obj.Center.XDouble))
                        obj.SetIsLocated(false, NotMeasuredReasons.ObjectExpectedPositionIsOffScreen);
            }
            else
            {
                foreach (TrackedObject obj in TrackedObjects) m_IsOffScreenPrev[obj.TargetNo] = obj.IsOffScreen;
            }
        }
Example #27
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            IsTrackedSuccessfully = false;

            // For each of the non manualy positioned Tracked objects do a PSF fit in the area of its previous location
            for (int i = 0; i < m_TrackedObjectGroups.Count; i++)
            {
                TrackedObjectGroup objectGroup = m_TrackedObjectGroups[i];
                objectGroup.NextFrame();

                if (objectGroup.TrackLater)
                {
                    // Group position will be determined after the rest of the stars are found
                }
                else
                {
                    if (objectGroup.IsSingleObject)
                    {
                        TrackedObjectLight trackedObject = (TrackedObjectLight)objectGroup.SingleObject;
                        uint[,] pixels = astroImage.GetPixelsArea(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y, 17);
                        var fit = new PSFFit(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y);
                        fit.FittingMethod = PSFFittingMethod.NonLinearFit;
                        fit.Fit(pixels);

                        if (fit.IsSolved)
                        {
                            if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                            }
                            else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange);
                            }
                            else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated);
                            }
                            else
                            {
                                trackedObject.SetTrackedObjectMatch(fit);
                                trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                            }
                        }
                    }
                    else
                    {
                        string dbg = "";

                        int areaCenterX = (objectGroup.LastCenterObject1.X + objectGroup.LastCenterObject2.X) / 2;
                        int areaCenterY = (objectGroup.LastCenterObject1.Y + objectGroup.LastCenterObject2.Y) / 2;

                        uint[,] pixels = astroImage.GetPixelsArea(areaCenterX, areaCenterY, 35);
                        var doubleFit = new DoublePSFFit(areaCenterX, areaCenterY);

                        int x1 = objectGroup.LastCenterObject1.X - areaCenterX + 17;
                        int y1 = objectGroup.LastCenterObject1.Y - areaCenterY + 17;
                        int x2 = objectGroup.LastCenterObject2.X - areaCenterX + 17;
                        int y2 = objectGroup.LastCenterObject2.Y - areaCenterY + 17;

                        if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                        {
                            doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                        }
                        doubleFit.Fit(pixels, x1, y1, x2, y2);

                        if (doubleFit.IsSolved)
                        {
                            PSFFit fit1 = doubleFit.GetGaussian1();
                            PSFFit fit2 = doubleFit.GetGaussian2();

                            TrackedObjectLight trackedObject1;
                            TrackedObjectLight trackedObject2;

                            bool groupIdentified = objectGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2);
                            if (!groupIdentified)
                            {
                                dbg += "Ni-";
                                objectGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);

                                //Bitmap bmp = new Bitmap(100, 200);
                                //using (Graphics g = Graphics.FromImage(bmp))
                                //{
                                //	doubleFit.DrawInternalPoints(g, new Rectangle(0, 0, 100, 200), 5, 5, Brushes.Lime, Brushes.Yellow, 8);
                                //	g.Save();
                                //}
                                //bmp.Save(@"D:\Hristo\mutual_double_fit.bmp");
                                m_FailedGroupFits++;
                            }
                            else
                            {
                                PSFFit[]             fits           = new PSFFit[] { fit1, fit2 };
                                TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 };

                                int tooSmallCertainties = 0;
                                int errors = 0;

                                for (int j = 0; j < 2; j++)
                                {
                                    PSFFit             fit           = fits[j];
                                    TrackedObjectLight trackedObject = trackedObjects[j];

                                    if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY)
                                    {
                                        tooSmallCertainties++;
                                        trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                        dbg += "TsGs-";
                                    }
                                    else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM)
                                    {
                                        trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange);
                                        dbg += "Fw-";
                                        errors++;
                                    }
                                    else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION)
                                    {
                                        trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated);
                                        dbg += "Elo-";
                                        errors++;
                                    }
                                    else
                                    {
                                        trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                        dbg += "Ts-";
                                    }
                                }

                                if (tooSmallCertainties == 2)
                                {
                                    trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                                    trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                                    errors++;
                                    m_FailedGroupFits++;
                                    dbg += "Uncer-";
                                }

                                if (errors == 0)
                                {
                                    if (objectGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter))
                                    {
                                        trackedObjects[0].SetTrackedObjectMatch(fits[0]);
                                        trackedObjects[1].SetTrackedObjectMatch(fits[1]);
                                        m_FailedGroupFits = 0;
                                        dbg += "Id-";

                                        double dist = ImagePixel.ComputeDistance(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter);
                                        if (dist < 2)
                                        {
                                            Trace.WriteLine("TOO CLOSE");
                                        }

                                        if (dist > 16)
                                        {
                                            Trace.WriteLine("TOO FAR");
                                        }
                                    }
                                    else
                                    {
                                        dbg += "NoId-";
                                    }
                                }
                            }
                        }
                        else
                        {
                            dbg += "NoSlv-";
                        }

                        objectGroup.ValidatePosition();
                        Trace.WriteLine(dbg);
                    }
                }
            }

            bool atLeastOneGroupLocated = false;

            for (int i = 0; i < m_TrackedObjectGroups.Count; i++)
            {
                TrackedObjectGroup trackedGroup = m_TrackedObjectGroups[i];

                if (!trackedGroup.IsSingleObject && trackedGroup.LastCenterObject1 != null && trackedGroup.LastCenterObject2 != null)
                {
                    Trace.WriteLine(string.Format("({0}, {1}, {2}) ({3},{4},{5}) [{6},{7}]",
                                                  trackedGroup.LastCenterObject1.XDouble, trackedGroup.LastCenterObject1.YDouble, trackedGroup.LastCenterObject1.Brightness,
                                                  trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject2.YDouble, trackedGroup.LastCenterObject2.Brightness,
                                                  trackedGroup.LastCenterObject1.XDouble - trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject1.YDouble - trackedGroup.LastCenterObject2.YDouble));
                }

                bool containsFullyDisappearingTarget = trackedGroup.ContainsOcultedStar && m_IsFullDisappearance;

                if (!containsFullyDisappearingTarget && trackedGroup.IsLocated)
                {
                    atLeastOneGroupLocated = true;
                }

                if (!containsFullyDisappearingTarget)
                {
                    continue;
                }

                int    numReferences = 0;
                double x_double;
                double y_double;

                if (trackedGroup.IsSingleObject && m_IsFullDisappearance)
                {
                    // This is the case for single fully disappearing targets
                    double totalX = 0;
                    double totalY = 0;
                    numReferences = 0;

                    for (int j = 0; j < m_TrackedObjectGroups.Count; j++)
                    {
                        TrackedObjectGroup referenceGroup = (TrackedObjectGroup)m_TrackedObjectGroups[j];
                        if (referenceGroup.IsLocated)
                        {
                            totalX += (trackedGroup.BrigherOriginalObject.ApertureStartingX - referenceGroup.BrigherOriginalObject.ApertureStartingX) + referenceGroup.BrigherObjectLastCenter.XDouble;
                            totalY += (trackedGroup.BrigherOriginalObject.ApertureStartingY - referenceGroup.BrigherOriginalObject.ApertureStartingY) + referenceGroup.BrigherObjectLastCenter.YDouble;
                            numReferences++;
                            atLeastOneGroupLocated = true;
                        }
                    }

                    x_double = totalX / numReferences;
                    y_double = totalY / numReferences;
                }
                else
                {
                    // The fully disappearing target is in a group. The other target would have been located. We use the last known position of the other targets
                    numReferences = 1;
                    x_double      = trackedGroup.NonOccultedObjectLastCenter.XDouble;
                    y_double      = trackedGroup.NonOccultedObjectLastCenter.YDouble;
                }


                if (numReferences == 0)
                {
                    trackedGroup.SetIsTracked(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated);
                }
                else
                {
                    int x = (int)(Math.Round(x_double));
                    int y = (int)(Math.Round(y_double));

                    uint[,] pixels = astroImage.GetPixelsArea(x, y, 35);

                    if (trackedGroup.IsSingleObject)
                    {
                        PSFFit fit = new PSFFit(x, y);

                        fit.Fit(pixels);

                        if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY)
                        {
                            trackedGroup.SingleObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                            trackedGroup.SingleObject.SetTrackedObjectMatch(fit);
                        }
                        else if (m_IsFullDisappearance)
                        {
                            trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound);
                        }
                        else
                        {
                            trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                        }
                    }
                    else
                    {
                        string       dbg       = "";
                        DoublePSFFit doubleFit = new DoublePSFFit(x, y);

                        int x1 = trackedGroup.LastCenterObject1.X - x + 17;
                        int y1 = trackedGroup.LastCenterObject1.Y - y + 17;
                        int x2 = trackedGroup.LastCenterObject2.X - x + 17;
                        int y2 = trackedGroup.LastCenterObject2.Y - y + 17;

                        if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                        {
                            doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                        }

                        doubleFit.Fit(pixels, x1, y1, x2, y2);

                        if (doubleFit.IsSolved)
                        {
                            PSFFit             fit1    = doubleFit.GetGaussian1();
                            PSFFit             fit2    = doubleFit.GetGaussian2();
                            IImagePixel        center1 = null;
                            IImagePixel        center2 = null;
                            TrackedObjectLight trackedObject1;
                            TrackedObjectLight trackedObject2;

                            bool resortToBrightness = false;
                            bool groupIdentified    = trackedGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2);
                            if (!groupIdentified && m_IsFullDisappearance)
                            {
                                dbg               += "ReBr::";
                                groupIdentified    = trackedGroup.IdentifyBrightObject(fit1, fit2, STELLAR_OBJECT_MIN_CERTAINTY, out trackedObject1, out trackedObject2, out center1, out center2);
                                resortToBrightness = true;
                            }

                            if (!groupIdentified)
                            {
                                trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);
                                dbg += "PsF::";
                            }
                            else
                            {
                                PSFFit[]             fits           = new PSFFit[] { fit1, fit2 };
                                IImagePixel[]        centers        = new IImagePixel[] { center1, center2 };
                                TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 };

                                bool objectCheckSuccessful = resortToBrightness
                                                                        ? trackedGroup.CheckIdentifiedObjects(center1.XDouble, center2.XDouble, center1.YDouble, center2.YDouble)
                                                                        : trackedGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter);

                                if (objectCheckSuccessful)
                                {
                                    dbg += "ChS::";
                                    bool   atLeastOneOK = (fit1.IsSolved && fit1.Certainty > GUIDING_STAR_MIN_CERTAINTY) || (fit2.IsSolved && fit2.Certainty > GUIDING_STAR_MIN_CERTAINTY);
                                    double dist         = ImagePixel.ComputeDistance(fit1.XCenter, fit2.XCenter, fit1.YCenter, fit2.YCenter);

                                    if (!atLeastOneOK || ((dist < 2 || dist > 16) && !resortToBrightness))
                                    {
                                        trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);
                                    }

                                    int cntOk = 0;
                                    for (int j = 0; j < 2; j++)
                                    {
                                        PSFFit             fit           = fits[j];
                                        IImagePixel        center        = centers[j];
                                        TrackedObjectLight trackedObject = trackedObjects[j];

                                        if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY)
                                        {
                                            if (resortToBrightness && trackedObject.IsOccultedStar)
                                            {
                                                trackedObject.SetIsTracked(true, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, center, fit.Certainty);
                                                dbg += "OccDi::";
                                            }
                                            else
                                            {
                                                trackedObject.SetTrackedObjectMatch(fit);
                                                trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                                dbg += "TrSuc::";
                                            }

                                            cntOk++;
                                        }
                                        else if (m_IsFullDisappearance && trackedObject.IsOccultedStar)
                                        {
                                            trackedObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, resortToBrightness ? center : null, 1);
                                            dbg += "BadCerSuc::";
                                        }
                                        else
                                        {
                                            trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall, resortToBrightness ? center : null, resortToBrightness ? fit.Certainty : (double?)null);
                                            dbg += "BadCerNOSuc::";
                                        }
                                    }

                                    if (cntOk == 2)
                                    {
                                        m_FailedGroupFits = 0;
                                    }
                                }
                                else
                                {
                                    trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    m_FailedGroupFits++;
                                    dbg += "ChU::";
                                }
                            }
                        }
                        else
                        {
                            m_FailedGroupFits++;
                            dbg += "NoFi::";
                        }

                        trackedGroup.ValidatePosition();
                        Trace.WriteLine(dbg);
                    }
                }
            }

            IsTrackedSuccessfully = atLeastOneGroupLocated;

            if (IsTrackedSuccessfully)
            {
                RefinedAverageFWHM = m_TrackedObjects.Cast <TrackedObjectLight>().Average(x => x.RefinedFWHM);
            }

            if (m_FailedGroupFits > 10)
            {
                Trace.WriteLine("ERR~10+");
            }
        }
Example #28
0
        private void LocateNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject)
        {
            IImagePixel prevPos = trackedObject.HasRefinedPositions
                                     ? trackedObject.LastRefinedPosition
                                     : trackedObject.LastKnownGoodPosition != null
                                         ? trackedObject.LastKnownGoodPosition
                                         : trackedObject.OriginalObject.AsImagePixel;

            IImagePixel newStaringPos =
                m_AllGuidingStarsFailed
                    ? prevPos
                    : new ImagePixel(prevPos.Brightness, prevPos.XDouble + m_LastFrameDeltaX, prevPos.YDouble + m_LastFrameDeltaY);

            if (trackedObject.OriginalObject.IsWeakSignalObject)
            {
                LocateNonGuidingObject(astroImage, trackedObject, newStaringPos);
            }
            else if (trackedObject.OriginalObject.IsFixedAperture)
            {
                LocateFixedApertureObject(astroImage, trackedObject, newStaringPos);
            }
            else if (
                trackedObject.OriginalObject.TrackingType == TrackingType.OccultedStar &&
                LightCurveReductionContext.Instance.FullDisappearance &&
                !trackedObject.OriginalObject.IsCloseToOtherStars)
            {
                LocateFullDisappearingObject(astroImage, trackedObject, newStaringPos);
            }
            else
            {
                LocateSingleNonGuidingObject(astroImage, trackedObject, newStaringPos);
            }
        }
Example #29
0
        private void LocateFixedApertureObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
        {
            double averageX = 0;
            double averageY = 0;

            GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY);

            trackedObject.SetIsLocated(true, NotMeasuredReasons.FixedObject);
            trackedObject.ThisFrameX = (float)averageX;
            trackedObject.ThisFrameY = (float)averageY;
            trackedObject.PSFFit = null;
            trackedObject.ThisSignalLevel = float.NaN;
            trackedObject.ThisFrameCertainty = float.NaN;
        }
Example #30
0
        protected void ReLocateNonGuidingObjects(IAstroImage astroImage)
        {
            CheckAndCorrectGuidingStarPositions(astroImage, false);
            ComputeFrameShift();

            foreach (TrackedObject trackedObject in LocateSecondObjects)
                LocateNonGuidingObject(astroImage, trackedObject);
        }
Example #31
0
        public virtual void NextFrame(int frameNo, IAstroImage astroImage)
        {
            m_FrameNo = frameNo;

            if (!m_Refining)
            {
                int numLocatedGuidingStars = LocateFirstObjects.Sum(t => t.IsLocated ? 1 : 0);

                // TODO: Think of chaning this to rely on at least one guiding star being located
                //       rather than all guiding stars being located successfully !
                if (numLocatedGuidingStars == LocateFirstObjects.Count)
                {
                    foreach (TrackedObject trackedObject in TrackedObjects)
                    {
                        trackedObject.LastKnownGoodFrameId = frameNo - 1;
                        trackedObject.LastKnownGoodPosition = new ImagePixel((int)trackedObject.ThisSignalLevel, trackedObject.ThisFrameX, trackedObject.ThisFrameY);
                        trackedObject.LastKnownGoodPsfCertainty = trackedObject.ThisFrameCertainty;
                    }
                }
            }

            m_AllGuidingStarsFailed = false;
            foreach (TrackedObject trackedObject in TrackedObjects)
                trackedObject.NewFrame();

            // Locate all guiding objects based on their previous positions
            foreach (TrackedObject trackedObject in LocateFirstObjects)
                LocateObjectAsGuidingStar(astroImage, trackedObject, false);

            if (m_Refining)
            {
                if (m_MedianValueStart == uint.MaxValue)
                    m_MedianValueStart = astroImage.MedianNoise;

                UpdateReferencePosition();
            }
            else
            {
                // Based on the refined distances, brightness and allowed tolerance
                // confirm the positions and fix some of them if needed
                CheckAndCorrectGuidingStarPositions(astroImage, true);
                ComputeFrameShift();
            }

            foreach (TrackedObject trackedObject in LocateSecondObjects)
                LocateNonGuidingObject(astroImage, trackedObject);

            if (m_AllGuidingStarsFailed)
                LocateSecondObjects.ForEach((o) => o.SetIsLocated(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated));
        }
Example #32
0
        private void LocateObjectAsGuidingStar(IAstroImage astroImage, TrackedObject trackedObject, bool useLowPassFilter)
        {
            trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason);

            int bestMaxFixAreaSize = !float.IsNaN(trackedObject.OriginalObject.RefinedFWHM) ? (int)(6 * trackedObject.OriginalObject.RefinedFWHM) : 17;
            if (bestMaxFixAreaSize > 17) bestMaxFixAreaSize = 35; // We only support FSP Fitting of 17 or 35 square matrixes
            if (bestMaxFixAreaSize < 17) bestMaxFixAreaSize = 17;

            // Try all fits from 5 to 15. Find the one with the highest peak, then do a fit around this area with the configured psf matrix size
            uint[,] pixels;
            if (useLowPassFilter)
            {
                pixels = astroImage.GetPixelsArea((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize + 2);
                pixels = EnhanceByteAreaForSearch(pixels);
            }
            else
            {
                pixels = astroImage.GetPixelsArea((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize);
            }

            // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size
            PSFFit gaussian = new PSFFit((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY);
            gaussian.Fit(pixels, bestMaxFixAreaSize);

            if (gaussian.Certainty < TangraConfig.Settings.Special.MinGuidingStarCertainty &&
                (trackedObject.LastKnownGoodPsfCertainty > TangraConfig.Settings.Special.GoodGuidingStarCertainty || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars))
            {
                // We have a problem. Try to find the star in the area using other means
                IImagePixel centroid = astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize, m_MedianValue);

                if (centroid != null)
                {
                    double maxAllowedDistance = !float.IsNaN(trackedObject.OriginalObject.RefinedFWHM)
                                                    ? 2 * trackedObject.OriginalObject.RefinedFWHM
                                                    : 3 * TangraConfig.Settings.Special.LostTrackingMinDistance;

                    if (LightCurveReductionContext.Instance.WindOrShaking) maxAllowedDistance *= 1.5;

                    if (centroid.DistanceTo(new ImagePixel((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY)) < maxAllowedDistance)
                    {
                        pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, bestMaxFixAreaSize);
                        gaussian = new PSFFit(centroid.X, centroid.Y);
                        gaussian.Fit(pixels, bestMaxFixAreaSize);
                    }
                }
            }

            IImagePixel firstCenter =
                gaussian.IsSolved
                    ? new ImagePixel(gaussian.Brightness, (int)gaussian.XCenter, (int)gaussian.YCenter)
                    : astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize, m_MedianValue);

            if (!gaussian.IsSolved || gaussian.Certainty < TangraConfig.Settings.Special.MinGuidingStarCertainty)
                firstCenter = null;

            if (firstCenter != null)
            {
                // Do a second fit
                pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, bestMaxFixAreaSize);

                int secondFitAreaSize = Math.Max(trackedObject.PsfFitMatrixSize, (int)Math.Round(gaussian.FWHM * 2.5));
                if (secondFitAreaSize % 2 == 0) secondFitAreaSize++;
                secondFitAreaSize = Math.Min(17, secondFitAreaSize);

                gaussian = new PSFFit(firstCenter.X, firstCenter.Y);
                gaussian.Fit(pixels, secondFitAreaSize);

                if (gaussian.IsSolved)
                {
                    double signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0;
                    double brightnessFluctoation = signal > trackedObject.RefinedOrLastSignalLevel
                                                       ? signal / trackedObject.RefinedOrLastSignalLevel
                                                       : trackedObject.RefinedOrLastSignalLevel / signal;
                    //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel;
                    double fluckDiff = Math.Abs(brightnessFluctoation)/m_AllowedSignalFluctoation;

                    //if (trackedObject.LastSignalLevel != 0 &&
                    //    fluckDiff > 1 &&
                    //    LightCurveReductionContext.Instance.WindOrShaking)
                    //{
                    //    // If the located object is not similar brightness as expected, then search for our object in a wider area
                    //    try
                    //    {
                    //        IImagePixel centroid = astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, 14, m_MedianValueStart);
                    //        pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, 17);
                    //        gaussian = new PSFFit(centroid.X, centroid.Y);
                    //        gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize);

                    //        if (gaussian.IsSolved)
                    //        {
                    //            signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0;
                    //            brightnessFluctoation = signal > trackedObject.RefinedOrLastSignalLevel
                    //                                   ? signal / trackedObject.RefinedOrLastSignalLevel
                    //                                   : trackedObject.RefinedOrLastSignalLevel / signal;
                    //            //brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel;
                    //            fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation;
                    //        }
                    //        else
                    //        {
                    //           Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding.WindOrShaking]. Cannot solve third PSF", m_FrameNo, trackedObject.TargetNo));
                    //        }
                    //    }
                    //    catch { }
                    //}

                    if (!trackedObject.HasRefinedPositions || fluckDiff < 1 || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars)
                    {
                        trackedObject.PSFFit = gaussian;
                        trackedObject.ThisFrameX = (float)gaussian.XCenter;
                        trackedObject.ThisFrameY = (float)gaussian.YCenter;
                        trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0);
                        trackedObject.ThisFrameCertainty = (float) gaussian.Certainty;
                        trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);

                        if (m_Refining)
                        {
                            trackedObject.RegisterRefinedPosition(trackedObject.Center, trackedObject.ThisSignalLevel, gaussian.FWHM);
                        }
                    }
                    else
                    {
                        if (useLowPassFilter)
                        {
                            // Only show the warning the second time around
                            Trace.WriteLine(
                                string.Format(
                                    "Frame {0}: Guiding target #{1} is suspect because the brightness fluctuation is too big: {2}",
                                    m_FrameNo, trackedObject.TargetNo, fluckDiff.ToString("0.00")));

                            trackedObject.SetIsLocated(false, NotMeasuredReasons.GuidingStarBrightnessFluctoationTooHigh);
                        }
                    }
                }
                else
                {
                    Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding]. Cannot solve second PSF", m_FrameNo, trackedObject.TargetNo));
                    trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
                }
            }
            else
            {
                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding]. Cannot solve first PSF", m_FrameNo, trackedObject.TargetNo));
                trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }

            if (!trackedObject.IsLocated)
            {
                // Could not locate the object this time
                trackedObject.ThisSignalLevel = trackedObject.LastSignalLevel;
                if (m_Refining)
                {
                    // Use the last known coordinates for refining frames
                    trackedObject.ThisFrameX = trackedObject.LastFrameX;
                    trackedObject.ThisFrameY = trackedObject.LastFrameY;
                    trackedObject.ThisSignalLevel = trackedObject.LastSignalLevel;
                    trackedObject.ThisFrameCertainty = (float)trackedObject.LastKnownGoodPsfCertainty;
                    trackedObject.RegisterRefinedPosition(ImagePixel.Unspecified, float.NaN, double.NaN);
                }
                else
                {
                    // Make the position invalid, which will cause the distance check for this object to fail
                    // which will trigger another fitting later on. Eventually the previous position may be still used
                    trackedObject.ThisFrameX = float.NaN;
                    trackedObject.ThisFrameY = float.NaN;
                    trackedObject.ThisFrameCertainty = float.NaN;
                }
            }
        }
Example #33
0
        protected virtual void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            OccultedStar.NewFrame();
            m_NotCertain = false;
            float expectedX;
            float expectedY;

            GetExpectedXY(out expectedX, out expectedY);

            uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, 17);

            // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size
            PSFFit gaussian = new PSFFit((int)expectedX, (int)expectedY);

            gaussian.Fit(pixels, 17);

            IImagePixel firstCenter =
                gaussian.IsSolved
                    ? new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter)
                    : astroImage.GetCentroid((int)expectedX, (int)expectedY, 17, m_MedianValue);

            if (firstCenter != null)
            {
                // Do a second fit
                pixels   = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, 17);
                gaussian = new PSFFit(firstCenter.X, firstCenter.Y);
                gaussian.Fit(pixels, OccultedStar.PsfFitMatrixSize);
                if (gaussian.IsSolved)
                {
                    double signal = gaussian.IMax - gaussian.I0; if (signal < 0)
                    {
                        signal = 0;
                    }
                    double brightnessFluctoation = signal > OccultedStar.RefinedOrLastSignalLevel
                                                       ? signal / OccultedStar.RefinedOrLastSignalLevel
                                                       : OccultedStar.RefinedOrLastSignalLevel / signal;

                    //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel;
                    double fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation;

                    if (fluckDiff < 1 || (LightCurveReductionContext.Instance.HighFlickeringOrLargeStars && !LightCurveReductionContext.Instance.FullDisappearance && !LightCurveReductionContext.Instance.IsDriftThrough))
                    {
                        OccultedStar.PSFFit             = gaussian;
                        OccultedStar.ThisFrameX         = (float)gaussian.XCenter;
                        OccultedStar.ThisFrameY         = (float)gaussian.YCenter;
                        OccultedStar.ThisSignalLevel    = (float)(gaussian.IMax - gaussian.I0);
                        OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;
                        OccultedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
                    }
                    else
                    {
                        m_NotCertain = true;

                        // This is the Occulted Star, so no brightness fluctoations can be used as excuses!
                        FitObjectInLimitedArea(OccultedStar, astroImage, expectedX, expectedY);
                        OccultedStar.SetIsLocated(
                            LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null,
                            LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null
                                                                ? NotMeasuredReasons.TrackedSuccessfully
                                                                : NotMeasuredReasons.DistanceToleranceTooHighForNonFullDisappearingOccultedStar);

                        m_NotCertain = !OccultedStar.IsLocated;

                        if (m_PreviousPositions.Count > 1 && LightCurveReductionContext.Instance.FullDisappearance && LightCurveReductionContext.Instance.IsDriftThrough)
                        {
                            var prevSignals            = m_PreviousPositions.Select(x => x.Brightness).ToList();
                            var prevSignalMedian       = prevSignals.Median();
                            var prevSignalSigma        = Math.Sqrt(prevSignals.Sum(x => (x - prevSignalMedian) * (x - prevSignalMedian)) / (m_PreviousPositions.Count - 1));
                            var bigBrightnessVariation = (Math.Abs(signal - prevSignalMedian) > prevSignalSigma);
                            m_NotCertain = m_NotCertain || bigBrightnessVariation;
                        }

                        if (m_NotCertain)
                        {
                            OccultedStar.ThisFrameX         = expectedX;
                            OccultedStar.ThisFrameY         = expectedY;
                            OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;
                        }
                    }
                }
                else
                {
                    OccultedStar.ThisFrameX         = expectedX;
                    OccultedStar.ThisFrameY         = expectedY;
                    OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                    Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, OccultedStar.TargetNo));
                    OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
                }
            }
            else
            {
                OccultedStar.ThisFrameX         = expectedX;
                OccultedStar.ThisFrameY         = expectedY;
                OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve first PSF", m_FrameNo, OccultedStar.TargetNo));
                OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }
        }
Example #34
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);
            }
        }
Example #35
0
        public virtual void BeginMeasurements(IAstroImage astroImage)
        {
            m_Refining = false;

            m_MedianValue = (byte)Math.Min(254, ((astroImage.MedianNoise + m_MedianValueStart) / 2.0));

            FinalizeRefining();
        }
Example #36
0
 public virtual bool InitializeNewTracking(IAstroImage astroImage)
 {
     m_Refining = true;
     return true;
 }
Example #37
0
        protected override void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            // TODO: Do some smarts for Lunar Occultations?

            base.TrackSingleStar(frameNo, astroImage);
        }
Example #38
0
        protected void FitObjectInLimitedArea(TrackedObject trackedObject, IAstroImage astroImage, float startingX, float startingY)
        {
            int smallestMatrixSize = (int)Math.Round(trackedObject.OriginalObject.ApertureInPixels * 2);
            if (smallestMatrixSize % 2 == 0) smallestMatrixSize++;

            // If this is not an aperture photometry we still derive a PSF
            uint[,] pixels = astroImage.GetPixelsArea((int)Math.Round(startingX), (int)Math.Round(startingY), 17);

            bool isFSPSolved = false;
            bool isTooFar = true;

            for (int i = Math.Max(trackedObject.PsfFitMatrixSize, smallestMatrixSize); i >= smallestMatrixSize; i -= 2)
            {
                int borderZeroes = (trackedObject.PsfFitMatrixSize - i) / 2;
                for (int x = 0; x < pixels.GetLength(0); x++)
                {
                    for (int y = 0; y < borderZeroes; y++)
                    {
                        pixels[x, y] = 0;
                        pixels[x, pixels.GetLength(1) - y - 1] = 0;
                    }
                }
                for (int y = 0; y < pixels.GetLength(1); y++)
                {
                    for (int x = 0; x < borderZeroes; x++)
                    {
                        pixels[x, y] = 0;
                        pixels[pixels.GetLength(0) - x - 1, y] = 0;
                    }
                }

                PSFFit gaussian = new PSFFit((int)Math.Round(startingX), (int)Math.Round(startingY));
                gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize);
                isFSPSolved = gaussian.IsSolved;
                isTooFar = true;
                if (gaussian.IsSolved)
                {
                    trackedObject.ThisFrameCertainty = (float)gaussian.Certainty;
                    double dist = ImagePixel.ComputeDistance((float)gaussian.XCenter, (float)startingX, (float)gaussian.YCenter, (float)startingY);
                    if (dist <= PositionTolerance)
                    {
                        isTooFar = false;
                        trackedObject.PSFFit = gaussian;
                        trackedObject.ThisFrameX = (float)gaussian.XCenter;
                        trackedObject.ThisFrameY = (float)gaussian.YCenter;
                        trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0);
                        trackedObject.ThisFrameCertainty = (float)gaussian.Certainty;
                        trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
                        return;
                    }
                }
            }

            trackedObject.PSFFit = null;
            trackedObject.ThisFrameX = startingX;
            trackedObject.ThisFrameY = startingY;
            trackedObject.SetIsLocated(false,
                !isFSPSolved
                    ? NotMeasuredReasons.PSFFittingFailed
                    : isTooFar
                        ? NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance
                        : NotMeasuredReasons.UnknownReason);
        }
Example #39
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            m_FrameNo = frameNo;

            if (m_Refining)
            {
                // For refining use the base class
                base.NextFrame(frameNo, astroImage);
            }
            else
            {
                // And for measuring use
                TrackSingleStar(frameNo, astroImage);
            }

            if (m_RefiningFramesLeft > 0)
            {
                if (OccultedStar.IsLocated)
                    m_RefiningFramesLeft--;
            }
            else
            {
                m_IsTrackedSuccessfully = OccultedStar.IsLocated;
            }

            if (OccultedStar.IsLocated && !m_NotCertain)
                AddPreviousPosition();

            if (OccultedStar.IsLocated)
            {
                OccultedStar.LastKnownGoodPosition = new ImagePixel(OccultedStar.Center);
                OccultedStar.LastKnownGoodPsfCertainty = OccultedStar.PSFFit != null ? OccultedStar.PSFFit.Certainty : 0;
            }
        }
Example #40
0
        private void CheckAndCorrectGuidingStarPositions(IAstroImage astroImage, bool retryWithLPFilterIfSuspectObjects)
        {
            List<int> goodObjects = new List<int>();
            List<int> suspectObjects = new List<int>();

            for (int k = 0; k < 2; k++)
            {
                goodObjects.Clear();
                suspectObjects.Clear();

                if (LocateFirstObjects.Count == 1)
                {
                    if (!LocateFirstObjects[0].IsLocated ||
                        float.IsNaN(LocateFirstObjects[0].ThisFrameX) ||
                        float.IsNaN(LocateFirstObjects[0].ThisFrameY))
                    {
                        suspectObjects.Add(LocateFirstObjects[0].TargetNo);
                    }
                }
                else
                {
                    // See how many of the distances are okay
                    for (int i = 0; i < LocateFirstObjects.Count; i++)
                    {
                        TrackedObject obj1 = LocateFirstObjects[i];

                        for (int j = 0; j < LocateFirstObjects.Count; j++)
                        {
                            if (i == j) continue;

                            TrackedObject obj2 = LocateFirstObjects[j];

                            long pairId = (((long) obj1.TargetNo) << 32) + (long) obj2.TargetNo;
                            double expectedDistance = m_RefinedDistances[pairId];
                            double actualDistance =
                                ImagePixel.ComputeDistance(obj1.ThisFrameX, obj2.ThisFrameX, obj1.ThisFrameY,
                                                           obj2.ThisFrameY);

                            if (Math.Abs(expectedDistance - actualDistance) <= PositionTolerance)
                            {
                                goodObjects.Add(obj1.TargetNo);
                                goodObjects.Add(obj2.TargetNo);
                            }
                            else
                            {
                                suspectObjects.Add(obj1.TargetNo);
                                suspectObjects.Add(obj2.TargetNo);
                            }
                        }
                    }
                }

                if (k == 0 &&
                    suspectObjects.Count > 0 &&
                    retryWithLPFilterIfSuspectObjects)
                {
                    // There are some suspect objects. Try to locate the guiding stars with a low pass filter
                    foreach (TrackedObject trackedObject in LocateFirstObjects)
                        LocateObjectAsGuidingStar(astroImage, trackedObject, true);
                }
                else
                    break;
            }

            if (suspectObjects.Count > 0)
            {
                if (goodObjects.Distinct().Count() == LocateFirstObjectsTargetIds.Count)
                {
                    // There is at least one good distance involving each of the locate first objects
                    // This means the suspect distance it not too bad so we ignore and continue
                }
                else
                {
                    if (goodObjects.Count == 0)
                    {
                        List<TrackedObject> okayObjects = LocateFirstObjects.FindAll(o => !o.IsOccultedStar && o.IsLocated);

                        if (okayObjects.Count == 0)
                        {
                            // If one of the objects is the occulted star (found) and non of the other guiding stars are found
                            // then make all objects not found and use the latest expected positions

                            foreach(TrackedObject obj in LocateFirstObjects)
                            {
                                obj.PSFFit = null;
                                obj.ThisFrameX = obj.LastFrameX;
                                obj.ThisFrameY = obj.LastFrameY;
                                obj.ThisFrameCertainty = (float)obj.LastKnownGoodPsfCertainty;
                                obj.SetIsLocated(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated);
                            }

                            m_AllGuidingStarsFailed = true;
                            return;
                        }

                        // If no distances are okay consider the brightest located first object as the correctly identified one
                        // and then find the positions of the other ones based on the expected distances (and do another PSF fit in a smaller area)
                        okayObjects = LocateFirstObjects.FindAll(o => o.IsLocated);
                        okayObjects.Sort((o1, o2) => o1.LastSignalLevel.CompareTo(o2.LastSignalLevel));
                        TrackedObject brightestObject = okayObjects[0];

                        foreach (TrackedObject obj in LocateFirstObjects)
                        {
                            if (obj.TargetNo == brightestObject.TargetNo) continue;

                            LocationVector vec = brightestObject.OtherGuidingStarsLocationVectors[obj.TargetNo];
                            double expectedX = brightestObject.ThisFrameX + vec.DeltaXToAdd;
                            double expectedY = brightestObject.ThisFrameY + vec.DeltaYToAdd;

                            if (expectedX < RefinedAverageFWHM || expectedX > astroImage.Width - RefinedAverageFWHM ||
                                expectedY < RefinedAverageFWHM || expectedY > astroImage.Height - RefinedAverageFWHM)
                            {
                                // The expected position in Off Screen.
                                obj.PSFFit = null;
                                obj.ThisFrameX = float.NaN;
                                obj.ThisFrameY = float.NaN;
                                obj.ThisFrameCertainty = float.NaN;
                                obj.SetIsLocated(false, NotMeasuredReasons.ObjectExpectedPositionIsOffScreen);
                                continue;
                            }

                            uint[,] pixels = astroImage.GetPixelsArea((int)Math.Round(expectedX), (int)Math.Round(expectedY), 19);
                            pixels = EnhanceByteAreaForSearch(pixels);

                            PSFFit gaussian = new PSFFit((int)Math.Round(expectedX), (int)Math.Round(expectedY));
                            gaussian.Fit(pixels, obj.PsfFitMatrixSize);
                            if (gaussian.IsSolved)
                            {
                                double distance = ImagePixel.ComputeDistance(gaussian.XCenter, expectedX, gaussian.YCenter, expectedY);
                                if (distance <= 2 * PositionTolerance)
                                {
                                    // Object successfully located
                                    obj.PSFFit = gaussian;
                                    obj.ThisFrameX = (float)gaussian.XCenter;
                                    obj.ThisFrameY = (float)gaussian.YCenter;
                                    obj.ThisFrameCertainty = (float)gaussian.Certainty;
                                    obj.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterDistanceCheck);
                                    Trace.WriteLine(string.Format("Frame {0}: Successfully located object #{1} after a close look up {2}px from the expected position.", m_FrameNo, obj.TargetNo, distance.ToString("0.00")));
                                }
                                else
                                {
                                    obj.PSFFit = null;
                                    obj.ThisFrameX = (float)expectedX;
                                    obj.ThisFrameY = (float)expectedY;
                                    obj.ThisFrameCertainty = 0;
                                    obj.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    Trace.WriteLine(string.Format("Frame {0}: Cannot locate object #{1}. A close look up found it {2}px from the expected position.", m_FrameNo, obj.TargetNo, distance.ToString("0.00")));
                                }
                            }
                        }
                    }
                    else
                    {
                        // Some objects are okay and some are not okay.
                        List<int> badObjectIds = suspectObjects.FindAll(o => goodObjects.IndexOf(o) == -1).Distinct().ToList();
                        List<int> goodObjectIds = goodObjects.Distinct().ToList();
                        foreach(int badObjectId in badObjectIds)
                        {
                            double expectedX = 0;
                            double expectedY = 0;

                            TrackedObject badObject = TrackedObjectsByTargetId[badObjectId];
                            foreach (int goodObjectId in goodObjectIds)
                            {
                                TrackedObject goodObject = TrackedObjectsByTargetId[goodObjectId];
                                LocationVector vec = goodObject.OtherGuidingStarsLocationVectors[badObjectId];

                                expectedX += (goodObject.ThisFrameX + vec.DeltaXToAdd);
                                expectedY += (goodObject.ThisFrameY + vec.DeltaYToAdd);
                            }

                            expectedX /= goodObjectIds.Count;
                            expectedY /= goodObjectIds.Count;

                            uint[,] pixels = astroImage.GetPixelsArea((int)Math.Round(expectedX), (int)Math.Round(expectedY), 19);
                            pixels = EnhanceByteAreaForSearch(pixels);

                            PSFFit gaussian = new PSFFit((int)Math.Round(expectedX), (int)Math.Round(expectedY));
                            gaussian.Fit(pixels, badObject.PsfFitMatrixSize);
                            if (gaussian.IsSolved)
                            {
                                double distance = ImagePixel.ComputeDistance(gaussian.XCenter, expectedX, gaussian.YCenter, expectedY);
                                if (distance <= 2 * PositionTolerance)
                                {
                                    // Object successfully located
                                    badObject.PSFFit = gaussian;
                                    badObject.ThisFrameX = (float)gaussian.XCenter;
                                    badObject.ThisFrameY = (float)gaussian.YCenter;
                                    badObject.ThisFrameCertainty = (float)gaussian.Certainty;
                                    badObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterDistanceCheck);
                                    Trace.WriteLine(string.Format("Frame {0}: Successfully located object #{1} after a close look up {2}px from the expected position.", m_FrameNo, badObjectId, distance.ToString("0.00")));
                                }
                                else
                                {
                                    badObject.PSFFit = null;
                                    badObject.ThisFrameX = (float)expectedX;
                                    badObject.ThisFrameY = (float)expectedY;
                                    badObject.ThisFrameCertainty = 0;
                                    badObject.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    Trace.WriteLine(string.Format("Frame {0}: Cannot locate object #{1}. A close look up found it {2}px from the expected position.", m_FrameNo, badObjectId, distance.ToString("0.00")));
                                }
                            }
                        }
                    }
                }
            }
            else if (
                goodObjects.Count == 0 &&
                LocateFirstObjects.Count == 1 &&
                float.IsNaN(LocateFirstObjects[0].ThisFrameX))
            {
                // Single 'lost' guiding star or single object (occulted star only)
                TrackedObject obj1 = LocateFirstObjects[0];

                float bestFluctDiff = float.MaxValue;

                int coeff = LightCurveReductionContext.Instance.WindOrShaking ? 3 : 1;
                for (int i = 0; i < coeff * obj1.PsfFitMatrixSize; i++)
                {
                    int searchRadius = obj1.PsfFitMatrixSize + i;
                    IImagePixel centroid = astroImage.GetCentroid(
                        (int) Math.Round(obj1.LastFrameX), (int) Math.Round(obj1.LastFrameY),
                        searchRadius, m_MedianValue);

                    if (centroid != null)
                    {
                        uint[,] pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, 19);
                        PSFFit gaussian = new PSFFit(centroid.X, centroid.Y);
                        gaussian.Fit(pixels, obj1.PsfFitMatrixSize);
                        if (gaussian.IsSolved)
                        {
                            double brightnessFluctoation = (obj1.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / obj1.RefinedOrLastSignalLevel;
                            double fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation;

                            if (fluckDiff < 1 || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars)
                            {
                                obj1.PSFFit = gaussian;
                                obj1.ThisFrameX = (float) gaussian.XCenter;
                                obj1.ThisFrameY = (float) gaussian.YCenter;
                                obj1.ThisSignalLevel = (float) (gaussian.IMax - gaussian.I0);
                                obj1.ThisFrameCertainty = (float)gaussian.Certainty;
                                obj1.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterWiderAreaSearch);
                                Trace.WriteLine(
                                    string.Format(
                                        "Frame {0}: Successfully located object #{1} after a wider search in {2}px region.",
                                        m_FrameNo, obj1.TargetNo, searchRadius));
                                break;
                            }
                            else
                            {
                                if (bestFluctDiff > fluckDiff)
                                    bestFluctDiff = (float)fluckDiff;
                            }
                        }
                    }
                }

                if (!obj1.IsLocated)
                {
                    obj1.PSFFit = null;
                    obj1.ThisFrameX = obj1.LastFrameX;
                    obj1.ThisFrameY = obj1.LastFrameY;
                    obj1.ThisSignalLevel = obj1.LastSignalLevel;
                    obj1.ThisFrameCertainty = (float) obj1.LastKnownGoodPsfCertainty;
                    obj1.SetIsLocated(false, NotMeasuredReasons.TrackedSuccessfullyAfterWiderAreaSearch);
                    Trace.WriteLine(string.Format("Frame {0}: Cannot locate object #{1} after a wider search in {2}px region. Best fluct diff: {3}",
                        m_FrameNo, obj1.TargetNo, obj1.PsfFitMatrixSize * 2, bestFluctDiff.ToString("0.00")));
                }
            }
        }
Example #41
0
        private void LocateTwoStarsWithStarRecognition(List <PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels)
        {
            TrackedObject trackedObject1 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]);
            TrackedObject trackedObject2 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[1]);

            LocateTwoStarsWithStarRecognition(stars, astroImage, pixels, trackedObject1, trackedObject2);
        }
Example #42
0
        private void LocateFullDisappearingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
        {
            if (m_Refining)
                // Full disapearance is not expected during refining
                LocateNonGuidingObject(astroImage, trackedObject, newStaringPos);
            else
            {
                double averageX, averageY;
                GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY);

                trackedObject.ThisFrameX = (float)averageX + 0.5f;
                trackedObject.ThisFrameY = (float)averageY + 0.5f;
                trackedObject.PSFFit = null;
                trackedObject.ThisSignalLevel = float.NaN;
                trackedObject.ThisFrameCertainty = 1;

                int x0 = (int) Math.Round(averageX);
                int y0 = (int) Math.Round(averageY);

                trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason);
                PSFFit gaussian = null;

                int smallestMatrixSize = (int)Math.Round(trackedObject.OriginalObject.ApertureInPixels * 2);
                if (smallestMatrixSize % 2 == 0) smallestMatrixSize++;

                // If this is not an aperture photometry we still derive a PSF
                uint[,] pixels = astroImage.GetPixelsArea(x0, y0, 17);

                for (int i = trackedObject.PsfFitMatrixSize; i >= smallestMatrixSize; i -= 2)
                {
                    int borderZeroes = (trackedObject.PsfFitMatrixSize - i) / 2;
                    for (int x = 0; x < pixels.GetLength(0); x++)
                    {
                        for (int y = 0; y < borderZeroes; y++)
                        {
                            pixels[x, y] = 0;
                            pixels[x, pixels.GetLength(1) - y - 1] = 0;
                        }
                    }
                    for (int y = 0; y < pixels.GetLength(1); y++)
                    {
                        for (int x = 0; x < borderZeroes; x++)
                        {
                            pixels[x, y] = 0;
                            pixels[pixels.GetLength(0) - x - 1, y] = 0;
                        }
                    }

                    gaussian = new PSFFit(x0, y0);
                    gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize);
                    if (gaussian.IsSolved)
                    {
                        double dist = ImagePixel.ComputeDistance((float)gaussian.XCenter, (float)averageX, (float)gaussian.YCenter, (float)averageY);
                        if (dist <= PositionTolerance)
                        {
                            trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
                            break;
                        }
                        else
                            trackedObject.SetIsLocated(false, NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance);
                    }
                    else
                        trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
                }

                if (gaussian != null)
                {
                    if (!trackedObject.IsLocated)
                        trackedObject.SetIsLocated(true, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound);

                    trackedObject.PSFFit = gaussian;
                    trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0);

                    trackedObject.ThisFrameX = (float)gaussian.XCenter;
                    trackedObject.ThisFrameY = (float)gaussian.YCenter;
                    trackedObject.ThisFrameCertainty = (float)gaussian.Certainty;
                }
            }
        }
Example #43
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            base.NextFrame(frameNo, astroImage);

            #region run the full star recognition recovery if enabled
            if (TangraConfig.Settings.Tracking.RecoverFromLostTracking &&
                m_RefiningFramesLeft <= 0)
            {
                bool notAllStarsLocated            = TrackedObjects.Exists(o => !o.IsLocated);
                bool notAllLocateFirstStarsLocated = LocateFirstObjects.Exists(o => !o.IsLocated);
                if (notAllLocateFirstStarsLocated && LocateFirstObjects.Count > 1)
                {
                    LocateStarsWithStarRecognition(astroImage);
                }

                // TODO: Use the notAllStarsLocated to troubleshoot the pattern recognition alignment
            }
            #endregion

            bool allGuidingStarsLocated = true;
            foreach (TrackedObject trackedObject in LocateFirstObjects)
            {
                if (!trackedObject.IsLocated && !trackedObject.IsOffScreen)
                {
                    allGuidingStarsLocated = false;
                }
            }

            if (m_RefiningFramesLeft > 0)
            {
                if (allGuidingStarsLocated)
                {
                    m_RefiningFramesLeft--;
                }
            }
            else
            {
                m_IsTrackedSuccessfully =
                    LocateFirstObjects.Count > 0
                            ? allGuidingStarsLocated
                            : OccultedStar.IsLocated;
            }

            if (!m_Refining &&
                (LocateFirstObjects.Count > 0 && allGuidingStarsLocated) &&
                (LightCurveReductionContext.Instance.FieldRotation || LightCurveReductionContext.Instance.LightCurveReductionType == LightCurveReductionType.MutualEvent))
            {
                for (int i = 0; i < TrackedObjects.Count; i++)
                {
                    TrackedObject obj1 = TrackedObjects[i] as TrackedObject;

                    for (int j = 0; j < TrackedObjects.Count; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }

                        TrackedObject obj2 = TrackedObjects[j] as TrackedObject;

                        long pairId = (((long)obj1.TargetNo) << 32) + (long)obj2.TargetNo;

                        double oldDistance = m_RefinedDistances[pairId];
                        double newDistance = ImagePixel.ComputeDistance(
                            obj1.Center.XDouble, obj2.Center.XDouble,
                            obj1.Center.YDouble, obj2.Center.YDouble);

                        m_RefinedDistances[pairId] = (oldDistance + newDistance) / 2.0;

                        LocationVector vector = obj1.OtherGuidingStarsLocationVectors[obj2.TargetNo];
                        vector.DeltaXToAdd = (vector.DeltaXToAdd + obj2.Center.XDouble - obj1.Center.XDouble) / 2;
                        vector.DeltaYToAdd = (vector.DeltaYToAdd + obj2.Center.YDouble - obj1.Center.YDouble) / 2;
                    }
                }
            }


            if (!m_IsTrackedSuccessfully)
            {
                // If the tracking has failed, then some objects may be offscreen and have NaN position
                // So inherit the IsOffScreen flag from the previous position
                foreach (TrackedObject obj in TrackedObjects)
                {
                    if (m_IsOffScreenPrev[obj.TargetNo] && double.IsNaN(obj.Center.XDouble))
                    {
                        obj.SetIsLocated(false, NotMeasuredReasons.ObjectExpectedPositionIsOffScreen);
                    }
                }
            }
            else
            {
                foreach (TrackedObject obj in TrackedObjects)
                {
                    m_IsOffScreenPrev[obj.TargetNo] = obj.IsOffScreen;
                }
            }
        }
Example #44
0
        private void LocateNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
        {
            trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason);

            double averageX = 0;
            double averageY = 0;

            GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY);

            trackedObject.ThisFrameX = (float)averageX;
            trackedObject.ThisFrameY = (float)averageY;
            trackedObject.PSFFit = null;
            trackedObject.ThisSignalLevel = float.NaN;
            trackedObject.ThisFrameCertainty = float.NaN;

            List<TrackedObject> resolvedGuidingStars = LocateFirstObjects.FindAll(o => o.IsLocated);
            if (resolvedGuidingStars.Count == 0)
            {
                if (m_Refining)
                    trackedObject.RegisterRefinedPosition(newStaringPos, float.NaN, double.NaN);
            }
            else
            {
                FitObjectInLimitedArea(trackedObject, astroImage, (float) averageX, (float) averageY);

                if (m_Refining)
                    trackedObject.RegisterRefinedPosition(
                        new ImagePixel((int)trackedObject.ThisSignalLevel, trackedObject.ThisFrameX, trackedObject.ThisFrameY),
                        trackedObject.ThisSignalLevel,
                        trackedObject.PSFFit != null ? trackedObject.PSFFit.FWHM : double.NaN);
            }
        }
Example #45
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            IsTrackedSuccessfully = false;

            // For each of the non manualy positioned Tracked objects do a PSF fit in the area of its previous location
            for (int i = 0; i < m_TrackedObjects.Count; i++)
            {
                TrackedObjectLight trackedObject = (TrackedObjectLight)m_TrackedObjects[i];
                trackedObject.NextFrame();

                if (trackedObject.OriginalObject.IsFixedAperture || (trackedObject.OriginalObject.IsOcultedStar() && m_IsFullDisappearance))
                {
                    // Star position will be determined after the rest of the stars are found
                }
                else
                {
                    uint[,] pixels = astroImage.GetPixelsArea(trackedObject.Center.X, trackedObject.Center.Y, 17);
                    var fit = new PSFFit(trackedObject.Center.X, trackedObject.Center.Y);
                    fit.FittingMethod = TangraConfig.Settings.Tracking.CheckElongation ? PSFFittingMethod.NonLinearAsymetricFit : PSFFittingMethod.NonLinearFit;
                    fit.Fit(pixels);

                    if (fit.IsSolved)
                    {
                        if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY)
                        {
                            trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                        }
                        else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM)
                        {
                            trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange);
                        }
                        else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION)
                        {
                            trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated);
                        }
                        else
                        {
                            trackedObject.SetTrackedObjectMatch(fit);
                            trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                        }
                    }
                }
            }

            bool atLeastOneObjectLocated = false;

            for (int i = 0; i < m_TrackedObjects.Count; i++)
            {
                TrackedObjectLight trackedObject = (TrackedObjectLight)m_TrackedObjects[i];

                bool needsRelativePositioning = trackedObject.OriginalObject.IsFixedAperture || (trackedObject.OriginalObject.IsOcultedStar() && m_IsFullDisappearance);

                if (!needsRelativePositioning && trackedObject.IsLocated)
                {
                    atLeastOneObjectLocated = true;
                }

                if (!needsRelativePositioning)
                {
                    continue;
                }

                double totalX        = 0;
                double totalY        = 0;
                int    numReferences = 0;

                for (int j = 0; j < m_TrackedObjects.Count; j++)
                {
                    TrackedObjectLight referenceObject = (TrackedObjectLight)m_TrackedObjects[j];
                    if (referenceObject.IsLocated)
                    {
                        totalX += (trackedObject.OriginalObject.ApertureStartingX - referenceObject.OriginalObject.ApertureStartingX) + referenceObject.Center.XDouble;
                        totalY += (trackedObject.OriginalObject.ApertureStartingY - referenceObject.OriginalObject.ApertureStartingY) + referenceObject.Center.YDouble;
                        numReferences++;
                        atLeastOneObjectLocated = true;
                    }
                }

                if (numReferences == 0)
                {
                    trackedObject.SetIsTracked(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated);
                }
                else
                {
                    double x_double = totalX / numReferences;
                    double y_double = totalY / numReferences;

                    if (trackedObject.OriginalObject.IsFixedAperture)
                    {
                        trackedObject.SetIsTracked(true, NotMeasuredReasons.FixedObject, new ImagePixel(x_double, y_double), 1);
                    }
                    else if (trackedObject.OriginalObject.IsOcultedStar())
                    {
                        int x = (int)(Math.Round(totalX / numReferences));
                        int y = (int)(Math.Round(totalY / numReferences));

                        int matrixSize = (int)(Math.Round(trackedObject.OriginalObject.ApertureInPixels * 1.5));
                        if (matrixSize % 2 == 0)
                        {
                            matrixSize++;
                        }
                        if (matrixSize > 17)
                        {
                            matrixSize = 17;
                        }

                        uint[,] pixels = astroImage.GetPixelsArea(x, y, matrixSize);


                        PSFFit fit = new PSFFit(x, y);

                        fit.Fit(pixels);


                        if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY)
                        {
                            trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                            trackedObject.SetTrackedObjectMatch(fit);
                        }
                        else if (m_IsFullDisappearance)
                        {
                            trackedObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound);
                        }
                        else
                        {
                            trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                        }
                    }
                }
            }

            IsTrackedSuccessfully = atLeastOneObjectLocated;
        }
Example #46
0
 public void BeginMeasurements(IAstroImage astroImage)
 {
 }
Example #47
0
 public void BeginMeasurements(IAstroImage astroImage)
 {
 }
Example #48
0
        public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit)
        {
            IsTrackedSuccessfully = false;

            PSFFit psfFit = null;

            if (m_RepeatedIntergationPositions * 4 < m_PastFrameNos.Count)
            {
                var expectedPos = GetExpectedPosition(frameNo);
                if (expectedPos != null)
                    AstrometryContext.Current.StarMap.GetPSFFit(expectedPos.X, expectedPos.Y, PSFFittingMethod.NonLinearFit, out psfFit);
            }

            if (psfFit == null)
            {
                var brightestFeature = starMap.GetFeatureInRadius((int)TrackedObject.LastKnownX, (int)TrackedObject.LastKnownY, CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius);

                if (brightestFeature != null)
                {
                    var center = brightestFeature.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);
                    if (refStar == null)
                        // The brightest feature is not a reference star, so we assume it is our object
                        AstrometryContext.Current.StarMap.GetPSFFit(center.X, center.Y, PSFFittingMethod.NonLinearFit, out psfFit);
                }
            }

            if (psfFit == null)
            {
                ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid(
                    (int)TrackedObject.LastKnownX,
                    (int)TrackedObject.LastKnownY,
                    CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius);

                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 + CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius, 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;
                TrackedObject.LastKnownX = psfFit.XCenter;
                TrackedObject.LastKnownY = psfFit.YCenter;
                TrackedObject.PSFFit = psfFit;

                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);
            }
        }
Example #49
0
        private void LocateTwoStarsWithStarRecognition(List<PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels)
        {
            TrackedObject trackedObject1 = TrackedObjects.Cast<TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]);
            TrackedObject trackedObject2 = TrackedObjects.Cast<TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[1]);

            LocateTwoStarsWithStarRecognition(stars, astroImage, pixels, trackedObject1, trackedObject2);
        }
        protected override void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            // TODO: Do some smarts for Lunar Occultations?

            base.TrackSingleStar(frameNo, astroImage);
        }
Example #51
0
        private void LocateTwoStarsWithStarRecognition(
			List<PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels,
			TrackedObject trackedObject1, TrackedObject trackedObject2)
        {
            List<CandidatePair> candidates = LocateStarPairsWithStarRecognition(trackedObject1, trackedObject2, stars, pixels);

            LocateTwoStarsWithStarRecognition(candidates, astroImage, trackedObject1, trackedObject2);
        }
Example #52
0
        protected virtual void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            OccultedStar.NewFrame();
            m_NotCertain = false;
            float expectedX;
            float expectedY;

            GetExpectedXY(out expectedX, out expectedY);

            uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, 17);

            // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size
            PSFFit gaussian = new PSFFit((int)expectedX, (int)expectedY);
            gaussian.Fit(pixels, 17);

            IImagePixel firstCenter =
                gaussian.IsSolved
                    ? new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter)
                    : astroImage.GetCentroid((int)expectedX, (int)expectedY, 17, m_MedianValue);

            if (firstCenter != null)
            {
                // Do a second fit
                pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, 17);
                gaussian = new PSFFit(firstCenter.X, firstCenter.Y);
                gaussian.Fit(pixels, OccultedStar.PsfFitMatrixSize);
                if (gaussian.IsSolved)
                {
                    double signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0;
                    double brightnessFluctoation = signal > OccultedStar.RefinedOrLastSignalLevel
                                                       ? signal / OccultedStar.RefinedOrLastSignalLevel
                                                       : OccultedStar.RefinedOrLastSignalLevel / signal;

                    //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel;
                    double fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation;

                    if (fluckDiff < 1 || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars)
                    {
                        OccultedStar.PSFFit = gaussian;
                        OccultedStar.ThisFrameX = (float)gaussian.XCenter;
                        OccultedStar.ThisFrameY = (float)gaussian.YCenter;
                        OccultedStar.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0);
                        OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;
                        OccultedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
                    }
                    else
                    {
                        m_NotCertain = true;

                        // This is the Occulted Star, so no brightness fluctoations can be used as excuses!
                        FitObjectInLimitedArea(OccultedStar, astroImage, expectedX, expectedY);
                        OccultedStar.SetIsLocated(
                            LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null,
                            LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null
                                ? NotMeasuredReasons.TrackedSuccessfully
                                : NotMeasuredReasons.DistanceToleranceTooHighForNonFullDisappearingOccultedStar);

                        m_NotCertain = !OccultedStar.IsLocated;
                    }
                }
                else
                {
                    OccultedStar.ThisFrameX = expectedX;
                    OccultedStar.ThisFrameY = expectedY;
                    OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                    Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, OccultedStar.TargetNo));
                    OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
                }
            }
            else
            {
                OccultedStar.ThisFrameX = expectedX;
                OccultedStar.ThisFrameY = expectedY;
                OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve first PSF", m_FrameNo, OccultedStar.TargetNo));
                OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }
        }
Example #53
0
        private void LocateTwoStarsWithStarRecognition(
            List<CandidatePair> candidates, IAstroImage astroImage, 
            TrackedObject trackedObject1, TrackedObject trackedObject2)
        {
            try
            {
                if (candidates.Count > 0)
                {
                    candidates.Sort((c1, c2) => c2.Weight.CompareTo(c1.Weight));
                    CandidatePair bestPair = candidates[0];

                    bestPair.Object1.PSFFit = bestPair.Star1;
                    bestPair.Object1.ThisFrameX = (float)bestPair.Star1.XCenter;
                    bestPair.Object1.ThisFrameY = (float)bestPair.Star1.YCenter;
                    bestPair.Object1.ThisFrameCertainty = (float) bestPair.Star1.Certainty;
                    bestPair.Object1.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition);

                    bestPair.Object2.PSFFit = bestPair.Star2;
                    bestPair.Object2.ThisFrameX = (float)bestPair.Star2.XCenter;
                    bestPair.Object2.ThisFrameY = (float)bestPair.Star2.YCenter;
                    bestPair.Object2.ThisFrameCertainty = (float)bestPair.Star2.Certainty;
                    bestPair.Object2.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition);

                    ReLocateNonGuidingObjects(astroImage);
                }
                else
                {
                    trackedObject1.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterStarRecognition);
                    trackedObject2.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterStarRecognition);
                }
            }
            finally
            {
                AutoDiscoveredStars.Clear();
            }
        }
Example #54
0
        public void NextFrame(int frameNo, IAstroImage astroImage)
        {
            m_IsTrackedSuccessfully = false;

            StarMap starMap = new StarMap();

            starMap.FindBestMap(
                m_StarMapConfig,
                (AstroImage)astroImage,
                Rectangle.Empty,
                new Rectangle(0, 0, astroImage.Width, astroImage.Height),
                AstrometryContext.Current.LimitByInclusion);

            if (starMap.Features.Count >= 5)
            {
                starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount));
                int featuresToConsider = Math.Min(10, starMap.Features.Count);

                var featureDistances = new List <List <double> >();
                for (int i = 0; i < featuresToConsider; i++)
                {
                    var dist = new List <double>();
                    for (int j = 0; j < featuresToConsider; j++)
                    {
                        dist.Add(double.NaN);
                    }
                    featureDistances.Add(dist);
                }

                var pivotDistances = new List <List <double> >();
                for (int i = 0; i < featuresToConsider; i++)
                {
                    pivotDistances.Add(new List <double>(UNINITIALIZED_DISTANCES));
                }


                for (int i = 0; i < featuresToConsider; i++)
                {
                    var feature_i = starMap.Features[i];
                    for (int j = i + 1; j < featuresToConsider; j++)
                    {
                        var    feature_j = starMap.Features[j];
                        double distance  = feature_j.GetCenter().DistanceTo(feature_i.GetCenter());
                        pivotDistances[i][j] = distance;
                        pivotDistances[j][i] = distance;
                    }
                }

                Dictionary <int, int> pivotMap = IdentifyPivots(pivotDistances);

                int identifiedObjects = 0;

                for (int i = 0; i < m_TrackedObjects.Count; i++)
                {
                    ((TrackedObject)m_TrackedObjects[i]).NewFrame();

                    var xVals = new List <double>();
                    var yVals = new List <double>();
                    foreach (int key in pivotMap.Keys)
                    {
                        int mapsToSourceFeatureId = pivotMap[key];
                        xVals.Add(starMap.Features[key].GetCenter().XDouble + m_TrackedObjectsPivotDistancesX[i][mapsToSourceFeatureId]);
                        yVals.Add(starMap.Features[key].GetCenter().YDouble + m_TrackedObjectsPivotDistancesY[i][mapsToSourceFeatureId]);
                    }

                    double x0 = xVals.Median();
                    double y0 = yVals.Median();

                    double sigmaX = Math.Sqrt(xVals.Select(x => (x - x0) * (x - x0)).Sum()) / (xVals.Count - 1);
                    double sigmaY = Math.Sqrt(yVals.Select(y => (y - y0) * (y - y0)).Sum()) / (yVals.Count - 1);

                    if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 &&
                        (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage))
                    {
                        // Some of the pivots may have been misidentified. Remove all entries with too large residuals and try again
                        xVals.RemoveAll(x => Math.Abs(x - x0) > sigmaX);
                        yVals.RemoveAll(y => Math.Abs(y - y0) > sigmaY);

                        if (xVals.Count > 1)
                        {
                            x0 = xVals.Median();
                            y0 = yVals.Median();

                            sigmaX = Math.Sqrt(xVals.Select(x => (x - x0) * (x - x0)).Sum()) / (xVals.Count - 1);
                            sigmaY = Math.Sqrt(yVals.Select(y => (y - y0) * (y - y0)).Sum()) / (yVals.Count - 1);
                        }
                    }

                    if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 &&
                        (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage))
                    {
                        // There is something really wrong about this. Reject the position and fail the frame
                        m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance, null, null);
                    }
                    else
                    {
                        PSFFit fit = new PSFFit((int)x0, (int)y0);
                        uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0);
                        fit.Fit(data);

                        if (fit.IsSolved)
                        {
                            m_TrackedObjects[i].SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully, new ImagePixel(fit.XCenter, fit.YCenter), fit.Certainty);
                            ((TrackedObject)m_TrackedObjects[i]).ThisFrameX = (float)fit.XCenter;
                            ((TrackedObject)m_TrackedObjects[i]).ThisFrameY = (float)fit.YCenter;
                            ((TrackedObjectBase)m_TrackedObjects[i]).PSFFit = fit;
                            identifiedObjects++;
                        }
                        else
                        {
                            m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed, null, null);
                        }
                    }
                }

                m_IsTrackedSuccessfully = identifiedObjects == m_TrackedObjects.Count;

                if (m_IsTrackedSuccessfully)
                {
                    UpdatePivotDistances(starMap, pivotMap);
                }
            }
        }
Example #55
0
 public virtual void NextFrame(int frameNo, IAstroImage astroImage)
 {
     IsTrackedSuccessfully = false;
 }
Example #56
0
        public bool InitializeNewTracking(IAstroImage astroImage)
        {
            m_StarMapConfig = new StarMapInternalConfig(StarMapInternalConfig.Default);
            m_StarMapConfig.CustomMaxSignalValue    = astroImage.GetPixelmapPixels().Max();
            m_StarMapConfig.CustomOptimumStarsValue = 25;
            m_StarMapConfig.IsFITSFile = true;

            StarMap starMap = new StarMap();

            starMap.FindBestMap(
                m_StarMapConfig,
                (AstroImage)astroImage,
                Rectangle.Empty,
                new Rectangle(0, 0, astroImage.Width, astroImage.Height),
                AstrometryContext.Current.LimitByInclusion);

            if (starMap.Features.Count < 10)
            {
                MessageBox.Show("Cannot initialize object tracking as less than 10 stars can be identified in the field");
                return(false);
            }

            // Build a signature of the largest 10 features (pivots)
            m_PivotDistances.Clear();
            for (int i = 0; i < 10; i++)
            {
                m_PivotDistances.Add(new List <double>(UNINITIALIZED_DISTANCES));
            }

            double fwhmSum   = 0;
            int    fwhmCount = 0;

            starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount));
            for (int i = 0; i < 10; i++)
            {
                var feature_i = starMap.Features[i];
                for (int j = i + 1; j < 10; j++)
                {
                    var    feature_j = starMap.Features[j];
                    double distance  = feature_j.GetCenter().DistanceTo(feature_i.GetCenter());
                    m_PivotDistances[i][j] = distance;
                    m_PivotDistances[j][i] = distance;
                }

                int    x0  = feature_i.GetCenter().X;
                int    y0  = feature_i.GetCenter().Y;
                PSFFit fit = new PSFFit((int)x0, (int)y0);
                uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0);
                fit.Fit(data);

                if (fit.IsSolved)
                {
                    fwhmSum += fit.FWHM;
                    fwhmCount++;
                }
            }

            m_FWHMAverage = (float)(fwhmSum / fwhmCount);

            for (int i = 0; i < m_TrackedObjects.Count; i++)
            {
                m_TrackedObjectsPivotDistancesX[i] = new List <double>();
                m_TrackedObjectsPivotDistancesY[i] = new List <double>();
                for (int j = 0; j < 10; j++)
                {
                    m_TrackedObjectsPivotDistancesX[i].Add(m_TrackedObjects[i].Center.XDouble - starMap.Features[j].GetCenter().XDouble);
                    m_TrackedObjectsPivotDistancesY[i].Add(m_TrackedObjects[i].Center.YDouble - starMap.Features[j].GetCenter().YDouble);
                }

                int    x0  = m_TrackedObjects[i].Center.X;
                int    y0  = m_TrackedObjects[i].Center.Y;
                PSFFit fit = new PSFFit((int)x0, (int)y0);
                uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0);
                fit.Fit(data);

                if (fit.IsSolved)
                {
                    SetTargetFWHM(i, (float)fit.FWHM);
                }
            }

            m_TargetPivotDistancesListX.Clear();
            m_TargetPivotDistancesListY.Clear();

            return(true);
        }
Example #57
0
        private void LocateStarsWithStarRecognition(IAstroImage astroImage)
        {
            EnsureComputedRefinedData();

            if (m_MinLocateDistance > 8)
            {
                if (!LightCurveReductionContext.Instance.WindOrShaking)
                {
                    //TODO: If the wind flag is not set, then use a 3 frame binned integration to locate the stars on
                }

                uint[,] pixels = astroImage.GetPixelsCopy();

                List<PotentialStarStruct> peakPixels = new List<PotentialStarStruct>();
                AutoDiscoveredStars.Clear();
                AutoDiscoveredStars = StarFinder.GetStarsInArea(
                    ref pixels, astroImage.BitPix, astroImage.MaxSignalValue, TangraConfig.PreProcessingFilter.NoFilter, peakPixels, null,
                    (uint)Math.Round(TangraConfig.Settings.Special.LostTrackingMinSignalCoeff * m_MinLocateSignal),
                    TangraConfig.Settings.Special.LostTrackingMinDistance, false,
                    LightCurveReductionContext.Instance.OSDFrame, ReducePeakPixels);

                Stopwatch sw = new Stopwatch();
                sw.Start();
                if (m_LocateObjects.Count == 1 &&
                    AutoDiscoveredStars.Count == 1)
                {
                    LocateSingleStarsWithStarRecognition(AutoDiscoveredStars, astroImage);
                }
                else if (
                    m_LocateObjects.Count == 2 &&
                    peakPixels.Count > 1)
                {
                    LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels);
                }
                else if (
                    m_LocateObjects.Count > 2 &&
                    peakPixels.Count > 1)
                {
                    List<TrackedObject> goodTrackedObjects = TrackedObjects.Cast<TrackedObject>().ToList().FindAll(t => t.LastKnownGoodPosition != null);
                    if (goodTrackedObjects.Count < 2)
                    {
                        // We don't have at least one good pair. Fail.
                    }
                    else if (goodTrackedObjects.Count >= 2)
                    {
                        goodTrackedObjects.Sort((a, b) =>
                                    Math.Min(b.LastKnownGoodPosition.XDouble, b.LastKnownGoodPosition.YDouble).CompareTo(
                                    Math.Min(a.LastKnownGoodPosition.XDouble, a.LastKnownGoodPosition.YDouble)));

                        Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: Using objects {0} and {1}", goodTrackedObjects[0].TargetNo, goodTrackedObjects[1].TargetNo));
                        // There is only 1 good pair so fallback to using 2 star recognition
                        LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels, goodTrackedObjects[0], goodTrackedObjects[1]);
                    }
                }

                sw.Stop();
                Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: {0} sec", sw.Elapsed.TotalSeconds.ToString("0.00")));
            }
        }