Beispiel #1
0
        public Tracker(List<TrackedObjectConfig> trackedObjects)
        {
            TrackedObjects = new List<ITrackedObject>();

            int i = -1;
            foreach(TrackedObjectConfig originalObject in trackedObjects)
            {
                i++;
                TrackedObject trackedObject = new TrackedObject((byte)i, originalObject);
                TrackedObjects.Add(trackedObject);
                TrackedObjectsByTargetId.Add(trackedObject.TargetNo, trackedObject);

                if (IsLocateFirstObject(originalObject))
                {
                    LocateFirstObjects.Add(trackedObject);
                    LocateFirstObjectsTargetIds.Add(trackedObject.TargetNo);
                }
                else
                    LocateSecondObjects.Add(trackedObject);

                if (trackedObject.IsOccultedStar) OccultedStar = trackedObject;
             }

            m_AllowedSignalFluctoation = LightCurveReductionContext.Instance.HighFlickeringOrLargeStars ? 1.90f : 1.30f;

            //if this is not an aperture photometry we MUST have a PSF fit anyway so
            //       also fit objects with fixed aperture. Also not allow fixed apertures to be added
            //       when the object is faint and there is no good fit.  Test with first guiding and second faint occulted.

            RefinedFWHM = new float[trackedObjects.Count];
        }
Beispiel #2
0
 public StarFieldTracker(List<TrackedObjectConfig> measuringStars)
 {
     int i = -1;
     foreach (var originalObject in measuringStars)
     {
         i++;
         TrackedObject trackedObject = new TrackedObject((byte)i, originalObject);
         TrackedObjects.Add(trackedObject);
         TrackedObjectsByTargetId.Add(trackedObject.TargetNo, trackedObject);
     }
 }
Beispiel #3
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);
            }
        }
Beispiel #4
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);
            }
        }
Beispiel #5
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;
                }
            }
        }
Beispiel #6
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;
        }
Beispiel #7
0
        private void GetAverageObjectPositionsFromGuidingStars(TrackedObject trackedObject, IImagePixel newStaringPos, out double averageX, out double averageY)
        {
            List<TrackedObject> resolvedGuidingStars = LocateFirstObjects.FindAll(o => o.IsLocated);
            if (resolvedGuidingStars.Count == 0)
            {
                averageX = newStaringPos.XDouble;
                averageY = newStaringPos.YDouble;
            }
            else
            {
                averageX = 0;
                averageY = 0;

                foreach (TrackedObject resolvedGuidingStar in resolvedGuidingStars)
                {
                    if (m_Refining)
                    {
                        averageX += (resolvedGuidingStar.ThisFrameX + trackedObject.OriginalObject.ApertureStartingX -
                                     resolvedGuidingStar.OriginalObject.ApertureStartingX);
                        averageY += (resolvedGuidingStar.ThisFrameY + trackedObject.OriginalObject.ApertureStartingY -
                                     resolvedGuidingStar.OriginalObject.ApertureStartingY);
                    }
                    else
                    {
                        LocationVector vec =
                            resolvedGuidingStar.OtherGuidingStarsLocationVectors[trackedObject.TargetNo];
                        averageX += (resolvedGuidingStar.ThisFrameX + vec.DeltaXToAdd);
                        averageY += (resolvedGuidingStar.ThisFrameY + vec.DeltaYToAdd);
                    }
                }

                averageX /= resolvedGuidingStars.Count;
                averageY /= resolvedGuidingStars.Count;
            }
        }
Beispiel #8
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;
                }
            }
        }
Beispiel #9
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);
        }
Beispiel #10
0
 private void LocateSingleNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
 {
     LocateNonGuidingObject(astroImage, trackedObject, newStaringPos);
 }
Beispiel #11
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();
            }
        }
Beispiel #12
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);
        }
Beispiel #13
0
        private List<CandidatePair> LocateStarPairsWithStarRecognition(TrackedObject trackedObject1, TrackedObject trackedObject2, List<PotentialStarStruct> stars, uint[,] pixels)
        {
            List<CandidatePair> candidates = new List<CandidatePair>();

            double minFWHM = (1 - TangraConfig.Settings.Special.LostTrackingFWHMCoeff) * m_AverageFWHM;
            double maxFWHM = (1 + TangraConfig.Settings.Special.LostTrackingFWHMCoeff) * m_AverageFWHM;

            if (trackedObject1.TargetNo != trackedObject2.TargetNo &&
                trackedObject1.LastKnownGoodPosition != null &&
                trackedObject2.LastKnownGoodPosition != null)
            {
                double deltaX = trackedObject1.LastKnownGoodPosition.X - trackedObject2.LastKnownGoodPosition.X;
                double deltaY = trackedObject1.LastKnownGoodPosition.Y - trackedObject2.LastKnownGoodPosition.Y;

                // Looking for two stars with the same distance and similar brighness
                for (int i = 0; i < stars.Count; i++)
                {
                    for (int j = 0; j < stars.Count; j++)
                    {
                        if (i == j) continue;

                        double deltaXStars = stars[i].X - stars[j].X;
                        double deltaYStars = stars[i].Y - stars[j].Y;

                        if (Math.Abs(deltaX - deltaXStars) < TangraConfig.Settings.Special.LostTrackingPositionToleranceCoeff * PositionTolerance &&
                            Math.Abs(deltaY - deltaYStars) < TangraConfig.Settings.Special.LostTrackingPositionToleranceCoeff * PositionTolerance)
                        {
                            // Now compute PSFFits from the pixels
                            PSFFit fit1 = AstroImage.GetPSFFitForPeakPixel(pixels, stars[i], m_MinLocateSignal, minFWHM, maxFWHM);
                            PSFFit fit2 = AstroImage.GetPSFFitForPeakPixel(pixels, stars[j], m_MinLocateSignal, minFWHM, maxFWHM);

                            if (fit1 != null && fit2 != null)
                            {
                                AutoDiscoveredStars.Add(fit1);
                                AutoDiscoveredStars.Add(fit2);

                                deltaXStars = fit1.XCenter - fit2.XCenter;
                                deltaYStars = fit1.YCenter - fit2.YCenter;

                                if (Math.Abs(deltaX - deltaXStars) < PositionTolerance &&
                                    Math.Abs(deltaY - deltaYStars) < PositionTolerance)
                                {
                                    // Compute a certainty and add to the candidates dictionary
                                    CandidatePair pair = new CandidatePair();
                                    pair.Star1 = fit1;
                                    pair.Star2 = fit2;
                                    pair.Object1 = trackedObject1;
                                    pair.Object2 = trackedObject2;

                                    int[] BRIGTHNESS_MATCH_WEIGTH = new int[] { 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };

                                    int weight = (trackedObject1.IsGuidingStar ? 2 : 0) + (trackedObject2.IsGuidingStar ? 2 : 0);
                                    double d1 = pair.Star1.IMax - pair.Star1.I0;
                                    double d2 = pair.Star2.IMax - pair.Star2.I0;

                                    d1 = pair.Object1.RefinedOrLastSignalLevel / d1;
                                    if (d1 > 1) d1 = 1 / d1;
                                    int d1i = Math.Min(10, (int)Math.Round((1 - d1) * 10));

                                    weight += BRIGTHNESS_MATCH_WEIGTH[d1i];

                                    d2 = pair.Object2.RefinedOrLastSignalLevel / d2;
                                    if (d2 > 1) d2 = 1 / d2;
                                    int d2i = Math.Min(10, (int)Math.Round((1 - d2) * 10));

                                    weight += BRIGTHNESS_MATCH_WEIGTH[d2i];

                                    double distanceFromLastKnownGoodPosition =
                                        ImagePixel.ComputeDistance(
                                            pair.Star1.XCenter, pair.Object1.LastKnownGoodPosition.XDouble,
                                            pair.Star1.YCenter, pair.Object1.LastKnownGoodPosition.YDouble);

                                    int closeToPrevCoeff = LightCurveReductionContext.Instance.WindOrShaking ? 2 : 1;
                                    int closeToPrevPosWeighting = 0;
                                    if (distanceFromLastKnownGoodPosition < 4 * closeToPrevCoeff)
                                        closeToPrevPosWeighting = 3;
                                    else if (distanceFromLastKnownGoodPosition < 8 * closeToPrevCoeff)
                                        closeToPrevPosWeighting = 2;
                                    else if (distanceFromLastKnownGoodPosition < 16 * closeToPrevCoeff)
                                        closeToPrevPosWeighting = 1;
                                    else if (distanceFromLastKnownGoodPosition > 32 * closeToPrevCoeff)
                                        closeToPrevPosWeighting = -1;

                                    weight += closeToPrevPosWeighting;

                                    pair.Weight = weight;
                                    candidates.Add(pair);
                                }
                                else
                                    Trace.WriteLine("Pair with close distances has been rejected.");

                            }
                        }
                    }
                }
            }

            return candidates;
        }
 public SpectroscopyStarTracker(TrackedObjectConfig starConfig)
 {
     TrackedStar = new TrackedObject(0, starConfig);
     TrackedStar.LastKnownGoodPosition = new ImagePixel(starConfig.ApertureStartingX, starConfig.ApertureStartingY);
 }
Beispiel #15
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;
                }
            }
        }
Beispiel #16
0
        protected PSFFit GetBestFitGaussian(AstroImage astroImage, TrackedObject guidingStar)
        {
            // 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 = astroImage.GetMeasurableAreaPixels((int)guidingStar.LastFrameX, (int)guidingStar.LastFrameY);

            PSFFit bestGaussian = null;

            if (!guidingStar.OriginalObject.IsCloseToOtherStars)
            {
                // There is only one object in the area, just do a whide fit followed by a fit with the selected matrix size
                PSFFit gaussian = new PSFFit((int) guidingStar.LastFrameX, (int) guidingStar.LastFrameY);
                gaussian.Fit(pixels, pixels.GetLength(0));
                if (gaussian.IsSolved)
                {
                    bestGaussian = gaussian;
                }
            }
            else
            {
                // There is more than one object in the area. We need a smarter way to find the one we need.
                if (guidingStar.IsOccultedStar)
                {
                    for (int matSize = 5; matSize < 15; matSize += 2)
                    {
                        PSFFit gaussian = new PSFFit((int) guidingStar.LastFrameX, (int) guidingStar.LastFrameY);
                        gaussian.Fit(pixels, matSize);
                        if (gaussian.IsSolved)
                        {
                            if (bestGaussian == null ||
                                bestGaussian.IMax < gaussian.IMax)
                            {
                                bestGaussian = gaussian;
                            }
                        }
                    }
                }
                else
                {
                    PSFFit gaussian = new PSFFit((int) guidingStar.LastFrameX, (int) guidingStar.LastFrameY);
                    gaussian.Fit(pixels, guidingStar.PsfFitMatrixSize);
                }
            }

            if (bestGaussian != null)
            {
                pixels = astroImage.GetMeasurableAreaPixels((int)bestGaussian.XCenter, (int)bestGaussian.YCenter);
                bestGaussian = new PSFFit((int)bestGaussian.XCenter, (int)bestGaussian.YCenter);
                bestGaussian.Fit(pixels, guidingStar.PsfFitMatrixSize);
            }

            return bestGaussian;
        }
Beispiel #17
0
        public double ComputeRefinedDistances(TrackedObject obj2, out double vectorX, out double vectorY)
        {
            double refinedDistance = double.NaN;

            if (this.OriginalObject.IsFixedAperture ||
                obj2.OriginalObject.IsFixedAperture)
            {
                // For manually placed apertures, return the initial distances

                vectorX = obj2.OriginalObject.ApertureStartingX - this.OriginalObject.ApertureStartingX;
                vectorY = obj2.OriginalObject.ApertureStartingY - this.OriginalObject.ApertureStartingY;

                return Math.Sqrt(vectorX * vectorX + vectorY * vectorY);
            }

            List<double> distances = new List<double>();

            double xVector = 0;
            double yVector = 0;

            for (int k = 0; k < RefiningPositions.Count; k++)
            {
                IImagePixel pos1 = RefiningPositions[k];
                IImagePixel pos2 = obj2.RefiningPositions[k];

                if (pos1.IsSpecified &&
                    pos2.IsSpecified)
                {
                    // Compute and average the distance
                    double dist = Math.Sqrt((pos1.XDouble - pos2.XDouble) * (pos1.XDouble - pos2.XDouble) + (pos1.YDouble - pos2.YDouble) * (pos1.YDouble - pos2.YDouble));
                    distances.Add(dist);

                    xVector += (pos2.XDouble - pos1.XDouble);
                    yVector += (pos2.YDouble - pos1.YDouble);
                }
            }

            // Get the median and add in the final dict
            distances.Sort();
            if (distances.Count % 2 == 1)
                refinedDistance = distances[distances.Count / 2];
            else if (distances.Count > 0)
                refinedDistance = 0.5 * (distances[(distances.Count / 2) - 1] + distances[distances.Count / 2]);

            vectorX = xVector / distances.Count;
            vectorY = yVector / distances.Count;
            return refinedDistance;
        }
Beispiel #18
0
        private List <CandidatePair> LocateStarPairsWithStarRecognition(TrackedObject trackedObject1, TrackedObject trackedObject2, List <PotentialStarStruct> stars, uint[,] pixels)
        {
            List <CandidatePair> candidates = new List <CandidatePair>();

            double minFWHM = (1 - TangraConfig.Settings.Special.LostTrackingFWHMCoeff) * m_AverageFWHM;
            double maxFWHM = (1 + TangraConfig.Settings.Special.LostTrackingFWHMCoeff) * m_AverageFWHM;

            if (trackedObject1.TargetNo != trackedObject2.TargetNo &&
                trackedObject1.LastKnownGoodPosition != null &&
                trackedObject2.LastKnownGoodPosition != null)
            {
                double deltaX = trackedObject1.LastKnownGoodPosition.X - trackedObject2.LastKnownGoodPosition.X;
                double deltaY = trackedObject1.LastKnownGoodPosition.Y - trackedObject2.LastKnownGoodPosition.Y;

                // Looking for two stars with the same distance and similar brighness
                for (int i = 0; i < stars.Count; i++)
                {
                    for (int j = 0; j < stars.Count; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }

                        double deltaXStars = stars[i].X - stars[j].X;
                        double deltaYStars = stars[i].Y - stars[j].Y;

                        if (Math.Abs(deltaX - deltaXStars) < TangraConfig.Settings.Special.LostTrackingPositionToleranceCoeff * PositionTolerance &&
                            Math.Abs(deltaY - deltaYStars) < TangraConfig.Settings.Special.LostTrackingPositionToleranceCoeff * PositionTolerance)
                        {
                            // Now compute PSFFits from the pixels
                            PSFFit fit1 = AstroImage.GetPSFFitForPeakPixel(pixels, stars[i], m_MinLocateSignal, minFWHM, maxFWHM);
                            PSFFit fit2 = AstroImage.GetPSFFitForPeakPixel(pixels, stars[j], m_MinLocateSignal, minFWHM, maxFWHM);

                            if (fit1 != null && fit2 != null)
                            {
                                AutoDiscoveredStars.Add(fit1);
                                AutoDiscoveredStars.Add(fit2);

                                deltaXStars = fit1.XCenter - fit2.XCenter;
                                deltaYStars = fit1.YCenter - fit2.YCenter;

                                if (Math.Abs(deltaX - deltaXStars) < PositionTolerance &&
                                    Math.Abs(deltaY - deltaYStars) < PositionTolerance)
                                {
                                    // Compute a certainty and add to the candidates dictionary
                                    CandidatePair pair = new CandidatePair();
                                    pair.Star1   = fit1;
                                    pair.Star2   = fit2;
                                    pair.Object1 = trackedObject1;
                                    pair.Object2 = trackedObject2;

                                    int[] BRIGTHNESS_MATCH_WEIGTH = new int[] { 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };

                                    int    weight = (trackedObject1.IsGuidingStar ? 2 : 0) + (trackedObject2.IsGuidingStar ? 2 : 0);
                                    double d1     = pair.Star1.IMax - pair.Star1.I0;
                                    double d2     = pair.Star2.IMax - pair.Star2.I0;

                                    d1 = pair.Object1.RefinedOrLastSignalLevel / d1;
                                    if (d1 > 1)
                                    {
                                        d1 = 1 / d1;
                                    }
                                    int d1i = Math.Min(10, (int)Math.Round((1 - d1) * 10));

                                    weight += BRIGTHNESS_MATCH_WEIGTH[d1i];

                                    d2 = pair.Object2.RefinedOrLastSignalLevel / d2;
                                    if (d2 > 1)
                                    {
                                        d2 = 1 / d2;
                                    }
                                    int d2i = Math.Min(10, (int)Math.Round((1 - d2) * 10));

                                    weight += BRIGTHNESS_MATCH_WEIGTH[d2i];

                                    double distanceFromLastKnownGoodPosition =
                                        ImagePixel.ComputeDistance(
                                            pair.Star1.XCenter, pair.Object1.LastKnownGoodPosition.XDouble,
                                            pair.Star1.YCenter, pair.Object1.LastKnownGoodPosition.YDouble);

                                    int closeToPrevCoeff        = LightCurveReductionContext.Instance.WindOrShaking ? 2 : 1;
                                    int closeToPrevPosWeighting = 0;
                                    if (distanceFromLastKnownGoodPosition < 4 * closeToPrevCoeff)
                                    {
                                        closeToPrevPosWeighting = 3;
                                    }
                                    else if (distanceFromLastKnownGoodPosition < 8 * closeToPrevCoeff)
                                    {
                                        closeToPrevPosWeighting = 2;
                                    }
                                    else if (distanceFromLastKnownGoodPosition < 16 * closeToPrevCoeff)
                                    {
                                        closeToPrevPosWeighting = 1;
                                    }
                                    else if (distanceFromLastKnownGoodPosition > 32 * closeToPrevCoeff)
                                    {
                                        closeToPrevPosWeighting = -1;
                                    }

                                    weight += closeToPrevPosWeighting;

                                    pair.Weight = weight;
                                    candidates.Add(pair);
                                }
                                else
                                {
                                    Trace.WriteLine("Pair with close distances has been rejected.");
                                }
                            }
                        }
                    }
                }
            }

            return(candidates);
        }