示例#1
0
        public GroupMeasurer(float fwhm, List<TrackedObjectConfig> trackedObjects, MeasurementsHelper measurementsHelper)
        {
            m_FWHM = fwhm;
            m_TrackedObjects = trackedObjects;

            GroupObjects();
        }
示例#2
0
        public MeasurementsHelper Clone()
        {
            MeasurementsHelper clone = new MeasurementsHelper(m_BitPix, m_BackgroundMethod, m_SubPixelSquare, m_SaturationValue);

            clone.m_InnerRadiusOfBackgroundApertureInSignalApertures = this.m_InnerRadiusOfBackgroundApertureInSignalApertures;
            clone.m_NumberOfPixelsInBackgroundAperture  = this.m_NumberOfPixelsInBackgroundAperture;
            clone.m_RejectionBackgoundPixelsStdDevCoeff = this.m_RejectionBackgoundPixelsStdDevCoeff;

            clone.m_PositionTolerance = this.m_PositionTolerance;

            return(clone);
        }
        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);
                }
            }
        }
        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);
        }
示例#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);
        }
示例#6
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);
        }
        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);
                }
            }
        }
        private void MeasureTrackedObject2(
			ITrackedObject trackedObject,
			MeasurementsHelper measurer,
			TangraConfig.PreProcessingFilter filter,
			bool synchronise,
			List<ITrackedObject> objectsInGroup,
			float refinedFWHM,
			float averageFWHM)
        {
            IImagePixel center = trackedObject.Center;
            int areaSize = 17;
            if ((objectsInGroup != null && objectsInGroup.Count > 1) || LightCurveReductionContext.Instance.NoiseMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                // for double PSF fits and/or 3d polynomial background fits we need the largest area
                areaSize = 35;

            IImagePixel[] groupCenters = new IImagePixel[0];
            float[] aperturesInGroup = new float[0];

            if (objectsInGroup != null && objectsInGroup.Count > 1)
            {
                groupCenters = new IImagePixel[objectsInGroup.Count];
                aperturesInGroup = new float[objectsInGroup.Count];

                for (int i = 0; i < objectsInGroup.Count; i++)
                {
                    groupCenters[i] = objectsInGroup[i].Center;
                    aperturesInGroup[i] = objectsInGroup[i].OriginalObject.ApertureInPixels;
                }
            }

            int areaDigitalFilterEdge = 0;
            if (LightCurveReductionContext.Instance.DigitalFilter != TangraConfig.PreProcessingFilter.NoFilter)
                areaDigitalFilterEdge = 2; // The extra 2 pixels will be cut after the filter is applied before the measurement

            int centerX = (int)Math.Round(center.XDouble);
            int centerY = (int)Math.Round(center.YDouble);

            uint[,] data = m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaPixels(centerX, centerY, areaSize + areaDigitalFilterEdge);
            uint[,] backgroundPixels = m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaPixels(centerX, centerY, 35 + areaDigitalFilterEdge);

            float msrX0 = (float)trackedObject.Center.XDouble;
            float msrY0 = (float)trackedObject.Center.YDouble;

            var measuredObject = new LCMeasurement()
            {
                CurrFrameNo = (uint) m_CurrFrameNo,
                CurrFileName = m_CurrFileName,
                TargetNo = (byte) trackedObject.TargetNo,
                X0 = msrX0,
                Y0 = msrY0,
                PixelDataX0 = centerX,
                PixelDataY0 = centerY,
                OSDTimeStamp = m_OCRedTimeStamp,
                FlagsDWORD = trackedObject.GetTrackingFlags()
            };

            IMeasurableObject measurableObject = (IMeasurableObject)trackedObject;

            NotMeasuredReasons rv = MeasureObject(
                center,
                data,
                backgroundPixels,
                m_VideoController.VideoBitPix,
                measurer,
                filter,
                LightCurveReductionContext.Instance.ReductionMethod,
                LightCurveReductionContext.Instance.PsfQuadratureMethod,
                TangraConfig.Settings.Photometry.PsfFittingMethod,
                trackedObject.OriginalObject.ApertureInPixels,
                refinedFWHM,
                averageFWHM,
                measurableObject,
                groupCenters,
                aperturesInGroup,
                LightCurveReductionContext.Instance.FullDisappearance);

            measuredObject.SetIsMeasured(rv);

            uint[,] pixelsToSave = trackedObject.IsOffScreen
                                       ? new uint[35, 35]
                                       // As the background may have been pre-processed for measuring, we need to take another copy for saving in the file
                                       : m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaPixels(centerX, centerY, 35);

            bool lockTaken = false;

            if (synchronise)
                m_WriterLock.TryEnter(ref lockTaken);

            try
            {
                uint flags = trackedObject.GetTrackingFlags();

                measuredObject.TotalReading = (uint)Math.Round(measurer.TotalReading);
                measuredObject.TotalBackground = (uint)Math.Round(measurer.TotalBackground);
                measuredObject.PixelData = pixelsToSave; /* save the original non filtered data */
                measuredObject.FlagsDWORD |= flags;
                measuredObject.ApertureX = measurer.XCenter;
                measuredObject.ApertureY = measurer.YCenter;
                measuredObject.ApertureSize = measurer.Aperture;

                m_LastTotalReading[trackedObject.TargetNo] = measuredObject.TotalReading;
                m_LastTotalBackground[trackedObject.TargetNo] = measuredObject.TotalBackground;
                m_LastApertureX[trackedObject.TargetNo] = measuredObject.ApertureX;
                m_LastApertureY[trackedObject.TargetNo] = measuredObject.ApertureY;
                m_LastApertureSize[trackedObject.TargetNo] = measuredObject.ApertureSize;
                m_LastOCRedTimeStamp[trackedObject.TargetNo] = measuredObject.OSDTimeStamp;

                LCFile.SaveOnTheFlyMeasurement(measuredObject);
            }
            finally
            {
                if (synchronise && lockTaken)
                    m_WriterLock.Exit();
            }
        }
        public static MeasurementsHelper DoConfiguredMeasurement(uint[,] matrix, float aperture, int bitPixCamera, uint maxSignalValue, double bestFindTolerance, ref int matrixSize)
        {
            var measurer = new MeasurementsHelper(
                            bitPixCamera,
                            TangraConfig.BackgroundMethod.BackgroundMedian /* We always use Background Median for configuration measurements. */,
                            TangraConfig.Settings.Photometry.SubPixelSquareSize,
                            TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(bitPixCamera, maxSignalValue));

            measurer.SetCoreProperties(
                    TangraConfig.Settings.Photometry.AnnulusInnerRadius,
                    TangraConfig.Settings.Photometry.AnnulusMinPixels,
                    TangraConfig.Settings.Special.RejectionBackgroundPixelsStdDev,
                    4.0f);

            measurer.BestMatrixSizeDistanceDifferenceTolerance = bestFindTolerance;

            MeasurementsHelper.Filter measurementFilter = MeasurementsHelper.Filter.None;

            switch (LightCurveReductionContext.Instance.DigitalFilter)
            {
                case TangraConfig.PreProcessingFilter.NoFilter:
                    measurementFilter = MeasurementsHelper.Filter.None;
                    break;

                case TangraConfig.PreProcessingFilter.LowPassFilter:
                    measurementFilter = MeasurementsHelper.Filter.LP;
                    break;

                case TangraConfig.PreProcessingFilter.LowPassDifferenceFilter:
                    measurementFilter = MeasurementsHelper.Filter.LPD;
                    break;
            }

            // This will also find the best PSFFit
            measurer.FindBestFit(9, 9, measurementFilter, matrix, bitPixCamera, ref matrixSize, false);

            return measurer;
        }
        private void EnsureMeasurer(float positionTolerance)
        {
            m_Measurer = new MeasurementsHelper(
                                m_VideoController.VideoBitPix,
                                LightCurveReductionContext.Instance.NoiseMethod,
                                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                                TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(m_VideoController.VideoBitPix, m_VideoController.VideoAav16NormVal));

            m_Measurer.SetCoreProperties(
                TangraConfig.Settings.Photometry.AnnulusInnerRadius,
                TangraConfig.Settings.Photometry.AnnulusMinPixels,
                TangraConfig.PhotometrySettings.REJECTION_BACKGROUND_PIXELS_STD_DEV,
                positionTolerance);
        }
        internal static 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);
        }
示例#12
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));
        }
示例#13
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);
            }
        }
示例#14
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;
        }
示例#15
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;
        }
示例#16
0
        public MeasurementsHelper Clone()
        {
            MeasurementsHelper clone = new MeasurementsHelper(m_BitPix, m_BackgroundMethod, m_SubPixelSquare, m_SaturationValue);
            clone.m_InnerRadiusOfBackgroundApertureInSignalApertures = this.m_InnerRadiusOfBackgroundApertureInSignalApertures;
            clone.m_NumberOfPixelsInBackgroundAperture = this.m_NumberOfPixelsInBackgroundAperture;
            clone.m_RejectionBackgoundPixelsStdDevCoeff = this.m_RejectionBackgoundPixelsStdDevCoeff;

            clone.m_PositionTolerance = this.m_PositionTolerance;

            return clone;
        }