public GroupMeasurer(float fwhm, List <TrackedObjectConfig> trackedObjects, MeasurementsHelper measurementsHelper) { m_FWHM = fwhm; m_TrackedObjects = trackedObjects; GroupObjects(); }
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); } } }
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; }
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."); }
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)); }
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); }
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)); }
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; } }
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); } }
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); }
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)); }