internal NotMeasuredReasons DoOptimalExtractionPhotometry( PSFFit fit, uint[,] matrix, int x0Int, int y0Int, float x0, float y0, float aperture, int matrixSize, bool isFullyDisappearingOccultedStar, uint[,] backgroundArea, bool mayBeOcculted /* Some magic based on a pure guess */, double refinedFWHM, float bgAnnulusFactor) { // Proceed as with PSF Non linear, Then find the variance of the PSF fit and use a weight based on the residuals of the PSF fit // Signal[x, y] = PSF(x, y) + weight * Residual(x, y) double distance = ImagePixel.ComputeDistance(fit.XCenter, x0, fit.YCenter, y0); double tolerance = isFullyDisappearingOccultedStar ? m_TimesHigherPositionToleranceForFullyOccultedStars * m_PositionTolerance : m_PositionTolerance; float psfBackground = (float)fit.I0; // almost like aperture if (matrix.GetLength(0) != 17 && matrix.GetLength(0) != 35) { throw new ApplicationException("Measurement error. Correlation: AFP-101B"); } int side = matrix.GetLength(0); float halfSide = side * 1f / 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; double varR0Sq = fit.GetVariance(); varR0Sq = varR0Sq * varR0Sq * 2; double deltaX = fit.X0_Matrix - m_XCenter; double deltaY = fit.Y0_Matrix - m_YCenter; m_TotalReading = GetReading( m_Aperture, m_PixelData, side, side, m_XCenter, m_YCenter, delegate(int x, int y) { double videoPixel = m_PixelData[x, y]; double psfValue = fit.GetValue(x + deltaX, y + deltaY); if (fit.UsesBackgroundModel) { psfValue += fit.GetFittedBackgroundModelValue(x + deltaX, y + deltaY); } double residual = videoPixel - psfValue; double weight = Math.Exp(-residual * residual / varR0Sq); return(psfValue + residual * weight); }, ref m_TotalPixels); if (m_TotalPixels > 0) { if (m_BackgroundMethod == TangraConfig.BackgroundMethod.PSFBackground) { if (float.IsNaN(psfBackground)) { m_TotalBackground = 0; } else { m_TotalBackground = (uint)Math.Round(m_TotalPixels * psfBackground); } } else if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial) { if (!fit.UsesBackgroundModel) { throw new InvalidOperationException("3D-Polynomial was not applied correctly."); } m_TotalBackground = Integration.IntegrationOverCircularArea( (x, y) => fit.GetFittedBackgroundModelValue(x, y), m_Aperture); } else if (m_BackgroundMethod != TangraConfig.BackgroundMethod.PSFBackground) { int offset = (35 - fit.MatrixSize) / 2; 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-102B"); } if (!fit.IsSolved || // The PSF solution failed, mark the reading invalid (distance > tolerance && !mayBeOcculted) || // If this doesn't look like a full disappearance, then make the reading invalid (fit.FWHM < 0.75 * refinedFWHM || fit.FWHM > 1.25 * refinedFWHM) // The FWHM is too small or too large, make the reading invalid ) { return(!fit.IsSolved ? NotMeasuredReasons.MeasurementPSFFittingFailed : (distance > tolerance && !mayBeOcculted) ? NotMeasuredReasons.DistanceToleranceTooHighForNonFullDisappearingOccultedStar : NotMeasuredReasons.FWHMOutOfRange); } } else { // We can't do much here, but this should never happen (??) m_TotalBackground = 0; m_TotalReading = 0; return(NotMeasuredReasons.NoPixelsToMeasure); } return(NotMeasuredReasons.MeasuredSuccessfully); }