Esempio n. 1
0
        public GroupMeasurer(float fwhm, List <TrackedObjectConfig> trackedObjects, MeasurementsHelper measurementsHelper)
        {
            m_FWHM           = fwhm;
            m_TrackedObjects = trackedObjects;

            GroupObjects();
        }
Esempio n. 2
0
        private void ProcessSingleUnitSet(
            List <LCMeasurement> units,
            bool useLowPass,
            bool useLowPassDiff,
            MeasurementsHelper measurer)
        {
            for (int i = 0; i < units.Count; i++)
            {
                LCMeasurement reading          = units[i];
                IImagePixel[] groupCenters     = new IImagePixel[0];
                float[]       aperturesInGroup = new float[0];

                TrackedObjectConfig        objConfig     = Footer.TrackedObjects[reading.TargetNo];
                List <TrackedObjectConfig> gropedObjects = Footer.TrackedObjects.Where(x => objConfig.GroupId >= 0 && x.GroupId == objConfig.GroupId).ToList();
                if (gropedObjects.Count > 1)
                {
                    groupCenters     = new IImagePixel[gropedObjects.Count];
                    aperturesInGroup = new float[gropedObjects.Count];

                    for (int j = 0; j < gropedObjects.Count; j++)
                    {
                        LCMeasurement mea = units[Footer.TrackedObjects.IndexOf(gropedObjects[j])];
                        groupCenters[j]     = new ImagePixel(mea.X0, mea.Y0);
                        aperturesInGroup[j] = gropedObjects[j].ApertureInPixels;
                    }
                }

                units[i] = ProcessSingleUnit(
                    reading, useLowPass, useLowPassDiff,
                    Context.ReProcessFitAreas[i], Context.ReProcessApertures[i], Header.FixedApertureFlags[i],
                    measurer, groupCenters, aperturesInGroup);
            }
        }
        private void RecomputeData()
        {
            NumericUpDown[] targetApertures = new NumericUpDown[] { nudAperture1, nudAperture2, nudAperture3, nudAperture4 };
            NumericUpDown[] targetFitAreas  = new NumericUpDown[] { nudFitArea1, nudFitArea2, nudFitArea3, nudFitArea4 };
            PictureBox[]    psfBoxes        = new PictureBox[] { picTarget1PSF, picTarget2PSF, picTarget3PSF, picTarget4PSF };

            MeasurementsHelper measurer = new MeasurementsHelper(
                m_Context.BitPix,
                m_Context.BackgroundMethod,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(m_Context.BitPix, m_Context.MaxPixelValue));

            for (int i = 0; i < m_Header.ObjectCount; i++)
            {
                // Apply the selected filter, compute the PSF and then draw the data
                LCMeasurement reading = m_SelectedMeasurements[i];
                if (!LCMeasurement.IsEmpty(reading))
                {
                    LCMeasurement updatedReading = reading.Clone();

                    int x0Int = (int)Math.Round(reading.X0);
                    int y0Int = (int)Math.Round(reading.Y0);

                    updatedReading.PsfFit = new PSFFit(x0Int, y0Int);
                    updatedReading.PsfFit.FittingMethod = PSFFittingMethod.NonLinearFit;
                    int pixelDataWidth  = updatedReading.PixelData.GetLength(0);
                    int pixelDataHeight = updatedReading.PixelData.GetLength(1);
                    updatedReading.PsfFit.Fit(
                        updatedReading.PixelData,
                        m_Footer.TrackedObjects[updatedReading.TargetNo].PsfFitMatrixSize,
                        x0Int - updatedReading.PixelDataX0 + (pixelDataWidth / 2) + 1,
                        y0Int - updatedReading.PixelDataY0 + (pixelDataHeight / 2) + 1,
                        false);


                    int fitArea = (int)targetFitAreas[i].Value;
                    measurer.FindBestFit(
                        reading.X0, reading.Y0,
                        GetCurrentFilter(), reading.PixelData, m_Context.BitPix,
                        ref fitArea, m_Header.FixedApertureFlags[i]);

                    updatedReading.PsfFit = measurer.FoundBestPSFFit;

                    updatedReading.PixelData  = measurer.PixelData;
                    m_SelectedMeasurements[i] = updatedReading;

                    psfBoxes[reading.TargetNo].Visible = true;
                    PlotSingleGaussian(
                        psfBoxes[reading.TargetNo],
                        updatedReading,
                        m_AllBrushes,
                        (float)targetApertures[i].Value,
                        m_Footer.ReductionContext.BitPix);
                }
            }
        }
Esempio n. 4
0
        private void EnsureMeasurer(float positionTolerance)
        {
            uint saturatedValue = TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(m_VideoController.VideoBitPix, m_VideoController.VideoAav16NormVal);

            m_Measurer = new MeasurementsHelper(
                m_VideoController.VideoBitPix,
                m_BackgroundMethod,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                saturatedValue);

            m_Measurer.SetCoreProperties(
                TangraConfig.Settings.Photometry.AnnulusInnerRadius,
                TangraConfig.Settings.Photometry.AnnulusMinPixels,
                TangraConfig.PhotometrySettings.REJECTION_BACKGROUND_PIXELS_STD_DEV,
                positionTolerance);

            m_Measurer.GetImagePixelsCallback += m_Measurer_GetImagePixelsCallback;
        }
Esempio n. 5
0
        public void CheckLayoutColors(string sampleTypesList)
        {
            MeasurementsHelper helper = new MeasurementsHelper();
            var plateValues           = helper.GetPlateColors(repo.ProtocolAnalysisDesktop.PlateControlRslts);

            Report.Screenshot();

            var sampleIdsArray = sampleTypesList.Split(',');

            for (int i = 0; i < sampleIdsArray.Length; i++)
            {
                var sampleId = Convert.ToInt16(sampleIdsArray[i]);
                if (sampleId == 1)
                {
                    Validate.AreEqual(plateValues[i].ToArgb(), Color.White.ToArgb(), "Validate sample is white");
                }
                else if (sampleId == 2)
                {
                    Validate.AreEqual(plateValues[i].ToArgb(), Color.Red.ToArgb(), "Validate sample is red");
                }
                else if (sampleId == 3)
                {
                    Validate.AreEqual(plateValues[i].ToArgb(), Color.Yellow.ToArgb(), "Validate sample is yellow");
                }
                else if (sampleId == 4)
                {
                    Validate.AreEqual(plateValues[i].ToArgb(), Color.Aqua.ToArgb(), "Validate sample is aqua");
                }
                else if (sampleId == 5)
                {
                    Validate.AreEqual(plateValues[i].ToArgb(), Color.Lime.ToArgb(), "Validate sample is lime");
                }
                else
                {
                    Report.Failure("Wrong sample id parameter");
                }
            }

            for (int i = 0; i < plateValues.Count; i++)
            {
                var color = plateValues[i].ToArgb();
            }
        }
        public void checkFlaggedAmount(int expectedCount, Adapter adapter)
        {
            MeasurementsHelper helper = new MeasurementsHelper();
            var plateValues           = helper.GetFlaggedPlateValues(adapter);

            int crossedCount = 0;

            foreach (bool item in plateValues)
            {
                if (item.Equals(true))
                {
                    crossedCount++;
                }
                Report.Info(String.Format("element: " + item));
            }
            Report.Info(String.Format("Is crossed: {0}.", crossedCount));
            Report.Info(String.Format("Expected crossed count: {0}.", expectedCount));

            Validate.AreEqual(crossedCount, expectedCount, "On the plate control, flagged positions are as expected.");
        }
Esempio n. 7
0
 private NotMeasuredReasons MeasureObject(
     IImagePixel center,
     uint[,] data,
     uint[,] backgroundPixels,
     int bpp,
     MeasurementsHelper measurer,
     TangraConfig.PreProcessingFilter filter,
     TangraConfig.PhotometryReductionMethod reductionMethod,
     TangraConfig.PsfQuadrature psfQuadrature,
     TangraConfig.PsfFittingMethod psfFittngMethod,
     float aperture,
     double refinedFWHM,
     float refinedAverageFWHM,
     IMeasurableObject measurableObject,
     IImagePixel[] groupCenters,
     float[] aperturesInGroup,
     bool fullDisappearance
     )
 {
     return(measurer.MeasureObject(
                center, data, backgroundPixels, bpp, filter, reductionMethod, psfQuadrature, psfFittngMethod,
                aperture, refinedFWHM, refinedAverageFWHM, measurableObject, groupCenters, aperturesInGroup, fullDisappearance));
 }
Esempio n. 8
0
        private LCMeasurement ProcessSingleUnit(
            LCMeasurement reading,
            bool useLowPass,
            bool useLowPassDiff,
            int newFitMatrixSize,
            float newSignalAperture,
            bool fixedAperture,
            MeasurementsHelper measurer,
            IImagePixel[] groupCenters,
            float[] aperturesInGroup)
        {
            reading.ReProcessingPsfFitMatrixSize = newFitMatrixSize;

            TrackedObjectConfig objConfig = Footer.TrackedObjects[reading.TargetNo];
            ImagePixel          center    = new ImagePixel(reading.X0, reading.Y0);

            int areaSize = groupCenters != null && groupCenters.Length > 1 ? 35 : 17;

            if (Context.Filter != LightCurveContext.FilterType.NoFilter)
            {
                areaSize += 2;
            }

            uint[,] data = BitmapFilter.CutArrayEdges(reading.PixelData, (35 - areaSize) / 2);

            var filter = TangraConfig.PreProcessingFilter.NoFilter;

            if (useLowPassDiff)
            {
                filter = TangraConfig.PreProcessingFilter.LowPassDifferenceFilter;
            }
            else if (useLowPass)
            {
                filter = TangraConfig.PreProcessingFilter.LowPassFilter;
            }

            NotMeasuredReasons rv = ReduceLightCurveOperation.MeasureObject(
                center,
                data,
                reading.PixelData,
                Context.BitPix,
                measurer,
                filter,
                Context.SignalMethod,
                Context.PsfQuadratureMethod,
                Context.PsfFittingMethod,
                newSignalAperture,
                objConfig.RefinedFWHM,
                Footer.RefinedAverageFWHM,
                reading,
                groupCenters,
                aperturesInGroup,
                Footer.ReductionContext.FullDisappearance);

            reading.SetIsMeasured(rv);
            reading.TotalReading    = (uint)measurer.TotalReading;
            reading.TotalBackground = (uint)measurer.TotalBackground;
            reading.ApertureX       = measurer.XCenter;
            reading.ApertureY       = measurer.YCenter;
            reading.ApertureSize    = measurer.Aperture;

            return(reading);
        }
Esempio n. 9
0
        private void Worker(object state)
        {
            bool useLowPassDiff = Context.Filter == LightCurveContext.FilterType.LowPassDifference;
            bool useLowPass     = Context.Filter == LightCurveContext.FilterType.LowPass;

            LightCurveController.ReloadAllReadingsFromLcFile();

            MeasurementsHelper measurer = new MeasurementsHelper(
                Context.BitPix,
                Context.BackgroundMethod,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(Context.BitPix, Context.MaxPixelValue));

            measurer.SetCoreProperties(
                TangraConfig.Settings.Photometry.AnnulusInnerRadius,
                TangraConfig.Settings.Photometry.AnnulusMinPixels,
                TangraConfig.PhotometrySettings.REJECTION_BACKGROUND_PIXELS_STD_DEV,
                Header.PositionTolerance);

            m_EllapsedTime.Start();

            //measurer.GetImagePixelsCallback += new MeasurementsHelper.GetImagePixelsDelegate(measurer_GetImagePixelsCallback);

            int refreshCount = m_RefreshProgressEveryHowManyItems;


            List <LCMeasurement> readings0 = Context.AllReadings[0];
            List <LCMeasurement> readings1 = Header.ObjectCount > 1 ? Context.AllReadings[1] : null;
            List <LCMeasurement> readings2 = Header.ObjectCount > 2 ? Context.AllReadings[2] : null;
            List <LCMeasurement> readings3 = Header.ObjectCount > 3 ? Context.AllReadings[3] : null;

            int processedCount = 0;

            for (int i = 0; i < readings0.Count; i++)
            {
                List <LCMeasurement> units = new List <LCMeasurement>();
                units.Add(readings0[i]);
                if (Header.ObjectCount > 1)
                {
                    units.Add(readings1[i]);
                }
                if (Header.ObjectCount > 2)
                {
                    units.Add(readings2[i]);
                }
                if (Header.ObjectCount > 3)
                {
                    units.Add(readings3[i]);
                }

                if (m_CancelExecution)
                {
                    Invoke(new MethodInvoker(Cancelled));
                    return;
                }

                ProcessSingleUnitSet(units, useLowPass, useLowPassDiff, measurer);

                readings0[i] = units[0];
                if (Header.ObjectCount > 1)
                {
                    readings1[i] = units[1];
                }
                if (Header.ObjectCount > 2)
                {
                    readings2[i] = units[2];
                }
                if (Header.ObjectCount > 3)
                {
                    readings3[i] = units[3];
                }

                processedCount++;

                if (processedCount % refreshCount == 0)
                {
                    Invoke(new ProgressDelegate(OnProgress), 0, processedCount);
                    if (Header.ObjectCount > 1)
                    {
                        Invoke(new ProgressDelegate(OnProgress), 1, processedCount);
                    }
                    if (Header.ObjectCount > 2)
                    {
                        Invoke(new ProgressDelegate(OnProgress), 2, processedCount);
                    }
                    if (Header.ObjectCount > 3)
                    {
                        Invoke(new ProgressDelegate(OnProgress), 3, processedCount);
                    }
                }
            }

            Invoke(new MethodInvoker(Done));
        }
Esempio n. 10
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. 11
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. 12
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. 13
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);
        }
Esempio n. 14
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));
        }