Example #1
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");
            }
        }