Beispiel #1
0
        public ImagePixel GetPSFFit(int x, int y, int fitMatrixSize, PSFFittingMethod method, out PSFFit psfFit)
        {
            psfFit = new PSFFit(x, y);
            psfFit.FittingMethod = method;

            int dimention = 2 * (fitMatrixSize / 2) + 1;

            uint[,] data = new uint[dimention, dimention];
            int halfWidth = dimention / 2;

#if ASTROMETRY_DEBUG
            Trace.Assert(2 * halfWidth + 1 == dimention);
#endif

            PixelAreaOperation2(x, y, halfWidth,
                                delegate(int x1, int y1, uint z)
            {
                data[x1 - x + halfWidth, y1 - y + halfWidth] = z;
            });

            psfFit.Fit(data);
            if (psfFit.IsSolved)
            {
                ImagePixel psfPixel = new ImagePixel((int)Math.Min(m_Pixelmap.MaxSignalValue, (uint)Math.Round(psfFit.IMax)), psfFit.XCenter, psfFit.YCenter);
                psfPixel.SignalNoise = psfFit.Certainty;
                return(psfPixel);
            }

            return(null);
        }
Beispiel #2
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 #3
0
        private void HandleHotPixelDefinitionClick(MouseEventArgs e)
        {
            var    pixels = frmFullSizePreview.CurrFrame.GetPixelsArea(e.X, e.Y, 35);
            PSFFit fit    = new PSFFit(e.X, e.Y);

            fit.Fit(pixels);
            if (fit.IsSolved && fit.Certainty > 1 && fit.IMax > frmFullSizePreview.CurrFrame.MaxSignalValue / 2.0)
            {
                var sample = frmFullSizePreview.CurrFrame.GetPixelsArea((int)Math.Round(fit.XCenter), (int)Math.Round(fit.YCenter), 7);
                HotPixelCorrector.RegisterHotPixelSample(sample, frmFullSizePreview.CurrFrame.Pixelmap.MaxSignalValue);

                m_ExpectHotPixelDefinition = false;
                FrameAdjustmentsPreview.Instance.ExpectHotPixelClick(false, true);
                pnlHotPixelControls.Enabled = true;

                HotPixelCorrector.LocateHotPixels(frmFullSizePreview.CurrFrame, Math.Max(0, tbDepth.Value));

                FrameAdjustmentsPreview.Instance.Update();
            }
            else
            {
                MessageBox.Show(
                    ParentForm,
                    "The location you clicked doesn't appear to contain a hot pixel. Please try again.\r\n\r\nIf necessary adjust the brightness and contrast of the image first.",
                    "Tangra",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Beispiel #4
0
        private void CalculateSingleObjectPSF()
        {
            m_ProcessingPixels = m_AstroImage.GetMeasurableAreaPixels(m_OriginalCenter.X, m_OriginalCenter.Y, 35);
            m_DisplayPixels    = m_AstroImage.GetMeasurableAreaDisplayBitmapPixels(m_OriginalCenter.X, m_OriginalCenter.Y, 35);

            var psfFit = new PSFFit(m_OriginalCenter.X, m_OriginalCenter.Y);

            psfFit.Fit(m_ProcessingPixels);

            if (psfFit.IsSolved)
            {
                m_Gaussian = psfFit;
                m_FWHM     = (float)m_Gaussian.FWHM;
                m_X0       = m_Gaussian.X0_Matrix;
                m_Y0       = m_Gaussian.Y0_Matrix;
                m_X0Center = (float)psfFit.XCenter;
                m_Y0Center = (float)psfFit.YCenter;

                if (m_Aperture == null)
                {
                    if (TangraConfig.Settings.Photometry.SignalApertureUnitDefault == TangraConfig.SignalApertureUnit.FWHM)
                    {
                        m_Aperture = (float)(m_Gaussian.FWHM * TangraConfig.Settings.Photometry.DefaultSignalAperture);
                    }
                    else
                    {
                        m_Aperture = (float)(TangraConfig.Settings.Photometry.DefaultSignalAperture);
                    }
                }
                else if (
                    TangraConfig.Settings.Photometry.SignalApertureUnitDefault == TangraConfig.SignalApertureUnit.FWHM &&
                    m_Aperture < (float)(psfFit.FWHM * TangraConfig.Settings.Photometry.DefaultSignalAperture))
                {
                    // When the default aperture size is in FWHM we always use the largest aperture so far
                    m_Aperture = (float)(psfFit.FWHM * TangraConfig.Settings.Photometry.DefaultSignalAperture);
                }

                nudAperture1.SetNUDValue(m_Aperture.Value);

                m_Aperture1      = null;
                m_Aperture2      = null;
                m_DoubleGaussian = null;
            }
        }
Beispiel #5
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);
        }
Beispiel #6
0
        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 #7
0
        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 #8
0
        private void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            TrackedStar.NewFrame();
            float expectedX;
            float expectedY;

            GetExpectedXY(out expectedX, out expectedY);

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

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

            gaussian.Fit(pixels, FIT_AREA);

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

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

                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, TrackedStar.TargetNo));
                TrackedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }
        }
Beispiel #9
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);
        }
Beispiel #10
0
        internal 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);
        }
Beispiel #11
0
        protected virtual void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            OccultedStar.NewFrame();
            m_NotCertain = false;
            float expectedX;
            float expectedY;

            GetExpectedXY(out expectedX, out expectedY);

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

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

            gaussian.Fit(pixels, 17);

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

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

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

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

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

                        m_NotCertain = !OccultedStar.IsLocated;

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

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

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

                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve first PSF", m_FrameNo, OccultedStar.TargetNo));
                OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }
        }
Beispiel #12
0
        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 #13
0
        public static List <PSFFit> GetStarsInArea(
            ref uint[,] data, int bpp, uint maxSignalValue, TangraConfig.PreProcessingFilter filter,
            List <PotentialStarStruct> allPotentialStars,
            List <PSFFit> allFoundStars,
            uint aboveNoiseLevelRequired, double minDistanceInPixels,
            bool useLPDFilter, Rectangle excludeArea, FilterPotentialStars filterCallback)
        {
            double minFWHM = TangraConfig.Settings.Special.StarFinderMinFWHM;
            double maxFWHM = TangraConfig.Settings.Special.StarFinderMaxFWHM;

            int STAR_MATRIX_FIT = TangraConfig.Settings.Special.StarFinderFitArea;

            Stopwatch sw = new Stopwatch();

            sw.Start();
            uint[,] lpdData;
            List <PotentialStarStruct> potentialStars = GetPeakPixelsInArea(
                data, out lpdData, bpp, maxSignalValue, aboveNoiseLevelRequired, minDistanceInPixels, useLPDFilter, excludeArea);

            if (filterCallback != null)
            {
                filterCallback(potentialStars);
            }
            sw.Stop();
            Trace.WriteLine(string.Format("GetPeakPixelsInArea: {0} sec", sw.Elapsed.TotalSeconds.ToString("0.00")));

            if (potentialStars.Count > 3)
            {
                // Only include the 3 brightest stars. The other ones cannot be stars
                potentialStars.Sort((x, y) => y.Z.CompareTo(x.Z));
                potentialStars = potentialStars.Take(3).ToList();
            }

            // Debugging purposes
            if (allPotentialStars != null)
            {
                allPotentialStars.AddRange(potentialStars);
            }

            uint[,] lpData = data;

            List <PSFFit> foundStars = new List <PSFFit>();

            double MIN_DISTANCE_OF_PEAK_PIXEL_FROM_CENTER = TangraConfig.Settings.Special.StarFinderMinDistanceOfPeakPixelFromCenter;

            sw.Reset();
            sw.Start();

            foreach (PotentialStarStruct starToTest in potentialStars)
            {
                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(lpData, 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)
                    {
                        // This object passes all tests to be furhter considered as a star
                        foundStars.Add(fit);
                    }
                }


                if (allFoundStars != null)
                {
                    allFoundStars.Add(fit);
                }
            }

            foundStars.Sort((f1, f2) => f1.IMax.CompareTo(f2.IMax));

            PSFFit[] testStars = foundStars.ToArray();
            for (int i = 0; i < testStars.Length; i++)
            {
                PSFFit fainterStar = testStars[i];
                for (int j = i + 1; j < testStars.Length; j++)
                {
                    PSFFit brighterStar = testStars[j];

                    if (fainterStar.UniqueId == brighterStar.UniqueId)
                    {
                        continue;
                    }

                    // If a the max of a fainter star is inside the fit of a brighter star
                    // then see if it is simply not a point of the other star

                    double dist = Math.Sqrt((fainterStar.XCenter - brighterStar.XCenter) * (fainterStar.XCenter - brighterStar.XCenter) + (fainterStar.YCenter - brighterStar.YCenter) * (fainterStar.YCenter - brighterStar.YCenter));
                    if (dist <= minDistanceInPixels)
                    {
                        if (foundStars.Contains(fainterStar))
                        {
                            foundStars.Remove(fainterStar);
                        }
                    }
                }
            }
            sw.Stop();
            Trace.WriteLine(string.Format("Doing PSFFitting: {0} sec", sw.Elapsed.TotalSeconds.ToString("0.00")));

            switch (filter)
            {
            case TangraConfig.PreProcessingFilter.NoFilter:
                break;

            case TangraConfig.PreProcessingFilter.LowPassFilter:
                data = lpData;
                break;

            case TangraConfig.PreProcessingFilter.LowPassDifferenceFilter:
                data = lpdData;
                break;
            }

            return(foundStars);
        }
Beispiel #14
0
        public NotMeasuredReasons MeasureObject(
            IImagePixel center,
            uint[,] data,
            uint[,] backgroundPixels,
            int bpp,
            TangraConfig.PreProcessingFilter filter,
            TangraConfig.PhotometryReductionMethod reductionMethod,
            TangraConfig.PsfQuadrature psfQuadrature,
            TangraConfig.PsfFittingMethod psfFittingMethod,
            float aperture,
            double refinedFWHM,
            float refinedAverageFWHM,
            IMeasurableObject measurableObject,
            IImagePixel[] objectsInGroup,
            float[] aperturesInGroup,
            bool fullDisappearance)
        {
            // NOTE: This is how the center of the pixel area passed in data and background arrays is determined
            // TODO: Pass the center as an argument
            int centerX = (int)Math.Round(center.XDouble);
            int centerY = (int)Math.Round(center.YDouble);

            float msrX0 = (float)center.XDouble;
            float msrY0 = (float)center.YDouble;

            float bgAnnulusFactor = 1;

            switch (filter)
            {
            case TangraConfig.PreProcessingFilter.LowPassFilter:
                data             = ImageFilters.LowPassFilter(data, bpp, true);
                backgroundPixels = ImageFilters.LowPassFilter(backgroundPixels, bpp, true);
                break;

            case TangraConfig.PreProcessingFilter.LowPassDifferenceFilter:
                data             = ImageFilters.LowPassDifferenceFilter(data, bpp, true);
                backgroundPixels = ImageFilters.LowPassDifferenceFilter(backgroundPixels, bpp, true);
                break;

            default:
                break;
            }

            float modelFWHM = float.NaN;

            if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
            {
                if (TangraConfig.Settings.Photometry.UseUserSpecifiedFWHM)
                {
                    modelFWHM = TangraConfig.Settings.Photometry.UserSpecifiedFWHM;
                }
                else
                {
                    modelFWHM = refinedAverageFWHM;
                }
            }

            DoublePSFFit             doublefit       = null;
            PSFFit                   fit             = null;
            IBackgroundModelProvider backgroundModel = null;

            // 1 - Fit a PSF to the current obejct
            if (objectsInGroup != null && objectsInGroup.Length == 2)
            {
                // 1A - When this is a star group
                int x1 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[0].XDouble - center.XDouble);
                int y1 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[0].YDouble - center.YDouble);
                int x2 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[1].XDouble - center.XDouble);
                int y2 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[1].YDouble - center.YDouble);
                doublefit = new DoublePSFFit(centerX, centerY);

                if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel &&
                    !float.IsNaN(modelFWHM))
                {
                    doublefit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                    doublefit.SetAveragedModelFWHM(modelFWHM);
                }

                doublefit.Fit(data, x1, y1, x2, y2);

                PSFFit star1 = doublefit.GetGaussian1();
                PSFFit star2 = doublefit.GetGaussian2();

                if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                {
                    var bg3dFit = new Background3DPolynomialFit();
                    bg3dFit.Fit(data, star1, star2);

                    doublefit.Fit(data, bg3dFit, x1, y1, x2, y2);

                    star1           = doublefit.GetGaussian1();
                    star2           = doublefit.GetGaussian2();
                    backgroundModel = bg3dFit;
                }

                double d1 = ImagePixel.ComputeDistance(measurableObject.Center.XDouble, doublefit.X1Center, measurableObject.Center.YDouble, doublefit.Y1Center);
                double d2 = ImagePixel.ComputeDistance(measurableObject.Center.XDouble, doublefit.X2Center, measurableObject.Center.YDouble, doublefit.Y2Center);

                fit = (d1 < d2) ? star1 : star2;

                if (reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry)
                {
                    // NOTE: If aperture photometry is used, we measure the double object in a single larger aperture centered at the middle
                    double alpha = Math.Atan((star2.YCenter - star1.YCenter) / (star2.XCenter - star1.XCenter));

                    float dx = (float)((star1.FWHM - star2.FWHM) * Math.Cos(alpha));
                    float dy = (float)((star1.FWHM - star2.FWHM) * Math.Sin(alpha));

                    msrX0 = (float)(star1.XCenter - star1.FWHM + star2.XCenter + star2.FWHM) / 2.0f - dx;
                    msrY0 = (float)(star1.YCenter - star1.FWHM + star2.YCenter + star2.FWHM) / 2.0f - dy;

                    aperture        = aperturesInGroup.Sum();
                    bgAnnulusFactor = 0.67f;
                }
            }
            else if (reductionMethod != TangraConfig.PhotometryReductionMethod.AperturePhotometry)
            {
                // 1B - When this is a single star
                fit = new PSFFit(centerX, centerY);

                if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel &&
                    !float.IsNaN(modelFWHM))
                {
                    fit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                    fit.SetAveragedModelFWHM(modelFWHM);
                }

                fit.Fit(data, measurableObject.PsfFittingMatrixSize);

                if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                {
                    // If 3D Poly Background is used then fit the background, and supply it to the PSF Fitting
                    var bg3dFit = new Background3DPolynomialFit();
                    bg3dFit.Fit(backgroundPixels, fit, null);

                    backgroundModel = bg3dFit;

                    if (psfFittingMethod != TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                    {
                        /* 3D Poly modelling works in a direct fit only with non-linear fitting */
                        fit.Fit(backgroundPixels, bg3dFit, measurableObject.PsfFittingMatrixSize);
                    }
                }
            }
            else if (
                reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry &&
                m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
            {
                // 1C - Single star with aperture photometry and 3D Poly Background
                var bg3dFit = new Background3DPolynomialFit();
                bg3dFit.Fit(backgroundPixels, (float)(centerX - msrX0 + 17), (float)(centerY - msrY0 + 17), 2 * aperture);

                backgroundModel = bg3dFit;
            }

            // 2 - Do the actual photometric measurements (signal and background) based on the selected methods
            if (reductionMethod == TangraConfig.PhotometryReductionMethod.PsfPhotometry)
            {
                // 2A - PSF Photometry
                if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.DirectNonLinearFit)
                {
                    return(DoNonLinearProfileFittingPhotometry(
                               fit,
                               data, centerX, centerY, msrX0, msrY0,
                               aperture,
                               measurableObject.PsfFittingMatrixSize,
                               psfQuadrature == TangraConfig.PsfQuadrature.NumericalInAperture,
                               measurableObject.IsOccultedStar && fullDisappearance,
                               backgroundPixels,
                               measurableObject.MayHaveDisappeared,
                               refinedFWHM,
                               bgAnnulusFactor));
                }
                else if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                {
                    return(DoLinearProfileFittingOfAveragedMoodelPhotometry(
                               fit,
                               data, centerX, centerY, msrX0, msrY0, modelFWHM,
                               aperture,
                               measurableObject.PsfFittingMatrixSize,
                               psfQuadrature == TangraConfig.PsfQuadrature.NumericalInAperture,
                               measurableObject.IsOccultedStar && fullDisappearance,
                               backgroundPixels,
                               measurableObject.MayHaveDisappeared,
                               bgAnnulusFactor, backgroundModel));
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else if (reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry)
            {
                return(DoAperturePhotometry(
                           data, centerX, centerY, msrX0, msrY0,
                           aperture,
                           measurableObject.PsfFittingMatrixSize,
                           backgroundPixels, bgAnnulusFactor, backgroundModel,
                           measurableObject.Center.X, measurableObject.Center.Y));
            }
            else if (reductionMethod == TangraConfig.PhotometryReductionMethod.OptimalExtraction)
            {
                return(DoOptimalExtractionPhotometry(
                           fit,
                           data, centerX, centerY, msrX0, msrY0,
                           aperture,
                           measurableObject.PsfFittingMatrixSize,
                           measurableObject.IsOccultedStar && fullDisappearance,
                           backgroundPixels,
                           measurableObject.MayHaveDisappeared,
                           refinedFWHM, bgAnnulusFactor));
            }
            else
            {
                throw new ArgumentOutOfRangeException("reductionMethod");
            }
        }
Beispiel #15
0
        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);
            }
        }
Beispiel #16
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            IsTrackedSuccessfully = false;

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

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

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

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

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

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

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

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

                            TrackedObjectLight trackedObject1;
                            TrackedObjectLight trackedObject2;

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

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

                                int tooSmallCertainties = 0;
                                int errors = 0;

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

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

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

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

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

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

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

            bool atLeastOneGroupLocated = false;

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

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

                bool containsFullyDisappearingTarget = trackedGroup.ContainsOcultedStar && m_IsFullDisappearance;

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

                if (!containsFullyDisappearingTarget)
                {
                    continue;
                }

                int    numReferences = 0;
                double x_double;
                double y_double;

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

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

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


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

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

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

                        fit.Fit(pixels);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            IsTrackedSuccessfully = atLeastOneGroupLocated;

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

            if (m_FailedGroupFits > 10)
            {
                Trace.WriteLine("ERR~10+");
            }
        }
Beispiel #17
0
        internal NotMeasuredReasons DoAperturePhotometry(
            uint[,] matrix, int x0Int, int y0Int, float x0, float y0, float aperture, int matrixSize,
            uint[,] backgroundArea, float bgAnnulusFactor,
            IBackgroundModelProvider backgroundModel,
            int centerX = 0, int centerY = 0)
        {
            if (matrix.GetLength(0) != 17 && matrix.GetLength(0) != 35)
            {
                throw new ApplicationException("Measurement error. Correlation: AFP-101");
            }

            int   side     = matrix.GetLength(0);
            float halfSide = 1.0f * side / 2f;

            m_HasSaturatedPixels = false;
            m_PSFBackground      = double.NaN;
            m_FoundBestPSFFit    = null;
            m_XCenter            = x0 - x0Int + halfSide;
            m_YCenter            = y0 - y0Int + halfSide;
            m_Aperture           = aperture;
            m_PixelData          = matrix;

            m_TotalPixels = 0;

            m_TotalReading = GetReading(
                m_Aperture,
                m_PixelData, side, side,
                m_XCenter, m_YCenter, null, ref m_TotalPixels, centerX - 8, centerY - 8);

            if (m_TotalPixels > 0)
            {
                if (m_BackgroundMethod == TangraConfig.BackgroundMethod.PSFBackground)
                {
                    PSFFit fit = new PSFFit(x0Int, y0Int);
                    fit.Fit(matrix, matrixSize);

                    if (!fit.IsSolved)
                    {
                        m_TotalBackground = 0;
                    }
                    else
                    {
                        m_TotalBackground = (uint)Math.Round(m_TotalPixels * (float)fit.I0);
                    }
                }
                else if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                {
                    int offset = (35 - side) / 2;
                    m_TotalBackground = Get3DPolynomialBackground(backgroundArea, m_Aperture, m_XCenter + offset, m_YCenter + offset, backgroundModel);
                }
                else if (m_BackgroundMethod != TangraConfig.BackgroundMethod.PSFBackground)
                {
                    int offset = (35 - side) / 2;

                    if (GetImagePixelsCallback != null)
                    {
                        backgroundArea = GetImagePixelsCallback(x0Int, y0Int, 71);
                        offset        += 17;
                    }
                    double bgFromAnnulus = GetBackground(backgroundArea, m_Aperture, m_XCenter + offset, m_YCenter + offset, bgAnnulusFactor);
                    m_TotalBackground = (uint)Math.Round(m_TotalPixels * (float)bgFromAnnulus);
                }
                else
                {
                    throw new ApplicationException("Measurement error. Correlation: AFP-102");
                }

                return(NotMeasuredReasons.MeasuredSuccessfully);
            }
            else
            {
                m_TotalBackground = 0;
                m_TotalReading    = 0;
                return(NotMeasuredReasons.NoPixelsToMeasure);
            }
        }
Beispiel #18
0
        private void FindBestFit(
            float x0, float y0,
            Filter filter, uint[,] matrix, int bpp,
            bool findBestMatrixSize, ref int matrixSize,
            bool fixedAperture, bool doCentroidFitForFixedAperture)
        {
            m_HasSaturatedPixels = false;
            m_PSFBackground      = double.NaN;
            m_FoundBestPSFFit    = null;
            m_PixelData          = null;

            if (filter == Filter.LPD)
            {
                m_PixelData = ImageFilters.LowPassDifferenceFilter(matrix, bpp);
            }
            else if (filter == Filter.LP)
            {
                m_PixelData = ImageFilters.LowPassFilter(matrix, bpp, false);
            }
            else
            {
                m_PixelData = matrix;
            }


            int x0i = (int)Math.Round(x0);
            int y0i = (int)Math.Round(y0);

            bool isSolved = false;

            Trace.Assert(m_PixelData.GetLength(0) == m_PixelData.GetLength(1));
            int halfDataSize = (int)Math.Ceiling(m_PixelData.GetLength(0) / 2.0);

            if (findBestMatrixSize)
            {
                if (!fixedAperture)
                {
                    PSFFit fit = new PSFFit(x0i, y0i);

                    #region Copy only the matix around the PFS Fit Area
                    do
                    {
                        int halfSize = matrixSize / 2;
                        uint[,] fitAreaMatrix = new uint[matrixSize, matrixSize];
                        int xx = 0, yy = 0;
                        for (int y = halfDataSize - halfSize; y <= halfDataSize + halfSize; y++)
                        {
                            xx = 0;
                            for (int x = halfDataSize - halfSize; x <= halfDataSize + halfSize; x++)
                            {
                                fitAreaMatrix[xx, yy] = m_PixelData[x, y];
                                xx++;
                            }
                            yy++;
                        }
                        fit.Fit(fitAreaMatrix);

                        m_XCenter = fit.X0_Matrix + halfDataSize - halfSize;
                        m_YCenter = fit.Y0_Matrix + halfDataSize - halfSize;

                        if (!findBestMatrixSize)
                        {
                            break;
                        }

                        if (Math.Sqrt((m_XCenter - halfDataSize) * (m_XCenter - halfDataSize) + (m_YCenter - halfDataSize) * (m_YCenter - halfDataSize)) <
                            BestMatrixSizeDistanceDifferenceTolerance)
                        {
                            break;
                        }

                        matrixSize -= 2;
                    } while (matrixSize > 0);

                    #endregion

                    isSolved = fit.IsSolved;
                    if (isSolved)
                    {
                        m_FoundBestPSFFit = fit;
                    }
                }
                else
                {
                    // Fixed Aperture
                    if (doCentroidFitForFixedAperture)
                    {
                        //"Do a 5x5 centroid cenetring, then get the new byte[,] around this new center, and then pass for measuring with a fixed aperture value");
                    }

                    m_XCenter = halfDataSize - 1;
                    m_YCenter = halfDataSize - 1;
                }
            }
            else
            {
                m_XCenter = halfDataSize - 1;
                m_YCenter = halfDataSize - 1;
            }

            m_TotalReading    = 0;
            m_TotalBackground = 0;
            m_PSFBackground   = 0;
        }
Beispiel #19
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));
        }
Beispiel #20
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 #21
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 #22
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            IsTrackedSuccessfully = false;

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

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

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

            bool atLeastOneObjectLocated = false;

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

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

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

                if (!needsRelativePositioning)
                {
                    continue;
                }

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

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

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

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

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

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


                        PSFFit fit = new PSFFit(x, y);

                        fit.Fit(pixels);


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

            IsTrackedSuccessfully = atLeastOneObjectLocated;
        }