Beispiel #1
0
        public void Test12BitData()
        {
            string DATA_SER =
                "EQAAABEAAABqAQAAkAEAABgBAACuAQAAnQEAAMgBAABfAQAAbQEAALYBAAAJAQAAcAEAACMBAAA5AQAAWAEAAFMBAADVAQAAkQEAAFABAAAbAQAAYgEAAFwBAABTAQAAMgEAAH8BAABSAQAA1AEAAGoBAAC6AQAAnAEAAN4BAACKAQAAswEAAKUBAABhAQAAvwEAAE0BAABLAQAA9QAAAIoBAABWAQAAkwEAAOwBAACCAQAAxQEAAJYBAAD1AQAApgEAAPcBAACuAQAAawEAAEgBAAAZAQAAXAEAAF4BAAD0AQAA1QEAAH8BAADbAQAARwEAALkBAAAhAgAASgIAAMMBAAANAgAApgEAAGgBAAAWAQAADQEAAB4BAABiAQAAagEAABsBAABYAQAAuQEAAPgBAACgAgAAdgIAAMsCAAAKAwAABQMAALkCAAD9AQAAdgEAAKABAABoAQAAdwEAAD4BAABqAQAAaAEAAKUBAAC2AQAApgEAAFgDAACAAwAA6gMAALgEAACbBAAAMwMAAMMCAAAEAgAAoAEAAJYBAAAyAQAAWQEAADkBAABbAQAAdgEAAHwBAACpAQAAewIAACcEAABiBQAATgYAAL8FAABIBAAAkgMAALkBAAClAQAA2wEAANgAAAB8AQAAfAEAAO8AAABEAQAAjgEAAPcBAABEAgAASAMAAE0FAABLBgAADwYAACoEAAArAwAAugEAAEsBAACfAQAAfwEAABgBAABSAQAALQEAABABAADVAQAAWwEAANIBAACOAgAA8AMAANIFAAAuBQAAUwMAACQCAADaAQAAogEAAKMBAABFAQAA/gAAALMBAABNAQAAAQEAAG4BAAAyAQAAcwEAAE8CAAC8AgAA0wMAANoDAADDAgAAGgIAAOUBAAC/AQAAUwEAADUBAACsAQAADwEAACEBAADxAAAAYgEAABABAACrAQAApgEAANcBAAD6AQAAwwIAABACAABtAQAAEAEAAF4BAAB0AQAAWAEAAA8BAABkAQAAzwAAAD4BAABuAQAABgEAAOsBAACjAQAA9wAAAJEBAABiAQAAOwEAAJcBAADxAAAAXwEAAIsBAACvAQAAQQEAAGoBAABFAQAAeQEAALMBAAApAQAAbgEAAFYBAABtAQAA5gEAAJEBAAAkAQAA3gAAADMBAACzAQAAEwEAABkBAABLAQAAQQEAAE0BAACvAAAAzAAAACkBAABeAQAADwEAAFMBAACIAQAAUgEAANIBAACjAQAAEwEAADgBAAD+AAAAMwEAAEEBAAAqAQAAPAEAAF8BAABnAQAAdwEAAGoBAAAAAQAAOAEAAKUBAAAMAQAArAAAAAEBAABlAQAA4wAAADMBAACiAQAAHgEAACkBAAAqAQAAGAEAACcBAAADAQAAlwEAAEIBAAA8AQAA3gAAADMBAACoAQAAegEAAGEBAAApAQAAlgEAAHwBAABZAQAAIQEAAGIBAADaAAAAPgEAADIBAAA/AQAAZwEAAIoBAAA5AQAAywAAAGoBAACBAQAAIQEAAEgBAAA8AQAA";

            uint[,] data = DATA_SER.FromBase64String();

            int width = data.GetLength(0);
            int height = data.GetLength(1);

            int MAX = 255;
            uint[,] data_8bit = new uint[width,height];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    data_8bit[x, y] = (uint)Math.Max(0, Math.Min(MAX, Math.Round(data[x, y] * MAX * 1.0f / 4095)));
                }
            }

            PSFFit.DataRange = PSFFittingDataRange.DataRange12Bit;
            var psfFit8bit = new PSFFit(100, 100);
            psfFit8bit.Fit(data_8bit);
            Console.WriteLine(string.Format("8Bit: ({0}, {1})", psfFit8bit.XCenter, psfFit8bit.YCenter));

            PSFFit.DataRange = PSFFittingDataRange.DataRange12Bit;
            var psfFit = new PSFFit(100, 100);
            psfFit.Fit(data);
            Console.WriteLine(string.Format("12Bit: ({0}, {1})", psfFit.XCenter, psfFit.YCenter));

            Assert.AreEqual(psfFit8bit.XCenter, psfFit.XCenter, 0.01);
            Assert.AreEqual(psfFit8bit.YCenter, psfFit.YCenter, 0.01);
        }
        public frmTargetPSFViewerForm(VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;
            m_PSFFit = null;
            cbMeaMethod.SelectedIndex = 0;
        }
 public ObjectClickEventArgs(ImagePixel pixel, PSFFit gausian, Point location, bool shiftHeld, bool ctrlHeld, MouseEventArgs mouseEventArgs)
 {
     ClickLocation = location;
     Pixel = pixel;
     Gausian = gausian;
     Shift = shiftHeld;
     Control = ctrlHeld;
     MouseEventArgs = mouseEventArgs;
 }
Beispiel #4
0
        public void SetTrackedObjectMatch(PSFFit psfFitMatched)
        {
            PSFFit = psfFitMatched;
            Center = new ImagePixel((int)psfFitMatched.IMax, psfFitMatched.XCenter, psfFitMatched.YCenter);
            IsLocated = true;
            NotMeasuredReasons = NotMeasuredReasons.TrackedSuccessfully;

            if (PSFFit != null && PSFFit.IsSolved)
            {
                LastKnownGoodPosition = new ImagePixel(Center.Brightness, Center.XDouble, Center.YDouble);
                LastKnownGoodPsfCertainty = PSFFit.Certainty;
            }
        }
        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 GenerateFrame(Pixelmap pixmap, List<IStar> stars, ModelConfig modelConfig)
        {
            var mea = new MeasurementsHelper(
                pixmap.BitPixCamera,
                TangraConfig.BackgroundMethod.BackgroundMedian,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(pixmap.BitPixCamera, pixmap.MaxSignalValue));

            float apertureSize = APERTURE;
            float annulusInnerRadius = (GAP + APERTURE) / APERTURE;
            int annulusMinPixels = (int)(Math.PI * (Math.Pow(ANNULUS + GAP + APERTURE, 2) - Math.Pow(GAP + APERTURE, 2)));

            mea.SetCoreProperties(annulusInnerRadius, annulusMinPixels, CorePhotometrySettings.Default.RejectionBackgroundPixelsStdDev, 2 /* TODO: This must be configurable */);

            var measurements = new Dictionary<IStar, double>();

            foreach (IStar star in stars)
            {
                double x, y;

                GetOnPlateCoordinates(star.RADeg, star.DEDeg, modelConfig, out x, out y);

                if (x < 0 || x > modelConfig.FrameWidth || y < 0 || y > modelConfig.FrameHeight)
                    continue;

                float starMag = GetStarMag(star, modelConfig.PhotometricFilter);
                float iMax = ModelStarAmplitude(star, starMag, modelConfig, pixmap.BitPixCamera, pixmap.MaxSignalValue);

                if (!float.IsNaN(iMax))
                {
                    VideoModelUtils.GenerateStar(pixmap, (float)x, (float)y, (float)modelConfig.FWHM, iMax, 0 /*Use Gaussian */);

                    if (modelConfig.CheckMagnitudes)
                    {
                        var image = new AstroImage(pixmap);
                        uint[,] data = image.GetMeasurableAreaPixels((int)x, (int)y, 17);
                        uint[,] backgroundPixels = image.GetMeasurableAreaPixels((int)x, (int)y, 35);

                        PSFFit fit = new PSFFit((int)x, (int)y);
                        fit.Fit(data);

                        var result = mea.MeasureObject(new ImagePixel(x, y), data, backgroundPixels, pixmap.BitPixCamera,
                            TangraConfig.PreProcessingFilter.NoFilter,
                            TangraConfig.PhotometryReductionMethod.AperturePhotometry, TangraConfig.PsfQuadrature.NumericalInAperture,
                            TangraConfig.PsfFittingMethod.DirectNonLinearFit,
                            apertureSize, modelConfig.FWHM, (float)modelConfig.FWHM,
                            new FakeIMeasuredObject(fit),
                            null, null,
                            false);

                        if (result == NotMeasuredReasons.TrackedSuccessfully && !mea.HasSaturatedPixels)
                        {
                            // Add value for fitting
                            measurements.Add(star, mea.TotalReading - mea.TotalBackground);
                        }
                    }
                }
            }

            if (modelConfig.CheckMagnitudes)
                CalculateGagnitudeFit(measurements, modelConfig.BVSlope);
        }
        private void PlotAperturePreview()
        {
            if (m_MeasurementContext.ObjectToMeasure != null)
            {
                float x0 = m_MeasurementContext.ObjectToMeasure.X0;
                float y0 = m_MeasurementContext.ObjectToMeasure.Y0;

                // x0 and y0 were measured on the first frame but we may have moved to a different frame due to positioning to the first frame of integration period
                // so we determine the position of the object on the current frame in order to draw the aperture nicely centered
                var fit = new PSFFit((int)x0, (int)y0);
                fit.Fit(m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaPixels((int)x0, (int)y0));

                if (fit.IsSolved)
                {
                    x0 = (float)fit.XCenter;
                    y0 = (float)fit.YCenter;
                }

                byte[,] bmpPixels = m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaDisplayBitmapPixels((int) x0, (int) y0, 85);

                Bitmap bmp = Pixelmap.ConstructBitmapFromBitmapPixels(bmpPixels, 85, 85);
                using (Graphics g = Graphics.FromImage(pboxAperturePreview.Image))
                {
                    g.DrawImage(bmp, 0, 0);
                    float xCenter = (x0 - (int)x0) + 42;
                    float yCenter = (y0 - (int)y0) + 42;

                    float radius = (float) nudAperture.Value;
                    g.DrawEllipse(Pens.YellowGreen, xCenter - radius, yCenter - radius, 2 * radius, 2 * radius);

                    radius = (float)(nudAperture.Value + nudGap.Value);
                    g.DrawEllipse(Pens.YellowGreen, xCenter - radius, yCenter - radius, 2 * radius, 2 * radius);

                    radius = (float)(nudAperture.Value + nudGap.Value + nudAnnulus.Value);
                    g.DrawEllipse(Pens.YellowGreen, xCenter - radius, yCenter - radius, 2 * radius, 2 * radius);

                    g.Save();
                }

                pboxAperturePreview.Invalidate();
            }
        }
Beispiel #8
0
        public static void PSFPhotometry(FitInfo astrometricFit, List<IStar> catalogueStars, AstroImage currentAstroImage, Rectangle osdRectToExclude, Rectangle rectToInclude, bool limitByInclusion)
        {
            StringBuilder output = new StringBuilder();

            foreach (PlateConstStarPair pair in astrometricFit.AllStarPairs)
            {
                uint[,] data = currentAstroImage.GetMeasurableAreaPixels(
                    (int)Math.Round(pair.x), (int)Math.Round(pair.y), 9);

                if (limitByInclusion && !rectToInclude.Contains((int)pair.x, (int)pair.y)) continue;
                if (!limitByInclusion && osdRectToExclude.Contains((int)pair.x, (int)pair.y)) continue;

                PSFFit gaussian = new PSFFit((int)Math.Round(pair.x), (int)Math.Round(pair.y));
                gaussian.Fit(data);
                if (gaussian.IsSolved)
                {
                    IStar star = catalogueStars.Find(s => s.StarNo == pair.StarNo);
                    if (star != null &&
                        !double.IsNaN(star.MagR))
                    {
                        output.AppendLine(string.Format("{0}, {1}, {2}, {3}, {4}", pair.StarNo, star.MagR, gaussian.R0, gaussian.IMax, gaussian.I0));
                    }
                }
            }

            File.WriteAllText(@"C:\PSF_Photo.csv", output.ToString());
        }
Beispiel #9
0
 internal void SetRefinedSignalLevel(PSFFit gaussian)
 {
     RefinedSignalLevel = (float)(gaussian.IMax - gaussian.I0);
 }
Beispiel #10
0
 public static double DistanceTo(this PSFFit psf1, PSFFit psf2)
 {
     return Math.Sqrt(Math.Pow(psf1.XCenter - psf2.XCenter, 2) + Math.Pow(psf1.YCenter - psf2.YCenter, 2));
 }
Beispiel #11
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;
                }
            }
        }
        public override void MouseClick(ObjectClickEventArgs e)
        {
            if (m_OperationState == SpectroscopyState.ChoosingStar && e.Gausian != null && e.Gausian.IsSolved && e.Gausian.Certainty > 0.2)
            {
                float bestAngle = m_SpectroscopyController.LocateSpectraAngle(e.Gausian);

                if (float.IsNaN(bestAngle))
                {
                    SelectedStar = new ImagePixel(e.Gausian.XCenter, e.Gausian.YCenter);
                    SelectedStarFWHM = e.Gausian.FWHM;
                    m_SelectedStarGaussian = e.Gausian;
                    MeasurementAreaWing = (int)(2 * Math.Ceiling(SelectedStarFWHM));
                    BackgroundAreaWing = MeasurementAreaWing;
                    BackgroundAreaGap = 5;

                    SelectedAnglePoint = Point.Empty;
                    m_ControlPanel.ClearSpectra();

                    m_OperationState = SpectroscopyState.ChoosingAngleManually;
                }
                else
                {
                    SelectedStar = new ImagePixel(e.Gausian.XCenter, e.Gausian.YCenter);
                    SelectedStarFWHM = e.Gausian.FWHM;
                    m_SelectedStarGaussian = e.Gausian;
                    MeasurementAreaWing = (int)(2 * Math.Ceiling(SelectedStarFWHM));
                    BackgroundAreaWing = MeasurementAreaWing;
                    BackgroundAreaGap = 5;

                    SetBestAngle(bestAngle);
                }

                m_VideoController.RedrawCurrentFrame(false, true);
            }
            else if (m_OperationState == SpectroscopyState.ChoosingAngleManually && SelectedStar != null)
            {
                double atanAgnle = 180 * Math.Atan((SelectedStar.YDouble - e.Pixel.YDouble)/(e.Pixel.XDouble - SelectedStar.XDouble)) / Math.PI;
                if (atanAgnle < 0) atanAgnle = 360 + atanAgnle;
                int roughAngle = (int) atanAgnle;
                float bestAngle = m_SpectroscopyController.LocateSpectraAngle(e.Gausian, roughAngle);
                if (!float.IsNaN(bestAngle))
                {
                    SetBestAngle(bestAngle);
                    m_VideoController.RedrawCurrentFrame(false, true);
                }
            }
        }
Beispiel #13
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);
            }
        }
Beispiel #14
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;
        }
Beispiel #15
0
        internal void SelectStar(PlateConstStarPair selectedPair, PSFFit psfFit)
        {
            if (selectedPair != null)
            {
                lblStarNo.Text = selectedPair.StarNo.ToString();
                lblRA.Text = AstroConvert.ToStringValue(selectedPair.RADeg / 15.0, "HH MM SS.TT");
                lblDE.Text = AstroConvert.ToStringValue(selectedPair.DEDeg, "+DD MM SS.T");
                lblX.Text = selectedPair.x.ToString("0.00");
                lblY.Text = selectedPair.y.ToString("0.00");
                lblResRA.Text = string.Format("{0}\"", selectedPair.FitInfo.ResidualRAArcSec.ToString("0.00"));
                lblResDE.Text = string.Format("{0}\"", selectedPair.FitInfo.ResidualDEArcSec.ToString("0.00"));

                m_SelectedPSF = psfFit;
            }
            else
            {
                m_SelectedPSF = null;
            }

            pnlSelectedStar.Visible = selectedPair != null;
        }
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
        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")));
                }
            }
        }
        private void frmRunMultiFrameSpectroscopy_Load(object sender, EventArgs e)
        {
            IImagePixel starCenter = m_VideoOperation.SelectedStar;
            m_SpectraReader = new SpectraReader(m_AstroImage, m_VideoOperation.SelectedStarBestAngle, 1);
            m_Spectra = m_SpectraReader.ReadSpectra((float)starCenter.XDouble, (float)starCenter.YDouble, (int)nudAreaWing.Value, (int)nudBackgroundWing.Value, (int)nudBackgroundGap.Value, PixelCombineMethod.Average);

            m_Mapper = new RotationMapper(m_AstroImage.Width, m_AstroImage.Height, m_VideoOperation.SelectedStarBestAngle);

            uint[,] pixels = m_AstroImage.GetMeasurableAreaPixels(starCenter.X, starCenter.Y, 35);
            m_ZeroOrderPsf = new PSFFit(starCenter.X, starCenter.Y);
            m_ZeroOrderPsf.Fit(pixels);
            m_Spectra.ZeroOrderFWHM = (float)m_ZeroOrderPsf.FWHM;

            PlotMeasurementAreas();
            PlotAlignTarget();

            nudDivisor.SetNUDValue((decimal)m_AstroImage.Pixelmap.MaxSignalValue);
            nudMultiplier.Value = 1024;
        }
Beispiel #19
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;
                }
            }
        }
        internal frmAddOrEditSingleTarget(int objectId, ImagePixel center, PSFFit gaussian, LCStateMachine state, VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;

            m_AutocenteredApertureAvailable = true;

            Text = "Add Object";
            btnAdd.Text = "Add";
            btnDontAdd.Text = "Don't Add";
            btnDelete.Visible = false;
            m_IsEdit = false;

            nudFitMatrixSize.Value = 11;
            nudFitMatrixSize.Maximum = 15;

            m_ObjectId = objectId;
            m_State = state;
            m_AstroImage = m_State.VideoOperation.m_StackedAstroImage;

            ObjectToAdd = new TrackedObjectConfig();

            m_Center = new ImagePixel(center);

            Initialize();

            if (rbOccultedStar.Enabled)
                SelectedObjectType = TrackingType.OccultedStar;
            else
                SelectedObjectType = TrackingType.GuidingStar;

            // Apply filtering to the processing pixels according to the configured default filter value
            int matirxSize = (int)nudFitMatrixSize.Value;

            GetFitInMatrix(gaussian, ref matirxSize);

            nudFitMatrixSize.Maximum = matirxSize;

            if (SelectedObjectType != TrackingType.OccultedStar)
                SetHeightAndType();
        }
Beispiel #21
0
        public static PSFFit GetPSFFitForPeakPixel(
			uint[,] data,
			PotentialStarStruct starToTest,
			float aboveNoiseLevelRequired,
			double minFWHM,
			double maxFWHM)
        {
            int STAR_MATRIX_FIT = TangraConfig.Settings.Special.StarFinderFitArea;
            double MIN_DISTANCE_OF_PEAK_PIXEL_FROM_CENTER = TangraConfig.Settings.Special.StarFinderMinDistanceOfPeakPixelFromCenter;

            PSFFit fit = new PSFFit(starToTest.X, starToTest.Y);
            int fitMatrix = (int)Math.Min(data.GetLength(0), STAR_MATRIX_FIT + 2);

            // Get a matrix with 1 pixel larger each way and set the border pixels to zero
            fit.Fit(data, fitMatrix, starToTest.X, starToTest.Y, true);

            if (fit.IsSolved)
            {
                double distanceFromCenter = ImagePixel.ComputeDistance(fit.X0_Matrix, fitMatrix / 2, fit.Y0_Matrix, fitMatrix / 2);

                if (fit.Certainty > 0 &&
                    fit.FWHM >= minFWHM &&
                    fit.FWHM <= maxFWHM &&
                    distanceFromCenter < MIN_DISTANCE_OF_PEAK_PIXEL_FROM_CENTER &&
                    fit.IMax > aboveNoiseLevelRequired)
                {
                    //not good for lost tracking allow higher FWHM

                    // This object passes all tests to be furhter considered as a star
                    return fit;
                }
            }

            return null;
        }
        private bool GetFitInMatrix(ITrackedObjectPsfFit gaussian, ref int matirxSize, float preselectedAperture)
        {
            rbGuidingStar.Text = "Guiding Star";
            m_IsBrightEnoughForAutoGuidingStar = false;

            if (m_Aperture == null)
            {
                if (gaussian != null && !double.IsNaN(gaussian.FWHM) && TangraConfig.Settings.Photometry.SignalApertureUnitDefault == TangraConfig.SignalApertureUnit.FWHM)
                    m_Aperture = (float)(gaussian.FWHM * TangraConfig.Settings.Photometry.DefaultSignalAperture);
                else
                    m_Aperture = (float)(TangraConfig.Settings.Photometry.DefaultSignalAperture);
            }
            else if (
                gaussian != null && !double.IsNaN(gaussian.FWHM) && TangraConfig.Settings.Photometry.SignalApertureUnitDefault == TangraConfig.SignalApertureUnit.FWHM &&
                m_Aperture < (float)(gaussian.FWHM * TangraConfig.Settings.Photometry.DefaultSignalAperture))
            {
                m_Aperture = (float) (gaussian.FWHM*TangraConfig.Settings.Photometry.DefaultSignalAperture);
            }

            nudFitMatrixSize.ValueChanged -= nudFitMatrixSize_ValueChanged;
            try
            {
                uint[,] autoStarsPixels = m_AstroImage.GetMeasurableAreaPixels(m_Center.X, m_Center.Y, 35);
                m_AutoStarsInLargerArea = StarFinder.GetStarsInArea(
                    ref autoStarsPixels,
                    m_AstroImage.Pixelmap.BitPixCamera,
                    m_AstroImage.Pixelmap.MaxSignalValue,
                    m_AstroImage.MedianNoise,
                    LightCurveReductionContext.Instance.DigitalFilter);

                m_ProcessingPixels = ImageFilters.CutArrayEdges(autoStarsPixels, 9);
                m_DisplayPixels = m_AstroImage.GetMeasurableAreaDisplayBitmapPixels(m_Center.X, m_Center.Y, 17);

                m_AutoStarsInArea = new List<PSFFit>();
                foreach (PSFFit autoStar in m_AutoStarsInLargerArea)
                {
                    if (autoStar.XCenter > 9 && autoStar.XCenter < 9 + 17 &&
                        autoStar.YCenter > 9 && autoStar.YCenter < 9 + 17)
                    {
                        // Don't change original star so use a clone
                        PSFFit clone = autoStar.Clone();
                        clone.SetNewFieldCenterFrom35PixMatrix(8, 8);
                        m_AutoStarsInArea.Add(clone);
                    }
                }

                int oldMatirxSize = matirxSize;

                if (m_AutoStarsInArea.Count == 0)
                {
                    rbGuidingStar.Text = "Guiding Star";

                    // There are no stars that are bright enough. Simply let the user do what they want, but still try to default to a sensible aperture size
                    MeasurementsHelper measurement = ReduceLightCurveOperation.DoConfiguredMeasurement(m_ProcessingPixels, m_Aperture.Value, m_AstroImage.Pixelmap.BitPixCamera, m_AstroImage.Pixelmap.MaxSignalValue, 3.0, ref matirxSize);

                    if (measurement.FoundBestPSFFit != null &&
                        measurement.FoundBestPSFFit.IsSolved &&
                        measurement.FoundBestPSFFit.Certainty > 0.1)
                    {
                        m_X0 = measurement.XCenter;
                        m_Y0 = measurement.YCenter;
                        m_FWHM = (float) measurement.FoundBestPSFFit.FWHM;
                    }
                    else
                    {
                        m_X0 = 8;
                        m_Y0 = 8;
                        m_FWHM = 6;
                    }

                    m_Gaussian = null;
                    nudFitMatrixSize.SetNUDValue(11);
                }
                else if (m_AutoStarsInArea.Count == 1)
                {
                    // There is exactly one good star found. Go and do a fit in a wider area
                    double bestFindTolerance = 3.0;

                    for (int i = 0; i < 2; i++)
                    {
                        MeasurementsHelper measurement = ReduceLightCurveOperation.DoConfiguredMeasurement(m_ProcessingPixels, m_Aperture.Value, m_AstroImage.Pixelmap.BitPixCamera, m_AstroImage.Pixelmap.MaxSignalValue, bestFindTolerance, ref matirxSize);
                        if (measurement != null && matirxSize != -1)
                        {
                            if (matirxSize < 5)
                            {
                                // Do a centroid in the full area, and get another matix centered at the centroid
                                ImagePixel centroid = new ImagePixel(m_Center.X, m_Center.Y);

                                m_ProcessingPixels = m_AstroImage.GetMeasurableAreaPixels(centroid);
                                m_DisplayPixels = m_AstroImage.GetMeasurableAreaDisplayBitmapPixels(centroid);

                                m_X0 = centroid.X;
                                m_Y0 = centroid.Y;
                                m_FWHM = 6;
                                m_Gaussian = null;

                                nudFitMatrixSize.SetNUDValue(11);
                            }
                            else
                            {
                                m_X0 = measurement.XCenter;
                                m_Y0 = measurement.YCenter;
                                if (measurement.FoundBestPSFFit != null)
                                {
                                    m_FWHM = (float)measurement.FoundBestPSFFit.FWHM;
                                    m_Gaussian = measurement.FoundBestPSFFit;
                                }
                                else
                                {
                                    m_FWHM = 6;
                                    m_Gaussian = null;
                                }
                                m_ProcessingPixels = measurement.PixelData;
                                nudFitMatrixSize.SetNUDValue(matirxSize);
                            }
                        }
                        else
                        {
                            matirxSize = oldMatirxSize;
                            return false;
                        }

                        if (m_Gaussian != null)
                        {
                            if (IsBrightEnoughtForGuidingStar())
                            {
                                rbGuidingStar.Text = "Guiding/Comparison Star";
                                m_IsBrightEnoughForAutoGuidingStar = true;
                            }

                            break;
                        }
                    }
                }
                else if (m_AutoStarsInArea.Count > 1)
                {
                    rbGuidingStar.Text = "Guiding Star";

                    // There are more stars found.
                    double xBest = m_Gaussian != null
                                      ? m_Gaussian.XCenter
                                      : m_IsEdit ? ObjectToAdd.ApertureMatrixX0
                                                 : 8.5;

                    double yBest = m_Gaussian != null
                                      ? m_Gaussian.YCenter
                                      : m_IsEdit ? ObjectToAdd.ApertureMatrixY0
                                                 : 8.5;

                    // by default use the one closest to the original location
                    PSFFit closestFit = m_AutoStarsInArea[0];
                    double closestDist = double.MaxValue;
                    foreach (PSFFit star in m_AutoStarsInArea)
                    {
                        double dist =
                            Math.Sqrt((star.XCenter - xBest) * (star.XCenter - xBest) +
                                      (star.YCenter - yBest) * (star.YCenter - yBest));
                        if (closestDist > dist)
                        {
                            closestDist = dist;
                            closestFit = star;
                        }
                    }

                    m_X0 = (float)closestFit.XCenter;
                    m_Y0 = (float)closestFit.YCenter;
                    m_FWHM = (float)closestFit.FWHM;
                    m_Gaussian = closestFit;

                    nudFitMatrixSize.SetNUDValue(m_IsEdit ? ObjectToAdd.PsfFitMatrixSize : closestFit.MatrixSize);
                }

                //if (m_Gaussian == null && gaussian.Certainty > 0.1 && ImagePixel.ComputeDistance(gaussian.X0_Matrix, 8, gaussian.Y0_Matrix, 8) < 3)
                //{
                //	// Id we failed to locate a bright enough autostar, but the default Gaussian is still certain enough and close enought to the center, we present it as a starting point
                //	m_X0 = (float)gaussian.X0_Matrix;
                //	m_Y0 = (float)gaussian.Y0_Matrix;
                //	m_FWHM = (float)gaussian.FWHM;
                //	m_Gaussian = gaussian;
                //}

                decimal appVal;
                if (float.IsNaN(preselectedAperture))
                {
                    if (float.IsNaN(m_Aperture.Value))
                    {
                        appVal = Convert.ToDecimal(TangraConfig.Settings.Photometry.DefaultSignalAperture);
                    }
                    else
                    {
                        appVal = Convert.ToDecimal(m_Aperture.Value);
                        if (nudAperture1.Maximum < appVal) nudAperture1.Maximum = appVal + 1;
                    }
                }
                else
                    appVal = (decimal)preselectedAperture;

                if ((float)appVal > m_Aperture) m_Aperture = (float)appVal;

                nudAperture1.SetNUDValue(Math.Round(appVal, 2));

                PlotSingleTargetPixels();

                PlotGaussian();

                return true;
            }
            finally
            {
                nudFitMatrixSize.ValueChanged += nudFitMatrixSize_ValueChanged;
            }
        }
Beispiel #23
0
        public static StarMagnitudeFit PerformFit(
			IAstrometryController astrometryController,
			IVideoController videoController,
			int bitPix,
            uint maxSignalValue,
			FitInfo astrometricFit,
			TangraConfig.PhotometryReductionMethod photometryReductionMethod,
			TangraConfig.PsfQuadrature psfQuadrature,
			TangraConfig.PsfFittingMethod psfFittingMethod,
			TangraConfig.BackgroundMethod photometryBackgroundMethod,
			TangraConfig.PreProcessingFilter filter,
			List<IStar> catalogueStars,
            Guid magnitudeBandId,
			float encodingGamma,
			TangraConfig.KnownCameraResponse reverseCameraResponse,
			float? aperture,
			float? annulusInnerRadius,
			int? annulusMinPixels,
			ref float empericalPSFR0)
        {
            uint saturatedValue = TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(bitPix, maxSignalValue);

            MeasurementsHelper measurer = new MeasurementsHelper(
                bitPix,
                photometryBackgroundMethod,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                saturatedValue);

            measurer.SetCoreProperties(
                annulusInnerRadius ?? TangraConfig.Settings.Photometry.AnnulusInnerRadius,
                annulusMinPixels ?? TangraConfig.Settings.Photometry.AnnulusMinPixels,
                CorePhotometrySettings.Default.RejectionBackgroundPixelsStdDev,
                2 /* TODO: This must be configurable */);

            var bgProvider = new BackgroundProvider(videoController);
            measurer.GetImagePixelsCallback += new MeasurementsHelper.GetImagePixelsDelegate(bgProvider.measurer_GetImagePixelsCallback);

            List<double> intencities = new List<double>();
            List<double> magnitudes = new List<double>();
            List<double> colours = new List<double>();
            List<double> residuals = new List<double>();
            List<bool> saturatedFlags = new List<bool>();
            List<IStar> stars = new List<IStar>();
            List<PSFFit> gaussians = new List<PSFFit>();

            List<MagFitRecord> fitRecords = new List<MagFitRecord>();

            AstroImage currentAstroImage = videoController.GetCurrentAstroImage(false);
            Rectangle osdRectToExclude = astrometryController.OSDRectToExclude;
            Rectangle rectToInclude = astrometryController.RectToInclude;
            bool limitByInclusion = astrometryController.LimitByInclusion;

            int matSize = CorePhotometrySettings.Default.MatrixSizeForCalibratedPhotometry;

            double a = double.NaN;
            double b = double.NaN;
            double c = double.NaN;
            int excludedStars = 0;
            double empericalFWHM = double.NaN;

            try
            {
                foreach (PlateConstStarPair pair in astrometricFit.AllStarPairs)
                {
                    if (limitByInclusion && !rectToInclude.Contains((int)pair.x, (int)pair.y)) continue;
                    if (!limitByInclusion && osdRectToExclude.Contains((int)pair.x, (int)pair.y)) continue;

                    IStar star = catalogueStars.Find(s => s.StarNo == pair.StarNo);
                    if (star == null || double.IsNaN(star.Mag) || star.Mag == 0) continue;

                    uint[,] data = currentAstroImage.GetMeasurableAreaPixels((int)pair.x, (int)pair.y, matSize);

                    PSFFit fit = new PSFFit((int)pair.x, (int)pair.y);
                    fit.Fit(data, PSF_FIT_AREA_SIZE);
                    if (!fit.IsSolved) continue;

                    MagFitRecord record = new MagFitRecord();
                    record.Star = star;
                    record.Pair = pair;
                    record.PsfFit = fit;
                    record.Saturation = IsSaturated(data, matSize, saturatedValue);

                    if (!EXCLUDE_SATURATED_STARS || !record.Saturation)
                        fitRecords.Add(record);
                }

                // We need the average R0 if it hasn't been determined yet
                if (float.IsNaN(empericalPSFR0))
                {
                    empericalPSFR0 = 0;
                    foreach (MagFitRecord rec in fitRecords)
                    {
                        empericalPSFR0 += (float)rec.PsfFit.R0;
                    }
                    empericalPSFR0 /= fitRecords.Count;
                }

                empericalFWHM = 2 * Math.Sqrt(Math.Log(2)) * empericalPSFR0;

                foreach (MagFitRecord record in fitRecords)
                {
                    ImagePixel center = new ImagePixel(255, record.Pair.x, record.Pair.y);
                    int areaSize = filter == TangraConfig.PreProcessingFilter.NoFilter ? 17 : 19;

                    int centerX = (int)Math.Round(center.XDouble);
                    int centerY = (int)Math.Round(center.YDouble);

                    uint[,] data = currentAstroImage.GetMeasurableAreaPixels(centerX, centerY, areaSize);
                    uint[,] backgroundPixels = currentAstroImage.GetMeasurableAreaPixels(centerX, centerY, 35);

                    measurer.MeasureObject(
                        center,
                        data,
                        backgroundPixels,
                        currentAstroImage.Pixelmap.BitPixCamera,
                        filter,
                        photometryReductionMethod,
                        psfQuadrature,
                        psfFittingMethod,
                        aperture != null ? aperture.Value : (float)Aperture(record.PsfFit.FWHM),
                        record.PsfFit.FWHM,
                        (float)empericalFWHM,
                        new FakeIMeasuredObject(record.PsfFit),
                        null,
                        null,
                        false);

                    double intensity = measurer.TotalReading - measurer.TotalBackground;
                    if (intensity > 0)
                    {
                        var mag = record.Star.GetMagnitudeForBand(magnitudeBandId);
                        var clr = record.Star.MagJ - record.Star.MagK;

                        if (!double.IsNaN(mag) && !double.IsNaN(clr) && !double.IsInfinity(mag) && !double.IsInfinity(clr))
                        {
                            intencities.Add(intensity);
                            magnitudes.Add(record.Star.GetMagnitudeForBand(magnitudeBandId));
                            colours.Add(record.Star.MagJ - record.Star.MagK);

                            gaussians.Add(record.PsfFit);
                            stars.Add(record.Star);
                            saturatedFlags.Add(measurer.HasSaturatedPixels || record.PsfFit.IMax >= measurer.SaturationValue);
                        }
                    }
                }

                // Remove stars with unusual PSF fit radii (once only)
                double sum = 0;
                for (int i = 0; i < gaussians.Count; i++)
                {
                    sum += gaussians[i].R0;
                }
                double averageR = sum / gaussians.Count;

                residuals.Clear();
                sum = 0;
                for (int i = 0; i < gaussians.Count; i++)
                {
                    residuals.Add(averageR - gaussians[i].R0);
                    sum += (averageR - gaussians[i].R0) * (averageR - gaussians[i].R0);
                }
                double stdDev = Math.Sqrt(sum) / gaussians.Count;

                if (EXCLUDE_BAD_RESIDUALS)
                {
                    for (int i = residuals.Count - 1; i >= 0; i--)
                    {
                        if (Math.Abs(residuals[i]) > 6 * stdDev)
                        {
                            intencities.RemoveAt(i);
                            magnitudes.RemoveAt(i);
                            colours.RemoveAt(i);
                            stars.RemoveAt(i);
                            gaussians.RemoveAt(i);
                            saturatedFlags.RemoveAt(i);
                        }
                    }
                }

                double maxResidual = Math.Max(0.1, TangraConfig.Settings.Photometry.MaxResidualStellarMags);

                for (int itter = 1; itter <= MAX_ITERR; itter++)
                {
                    residuals.Clear();

                    SafeMatrix A = new SafeMatrix(intencities.Count, 3);
                    SafeMatrix X = new SafeMatrix(intencities.Count, 1);

                    int idx = 0;
                    for (int i = 0; i < intencities.Count; i++)
                    {
                        A[idx, 0] = magnitudes[i];
                        A[idx, 1] = colours[i];
                        A[idx, 2] = 1;

                        X[idx, 0] = -2.5 * Math.Log10(intencities[i]);

                        idx++;
                    }

                    SafeMatrix a_T = A.Transpose();
                    SafeMatrix aa = a_T * A;
                    SafeMatrix aa_inv = aa.Inverse();
                    SafeMatrix bx = (aa_inv * a_T) * X;

                    double Ka = bx[0, 0];
                    double Kb = bx[1, 0];
                    double Kc = bx[2, 0];

                    // -2.5 * a * Log(Median-Intensity) = A * Mv + B * Mjk + C - b
                    // -2.5 * Log(Median-Intensity) = Ka * Mv + Kb * Mjk + Kc
                    // Mv = -2.5 * a * Log(Median-Intensity) - b * Mjk - c
                    a = 1 / Ka;
                    b = -Kb / Ka;
                    c = -Kc / Ka;

                    int starsExcludedThisTime = 0;

                    if (EXCLUDE_BAD_RESIDUALS)
                    {
                        List<int> indexesToRemove = new List<int>();
                        for (int i = 0; i < intencities.Count; i++)
                        {
                            double computed = a * -2.5 * Math.Log10(intencities[i]) + b * colours[i] + c;

                            double diff = Math.Abs(computed - magnitudes[i]);
                            if (itter < MAX_ITERR)
                            {
                                if (Math.Abs(diff) > maxResidual)
                                {
                                    indexesToRemove.Add(i);
                                }
                            }
                            else
                                residuals.Add(diff);
                        }

                        for (int i = indexesToRemove.Count - 1; i >= 0; i--)
                        {
                            int idxToRemove = indexesToRemove[i];
                            intencities.RemoveAt(idxToRemove);
                            magnitudes.RemoveAt(idxToRemove);
                            colours.RemoveAt(idxToRemove);
                            stars.RemoveAt(idxToRemove);
                            gaussians.RemoveAt(idxToRemove);
                            saturatedFlags.RemoveAt(idxToRemove);

                            excludedStars++;
                            starsExcludedThisTime++;
                        }
                    }

                    if (starsExcludedThisTime == 0)
                        break;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
            }

            return new StarMagnitudeFit(
                currentAstroImage,
                bitPix,
                intencities, magnitudes, colours, stars, gaussians, new List<double>(),
                saturatedFlags, a, b, c, encodingGamma, reverseCameraResponse, excludedStars, filter, empericalFWHM,
                photometryReductionMethod, photometryBackgroundMethod, psfQuadrature, psfFittingMethod, measurer, aperture);
        }
        internal frmAddOrEditSingleTarget(int objectId, TrackedObjectConfig selectedObject, LCStateMachine state, VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;

            m_AutocenteredApertureAvailable = true;

            Text = "Edit Object";

            btnAdd.Text = "Save";
            btnDontAdd.Text = "Cancel";
            btnDelete.Visible = true;
            m_IsEdit = true;

            m_ObjectId = objectId;
            m_State = state;
            m_AstroImage = m_State.VideoOperation.m_StackedAstroImage;

            ObjectToAdd = selectedObject;

            if (selectedObject.TrackingType != TrackingType.ComparisonStar)
                nudFitMatrixSize.SetNUDValue(selectedObject.PsfFitMatrixSize);

            m_Center = new ImagePixel(
                selectedObject.OriginalFieldCenterX,
                selectedObject.OriginalFieldCenterY);

            if (ObjectToAdd.PositionTolerance > 0)
                nudPositionTolerance.SetNUDValue((decimal)ObjectToAdd.PositionTolerance);

            Initialize();

            if (!selectedObject.IsWeakSignalObject && !selectedObject.IsFixedAperture)
            {
                int matrixSize = selectedObject.PsfFitMatrixSize;
                GetFitInMatrix(selectedObject.Gaussian, ref matrixSize, selectedObject.ApertureInPixels);
                selectedObject.PsfFitMatrixSize = matrixSize;
            }
            else
            {
                m_ProcessingPixels = m_AstroImage.GetMeasurableAreaPixels(m_Center);
                m_DisplayPixels = m_AstroImage.GetMeasurableAreaDisplayBitmapPixels(m_Center);

                m_FWHM = 6;
                m_Gaussian = null;
                m_X0 = selectedObject.ApertureMatrixX0;
                m_Y0 = selectedObject.ApertureMatrixY0;
                dx = selectedObject.ApertureDX;
                dy = selectedObject.ApertureDY;

                PlotSingleTargetPixels();

                nudAperture1.SetNUDValue((decimal) Math.Round(ObjectToAdd.ApertureInPixels, 2));
            }

            SetHeightAndType();

            if (selectedObject.TrackingType == TrackingType.GuidingStar)
                SelectedObjectType = TrackingType.GuidingStar;
            else if (selectedObject.TrackingType == TrackingType.OccultedStar)
                SelectedObjectType = TrackingType.OccultedStar;
        }
Beispiel #25
0
        public double GetIntencity(ImagePixel center, out bool isSaturated)
        {
            isSaturated = false;

            uint[,] data = m_CurrentAstroImage.GetMeasurableAreaPixels(center.X, center.Y, 17);

            PSFFit fit = new PSFFit(center.X, center.Y);
            fit.Fit(data, PSF_FIT_AREA_SIZE);
            if (!fit.IsSolved)
                return double.NaN;

            int areaSize = m_Filter == TangraConfig.PreProcessingFilter.NoFilter ? 17 : 19;

            int centerX = (int)Math.Round(center.XDouble);
            int centerY = (int)Math.Round(center.YDouble);

            data = m_CurrentAstroImage.GetMeasurableAreaPixels(centerX, centerY, areaSize);
            uint[,] backgroundPixels = m_CurrentAstroImage.GetMeasurableAreaPixels(centerX, centerY, 35);

            m_Measurer.MeasureObject(
                center,
                data,
                backgroundPixels,
                m_CurrentAstroImage.Pixelmap.BitPixCamera,
                m_Filter,
                m_PhotometryReductionMethod,
                m_PsfQuadrature,
                m_PsfFittingMethod,
                m_MeasurementAperture ?? (float)Aperture(fit.FWHM),
                fit.FWHM,
                (float)m_EmpericalFWHM,
                new FakeIMeasuredObject(fit),
                null, null,
                false);

            isSaturated = m_Measurer.HasSaturatedPixels;

            return m_Measurer.TotalReading - m_Measurer.TotalBackground;
        }
        private void picTarget1Pixels_Click(object sender, EventArgs e)
        {
            if (newStar != null)
            {
                m_Gaussian = newStar;
                m_X0 = (float)newStar.XCenter;
                m_Y0 = (float)newStar.YCenter;
                m_FWHM = (float)newStar.FWHM;

                nudFitMatrixSize.ValueChanged -= nudFitMatrixSize_ValueChanged;
                try
                {
                    nudFitMatrixSize.SetNUDValue(newStar.MatrixSize);
                }
                finally
                {
                    nudFitMatrixSize.ValueChanged += nudFitMatrixSize_ValueChanged;
                }
                PlotSingleTargetPixels();
                PlotGaussian();
            }
        }
Beispiel #27
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);
            }
        }
        private void picTarget1Pixels_MouseMove(object sender, MouseEventArgs e)
        {
            if (m_AutoStarsInArea != null &&
                m_AutoStarsInArea.Count > 1)
            {
                float x = e.X / 7.0f;
                float y = e.Y / 7.0f;

                PSFFit star = m_AutoStarsInArea.Find(
                    s =>
                    {
                        return Math.Abs(s.XCenter - x + 0.5f) < 2.0f && Math.Abs(s.YCenter - y + 0.5) < 2.0f;
                    }
                    );

                if (star != null &&
                    m_Gaussian.UniqueId != star.UniqueId)
                {
                    newStar = star;
                    Cursor = Cursors.Hand;
                }
                else
                    Cursor = Cursors.Default;
            }
        }
        private void InitStarAmplitudeModelling(ModelConfig modelConfig, float accuracy, int bitPix, uint maxSignalValue)
        {
            if (m_MagnitudeToPeakDict != null)
                return;

            m_MagnitudeToPeakDict = new Dictionary<double, int>();
            m_MagnitudeToPeakMags = new List<double>();
            m_MagnitudeToPeakPeaks = new List<int>();

            var mea = new MeasurementsHelper(
                bitPix,
                TangraConfig.BackgroundMethod.BackgroundMedian,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(bitPix, maxSignalValue));

            float apertureSize = APERTURE;
            float annulusInnerRadius = (GAP + APERTURE) / APERTURE;
            int annulusMinPixels = (int)(Math.PI * (Math.Pow(ANNULUS + GAP + APERTURE, 2) - Math.Pow(GAP + APERTURE, 2)));

            mea.SetCoreProperties(annulusInnerRadius, annulusMinPixels, CorePhotometrySettings.Default.RejectionBackgroundPixelsStdDev, 2 /* TODO: This must be configurable */);

            int peak = (int)(maxSignalValue - (modelConfig.NoiseMean + modelConfig.DarkFrameMean) * modelConfig.Integration);
            int TOTAL_STEPS = 100;
            double step = Math.Log10(peak) / TOTAL_STEPS;
            double zeroMag = double.NaN;
            for (int ii = 0; ii < TOTAL_STEPS; ii++)
            {
                int amplitude = (int)Math.Round(Math.Pow(10, Math.Log10(peak) - ii * step));
                Pixelmap pixmap = new Pixelmap(64, 64, bitPix, new uint[64 * 64], null, null);
                VideoModelUtils.GenerateStar(pixmap, 32, 32, (float)modelConfig.FWHM, amplitude, 0 /* Gaussian */);
                PSFFit fit = new PSFFit(32, 32);
                AstroImage img = new AstroImage(pixmap);
                uint[,] data = img.GetMeasurableAreaPixels(32, 32, 17);
                uint[,] backgroundPixels = img.GetMeasurableAreaPixels(32, 32, 35);

                fit.Fit(data);

                var result = mea.MeasureObject(new ImagePixel(32, 32), data, backgroundPixels, pixmap.BitPixCamera,
                    TangraConfig.PreProcessingFilter.NoFilter,
                    TangraConfig.PhotometryReductionMethod.AperturePhotometry, TangraConfig.PsfQuadrature.NumericalInAperture,
                    TangraConfig.PsfFittingMethod.DirectNonLinearFit,
                    apertureSize, modelConfig.FWHM, (float)modelConfig.FWHM,
                    new FakeIMeasuredObject(fit),
                    null, null,
                    false);

                if (result == NotMeasuredReasons.TrackedSuccessfully && !mea.HasSaturatedPixels)
                {
                    // Add value for fitting
                    double measurement = mea.TotalReading - mea.TotalBackground;
                    if (double.IsNaN(zeroMag))
                        zeroMag = modelConfig.BrighestUnsaturatedStarMag + 2.5 * Math.Log10(measurement);
                    double magnitude = -2.5 * Math.Log10(measurement) + zeroMag;

                    m_MagnitudeToPeakDict[magnitude] = amplitude;
                    m_MagnitudeToPeakMags.Add(magnitude);
                    m_MagnitudeToPeakPeaks.Add(amplitude);
                }
            }
        }
Beispiel #30
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);
        }