Exemplo n.º 1
0
        public StarMagnitudeFit(
			AstroImage astroImage,
			int bitPix,
			List<double> intencities,
			List<double> magnitudes,
			List<double> colours,
			List<IStar> starNumbers,
			List<PSFFit> psfGaussians,
			List<double> profileFittedAmplitudes,
			List<bool> saturatedFlags,
			double a, double b, double c, float encodingGamma, TangraConfig.KnownCameraResponse reverseCameraResponse, int excludedStars,
			TangraConfig.PreProcessingFilter filter, double empericalFWHM, 
			TangraConfig.PhotometryReductionMethod photometryReductionMethod, 
			TangraConfig.BackgroundMethod photometryBackgroundMethod,
			TangraConfig.PsfQuadrature psfQuadrature,
			TangraConfig.PsfFittingMethod psfFittingMethod,
            MeasurementsHelper measurer,
            float? aperture)
        {
            m_CurrentAstroImage = astroImage;
            m_BitPix = bitPix;
            m_Intencities = intencities;
            m_Magnitudes = magnitudes;
            m_Colours = colours;
            m_Residuals = new List<double>();
            m_StarNumbers = starNumbers;
            m_PSFGaussians = psfGaussians;
            m_EncodingGamma = encodingGamma;
            m_ReverseCameraResponse = reverseCameraResponse;
            m_ExcludedStars = excludedStars;
            m_SaturatedFlags = saturatedFlags;
            m_ProfileFittedAmplitudes = profileFittedAmplitudes;

            m_Sigma = 0;
            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]);
                m_Residuals.Add(diff);

                m_Sigma += diff*diff;
            }
            m_Sigma = Math.Sqrt(m_Sigma / (m_Residuals.Count - 1));

            m_Filter = filter;
            m_EmpericalFWHM = empericalFWHM;
            m_PhotometryReductionMethod = photometryReductionMethod;
            m_PhotometryBackgroundMethod = photometryBackgroundMethod;
            m_PsfQuadrature = psfQuadrature;
            m_PsfFittingMethod = psfFittingMethod;

            m_A = a;
            m_B = b;
            m_C = c;

            m_Measurer = measurer.Clone();
            m_MeasurementAperture = aperture;

            m_Sigma = 0;
            m_MinRes = double.MaxValue;
            m_MaxRes = double.MinValue;
            m_MinMag = double.MaxValue;
            m_MaxMag = double.MinValue;
            for (int i = 0; i < m_Residuals.Count; i++)
            {
                double res = m_Residuals[i];

                m_Sigma += res * res;
                if (m_MinRes > res) m_MinRes = res;
                if (m_MaxRes < res) m_MaxRes = res;

                double mag = m_Magnitudes[i];
                if (m_MinMag > mag) m_MinMag = mag;
                if (m_MaxMag < mag) m_MaxMag = mag;
            }

            m_Sigma = Math.Sqrt(m_Sigma / m_Residuals.Count);
        }
Exemplo n.º 2
0
 public static void AddCameraResponseCorrection(TangraConfig.KnownCameraResponse cameraResponse, int[] responseParams)
 {
     PreProcessingAddCameraResponseCorrection((int)cameraResponse, responseParams);
 }
Exemplo n.º 3
0
        public StarMagnitudeFit(
            AstroImage astroImage,
            int bitPix,
            List <double> intencities,
            List <double> magnitudes,
            List <double> colours,
            List <IStar> starNumbers,
            List <PSFFit> psfGaussians,
            List <double> profileFittedAmplitudes,
            List <bool> saturatedFlags,
            double a, double b, double c, float encodingGamma, TangraConfig.KnownCameraResponse reverseCameraResponse, int excludedStars,
            TangraConfig.PreProcessingFilter filter, double empericalFWHM,
            TangraConfig.PhotometryReductionMethod photometryReductionMethod,
            TangraConfig.BackgroundMethod photometryBackgroundMethod,
            TangraConfig.PsfQuadrature psfQuadrature,
            TangraConfig.PsfFittingMethod psfFittingMethod,
            MeasurementsHelper measurer,
            float?aperture)
        {
            m_CurrentAstroImage       = astroImage;
            m_BitPix                  = bitPix;
            m_Intencities             = intencities;
            m_Magnitudes              = magnitudes;
            m_Colours                 = colours;
            m_Residuals               = new List <double>();
            m_StarNumbers             = starNumbers;
            m_PSFGaussians            = psfGaussians;
            m_EncodingGamma           = encodingGamma;
            m_ReverseCameraResponse   = reverseCameraResponse;
            m_ExcludedStars           = excludedStars;
            m_SaturatedFlags          = saturatedFlags;
            m_ProfileFittedAmplitudes = profileFittedAmplitudes;

            m_Sigma = 0;
            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]);
                m_Residuals.Add(diff);

                m_Sigma += diff * diff;
            }
            m_Sigma = Math.Sqrt(m_Sigma / (m_Residuals.Count - 1));

            m_Filter                     = filter;
            m_EmpericalFWHM              = empericalFWHM;
            m_PhotometryReductionMethod  = photometryReductionMethod;
            m_PhotometryBackgroundMethod = photometryBackgroundMethod;
            m_PsfQuadrature              = psfQuadrature;
            m_PsfFittingMethod           = psfFittingMethod;

            m_A = a;
            m_B = b;
            m_C = c;

            m_Measurer            = measurer.Clone();
            m_MeasurementAperture = aperture;

            m_Sigma  = 0;
            m_MinRes = double.MaxValue;
            m_MaxRes = double.MinValue;
            m_MinMag = double.MaxValue;
            m_MaxMag = double.MinValue;
            for (int i = 0; i < m_Residuals.Count; i++)
            {
                double res = m_Residuals[i];

                m_Sigma += res * res;
                if (m_MinRes > res)
                {
                    m_MinRes = res;
                }
                if (m_MaxRes < res)
                {
                    m_MaxRes = res;
                }

                double mag = m_Magnitudes[i];
                if (m_MinMag > mag)
                {
                    m_MinMag = mag;
                }
                if (m_MaxMag < mag)
                {
                    m_MaxMag = mag;
                }
            }

            m_Sigma = Math.Sqrt(m_Sigma / m_Residuals.Count);
        }
Exemplo n.º 4
0
        private bool LoadDarkFlatOrBiasFrameInternal(string title, ref float[,] pixels, ref float medianValue, ref float exposureSeconds, ref int imagesCombined)
        {
            string filter = "FITS Image 16 bit (*.fit;*.fits)|*.fit;*.fits";

            string fileName;

            if (m_VideoController.ShowOpenFileDialog(title, filter, out fileName) == DialogResult.OK &&
                File.Exists(fileName))
            {
                Type pixelDataType;
                int  snapshot = 1;
                bool hasNegativePixels;

                bool loaded = FITSHelper.LoadFloatingPointFitsFile(
                    fileName,
                    null,
                    out pixels,
                    out medianValue,
                    out pixelDataType,
                    out exposureSeconds,
                    out hasNegativePixels,
                    delegate(BasicHDU imageHDU)
                {
                    if (
                        imageHDU.Axes.Count() != 2 ||
                        imageHDU.Axes[0] != TangraContext.Current.FrameHeight ||
                        imageHDU.Axes[1] != TangraContext.Current.FrameWidth)
                    {
                        m_VideoController.ShowMessageBox(
                            "Selected image has a different frame size from the currently loaded video.", "Tangra",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);

                        return(false);
                    }

                    bool isFloatingPointImage = false;
                    Array dataArray           = (Array)imageHDU.Data.DataArray;
                    object entry = dataArray.GetValue(0);
                    if (entry is float[])
                    {
                        isFloatingPointImage = true;
                    }
                    else if (entry is Array)
                    {
                        isFloatingPointImage = ((Array)entry).GetValue(0) is float;
                    }

                    HeaderCard imagesCombinedCard = imageHDU.Header.FindCard("SNAPSHOT");
                    if (imagesCombinedCard != null)
                    {
                        int.TryParse(imagesCombinedCard.Value, out snapshot);
                    }


                    if (!isFloatingPointImage && imageHDU.BitPix != 16)
                    {
                        if (m_VideoController.ShowMessageBox(
                                "Selected image data type may not be compatible with the currently loaded video. Do you wish to continue?", "Tangra",
                                MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No)
                        {
                            return(false);
                        }
                    }

                    float usedEncodingGamma    = float.NaN;
                    string usedGammaString     = null;
                    HeaderCard tangraGammaCard = imageHDU.Header.FindCard("TANGAMMA");
                    if (tangraGammaCard != null &&
                        float.TryParse(tangraGammaCard.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out usedEncodingGamma))
                    {
                        usedGammaString = usedEncodingGamma.ToString("0.0000", CultureInfo.InvariantCulture);
                    }

                    string gammaUsageError = null;
                    string currGammaString = TangraConfig.Settings.Generic.ReverseGammaCorrection
                                                        ? TangraConfig.Settings.Photometry.EncodingGamma.ToString("0.0000", CultureInfo.InvariantCulture)
                                                        : null;
                    if (TangraConfig.Settings.Generic.ReverseGammaCorrection && currGammaString != null && usedGammaString == null)
                    {
                        gammaUsageError = string.Format("Selected image hasn't been Gamma corrected while the current video uses a gamma of {0}.", currGammaString);
                    }
                    else if (!TangraConfig.Settings.Generic.ReverseGammaCorrection && usedGammaString != null && currGammaString == null)
                    {
                        gammaUsageError = string.Format("Selected image has been corrected for Gamma of {0} while the current video doesn't use gamma correction.", usedGammaString);
                    }
                    else if (TangraConfig.Settings.Generic.ReverseGammaCorrection && !string.Equals(currGammaString, usedGammaString))
                    {
                        gammaUsageError = string.Format("Selected image has been corrected for Gamma of {0} while the current video uses a gamma of {1}.", usedGammaString, currGammaString);
                    }

                    if (gammaUsageError != null)
                    {
                        if (m_VideoController.ShowMessageBox(gammaUsageError + " Do you wish to continue?", "Tangra", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No)
                        {
                            return(false);
                        }
                    }

                    TangraConfig.KnownCameraResponse usedCameraResponse = TangraConfig.KnownCameraResponse.Undefined;
                    string usedCameraResponseString  = null;
                    int usedCameraResponseInt        = 0;
                    HeaderCard tangraCamResponseCard = imageHDU.Header.FindCard("TANCMRSP");
                    if (tangraCamResponseCard != null &&
                        int.TryParse(tangraCamResponseCard.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out usedCameraResponseInt))
                    {
                        usedCameraResponse       = (TangraConfig.KnownCameraResponse)usedCameraResponseInt;
                        usedCameraResponseString = usedCameraResponse.ToString();
                    }

                    string cameraResponseUsageError = null;
                    string currCameraResponseString = TangraConfig.Settings.Generic.ReverseCameraResponse
                                                        ? TangraConfig.Settings.Photometry.KnownCameraResponse.ToString()
                                                        : null;
                    if (TangraConfig.Settings.Generic.ReverseCameraResponse && currCameraResponseString != null && usedCameraResponseString == null)
                    {
                        cameraResponseUsageError = string.Format("Selected image hasn't been corrected for camera reponse while the current video uses a camera response correction for {0}.", currCameraResponseString);
                    }
                    else if (!TangraConfig.Settings.Generic.ReverseCameraResponse && usedCameraResponseString != null && currCameraResponseString == null)
                    {
                        cameraResponseUsageError = string.Format("Selected image has been corrected for camera response of {0} while the current video doesn't use camera response correction.", usedCameraResponseString);
                    }
                    else if (TangraConfig.Settings.Generic.ReverseCameraResponse && !string.Equals(currCameraResponseString, usedCameraResponseString))
                    {
                        cameraResponseUsageError = string.Format("Selected image has been corrected for camera reponse of {0} while the current video uses a camera response correction for {1}.", usedCameraResponseString, currCameraResponseString);
                    }

                    if (cameraResponseUsageError != null)
                    {
                        if (m_VideoController.ShowMessageBox(cameraResponseUsageError + " Do you wish to continue?", "Tangra", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No)
                        {
                            return(false);
                        }
                    }

                    return(true);
                });

                imagesCombined = snapshot;
                return(loaded);
            }

            return(false);
        }
Exemplo n.º 5
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));
        }