Esempio n. 1
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());
        }
Esempio n. 2
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);
        }
Esempio n. 3
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;
        }
Esempio n. 4
0
        internal frmAddOrEditSingleTarget(int objectId, TrackedObjectConfig selectedObject, LCStateMachine state, VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;

            m_AutocenteredApertureAvailable = true;

            Text = "Edit Object";

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

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

            ObjectToAdd = selectedObject;

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

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

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

            Initialize();

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

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

                PlotSingleTargetPixels();

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

            SetHeightAndType();

            if (selectedObject.TrackingType == TrackingType.GuidingStar)
            {
                SelectedObjectType = TrackingType.GuidingStar;
            }
            else if (selectedObject.TrackingType == TrackingType.OccultedStar)
            {
                SelectedObjectType = TrackingType.OccultedStar;
            }
        }
Esempio n. 5
0
        private bool GetFitInMatrix(ITrackedObjectPsfFit gaussian, ref int matirxSize, float preselectedAperture)
        {
            rbGuidingStar.Text = "Guiding/Comparison Star";
            m_IsBrightEnoughForAutoGuidingStar = false;

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

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

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

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

                int oldMatirxSize = matirxSize;

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

                PlotSingleTargetPixels();

                PlotGaussian();

                return(true);
            }
            finally
            {
                nudFitMatrixSize.ValueChanged += nudFitMatrixSize_ValueChanged;
            }
        }
Esempio n. 6
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);
                }
            }
        }
Esempio n. 7
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);
            }
        }
Esempio n. 8
0
        private void Initialise()
        {
            picTarget1Pixels.Image = new Bitmap(AREA_SIDE * MAGN_FACTOR, AREA_SIDE * MAGN_FACTOR, PixelFormat.Format24bppRgb);
            picTarget1PSF.Image    = new Bitmap(picTarget1PSF.Width, picTarget1PSF.Height);

            m_AllTargetColors = new Color[]
            {
                TangraConfig.Settings.Color.Target1,
                TangraConfig.Settings.Color.Target2,
                TangraConfig.Settings.Color.Target3,
                TangraConfig.Settings.Color.Target4
            };

            m_Color = m_AllTargetColors[m_ObjectId];
            if (m_ObjectId < 3 && !m_IsEdit)
            {
                m_Color2 = m_AllTargetColors[m_ObjectId + 1];
            }

            bool doubleModeDisabled = false;

            if (m_IsEdit && m_ObjectId2 <= 3)
            {
                m_Color2 = m_AllTargetColors[m_ObjectId2];
            }
            else if (m_ObjectId == 3 || m_ObjectId2 == 4)
            {
                doubleModeDisabled   = true;
                rbTwoObjects.Enabled = false;
            }

            m_Pen    = new Pen(m_Color);
            m_Brush  = new SolidBrush(m_Color);
            m_Pen2   = new Pen(m_Color2);
            m_Brush2 = new SolidBrush(m_Color2);

            m_ProcessingPixels = m_AstroImage.GetMeasurableAreaPixels(m_Center.X, m_Center.Y, 35);
            m_DisplayPixels    = m_AstroImage.GetMeasurableAreaDisplayBitmapPixels(m_Center.X, m_Center.Y, 35);

            ImagePixel newCenter = null;
            bool       autoDoubleObjectLocated = m_TryAutoDoubleFind && TryAutoLocateDoubleObject(out newCenter);

            if (autoDoubleObjectLocated)
            {
                int deltaX = (int)Math.Round(newCenter.XDouble - 18);
                int deltaY = (int)Math.Round(newCenter.YDouble - 18);
                m_X1Start         -= deltaX;
                m_Y1Start         -= deltaY;
                m_X2Start         -= deltaX;
                m_Y2Start         -= deltaY;
                m_Center           = new ImagePixel(newCenter.Brightness, m_Center.XDouble + newCenter.XDouble - 18, m_Center.YDouble + newCenter.YDouble - 18);
                m_ProcessingPixels = m_AstroImage.GetMeasurableAreaPixels(m_Center.X, m_Center.Y, 35);
                m_DisplayPixels    = m_AstroImage.GetMeasurableAreaDisplayBitmapPixels(m_Center.X, m_Center.Y, 35);

                m_AutoDoubleCenter  = new ImagePixel(m_Center);
                m_AutoDoubleX1Start = m_X1Start;
                m_AutoDoubleY1Start = m_Y1Start;
                m_AutoDoubleX2Start = m_X2Start;
                m_AutoDoubleY2Start = m_Y2Start;
            }

            bool occultedStartAlreadyPicked = m_State.MeasuringStars.Any(x => x.IsOcultedStar());

            if (m_IsEdit)
            {
                rbOcculted.Enabled  = m_EditingOccultedStar || !occultedStartAlreadyPicked;
                rbReference.Checked = !m_EditingOccultedStar;
                rbOcculted.Checked  = m_EditingOccultedStar;
            }
            else
            {
                if (occultedStartAlreadyPicked)
                {
                    rbOcculted.Enabled  = false;
                    rbReference.Checked = true;
                }
                else
                {
                    rbOcculted.Enabled = true;
                    rbOcculted.Checked = true;
                }
            }

            if (doubleModeDisabled || !autoDoubleObjectLocated)
            {
                rbOneObject.Checked = true;
            }

            UpdateStateControls();

            DrawCollorPanel();
            DrawCollorPanel2();

            CalculatePSF();
        }
Esempio n. 9
0
        public uint[,] measurer_GetImagePixelsCallback(int x, int y, int matrixSize)
        {
            AstroImage currentAstroImage = m_VideoController.GetCurrentAstroImage(false);

            return(currentAstroImage.GetMeasurableAreaPixels(x, y, matrixSize));
        }
Esempio n. 10
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));
        }