public PlateCalibration( CalibrationContext context, IAstrometrySettings astrometrySettings, IAstrometryController astrometryController) { m_Context = context; m_AstrometrySettings = astrometrySettings; m_AstrometryController = astrometryController; }
public PyramidStarsDensityDistributor(List <IStar> stars, AstroPlate image, IAstrometrySettings settings, double ra0Deg, double de0Deg) { m_Stars = stars; m_Image = image; m_XAreaSideDeg = image.GetDistanceInArcSec(0, image.CenterYImage, image.CenterXImage, image.CenterYImage) / 3600.0; m_YAreaSideDeg = image.GetDistanceInArcSec(image.CenterXImage, 0, image.CenterXImage, image.CenterYImage) / 3600.0; m_RA0Deg = ra0Deg; m_DE0Deg = de0Deg; MAX_STARS_IN_AREA = settings.DistributionZoneStars; }
public static void Init(IAstrometrySettings fitSettings, double pyramidMinMag, double pyramidMaxMag, double astrometryMinMag, double astrometryMaxMag) { lock (s_SyncLock) { ResetInternal(); FitSettings = fitSettings; PyramidMinMag = pyramidMinMag; PyramidMaxMag = pyramidMaxMag; AstrometryMinMag = astrometryMinMag; AstrometryMaxMag = astrometryMaxMag; } }
public DistanceBasedAstrometrySolver( IOperationNotifier operationNotifier, AstroPlate plateConfig, IAstrometrySettings fitSettings, List <IStar> celestialStars, double ra0Deg, double de0Deg, bool determineAutoLimitMagnitude) { m_PlateConfig = plateConfig; m_FitSettings = fitSettings; m_CelestialStars = celestialStars; m_RA0Deg = ra0Deg; m_DE0Deg = de0Deg; m_DetermineAutoLimitMagnitude = determineAutoLimitMagnitude; m_OperationNotifier = operationNotifier; Context = new DistanceBasedContext(operationNotifier, plateConfig, fitSettings, fitSettings.MaxResidualInPixels, m_AstrometryMinMag, m_AstrometryMaxMag); }
public LeastSquareFittedAstrometry SolveWithLinearRegression(IAstrometrySettings settings, out LeastSquareFittedAstrometry firstFit) { double maxResidual = m_PlateConfig.GetDistanceInArcSec( m_PlateConfig.CenterXImage, m_PlateConfig.CenterYImage, m_PlateConfig.CenterXImage + settings.MaxResidualInPixels, m_PlateConfig.CenterYImage + settings.MaxResidualInPixels); if (m_Pairs.Count < CorePyramidConfig.Default.MinStarsForImprovementForThreshold) { double minResidual = m_PlateConfig.GetDistanceInArcSec( m_PlateConfig.CenterXImage, m_PlateConfig.CenterYImage, m_PlateConfig.CenterXImage + CorePyramidConfig.Default.MaxResidualThresholdForImprovementInPixels, m_PlateConfig.CenterYImage); if (maxResidual < minResidual) { maxResidual = minResidual; } } if (settings.Method == AstrometricMethod.AutomaticFit) { return(SolveWithLinearRegression(FitOrder.Cubic, settings.MinimumNumberOfStars, maxResidual, true, out firstFit)); } else if (settings.Method == AstrometricMethod.LinearFit) { return(SolveWithLinearRegression(FitOrder.Linear, settings.MinimumNumberOfStars, maxResidual, false, out firstFit)); } else if (settings.Method == AstrometricMethod.QuadraticFit) { return(SolveWithLinearRegression(FitOrder.Quadratic, settings.MinimumNumberOfStars, maxResidual, false, out firstFit)); } else if (settings.Method == AstrometricMethod.CubicFit) { return(SolveWithLinearRegression(FitOrder.Cubic, settings.MinimumNumberOfStars, maxResidual, false, out firstFit)); } else { throw new NotImplementedException(); } }
public DistanceBasedAstrometrySolver( IOperationNotifier operationNotifier, AstroPlate plateConfig, IAstrometrySettings fitSettings, List<IStar> celestialStars, bool determineAutoLimitMagnitude) { m_PlateConfig = plateConfig; m_FitSettings = fitSettings; m_CelestialStars = celestialStars; m_DetermineAutoLimitMagnitude = determineAutoLimitMagnitude; m_OperationNotifier = operationNotifier; Context = new DistanceBasedContext(operationNotifier, plateConfig, fitSettings, fitSettings.MaxResidualInPixels, m_AstrometryMinMag, m_AstrometryMaxMag); }
public DistanceBasedContext( IOperationNotifier operationNotifier, AstroPlate plateConfigs, IAstrometrySettings settings, double maxLeastSquareResidualInPixels, double minMag, double maxMag) { m_PlateConfig = plateConfigs; if (settings.AlignmentMethod != FieldAlignmentMethod.Pyramid) throw new NotSupportedException("Only the Pyramid field alignment method is supported."); m_Settings = settings; m_MinMag = minMag; m_MaxMag = maxMag; m_MaxLeastSquareResidual = maxLeastSquareResidualInPixels * Math.Max(plateConfigs.EffectivePixelWidth, plateConfigs.EffectivePixelHeight); m_OperationNotifier = operationNotifier; m_OperationNotifier.Subscribe(this, typeof(OperationNotifications)); }
public static PyramidStarsDensityDistributor BuildPyramidMatchingByMagnitude( List<IStar> pyramidStars, AstroPlate image, IAstrometrySettings settings, Dictionary<int, ulong> debugResolvedStarsWithAppliedExclusions, List<ulong> alwaysIncludeStars, out List<DistanceEntry> distancesByMagnitude, out Dictionary<ulong, Dictionary<ulonglong, DistanceEntry>> starsDistanceCache) { // 1) This should be the first N brightest (or all stars) // 2) The memory structure should be a dictionary of Pairs with values all other pairs that include one of the pair // 3) The dictionary should be sorted by brightness i.e. brightest pairs should be on the top/ NOTE: Exclude the brightest // stars until the mag difference between the next 2 bright stars becomes less than 1 mag // 4) Matching should be done by searching the distance match checking the brightest pairs first. distancesByMagnitude = new List<DistanceEntry>(); starsDistanceCache = new Dictionary<ulong, Dictionary<ulonglong, DistanceEntry>>(); if (pyramidStars.Count == 0) return null; PyramidStarsDensityDistributor distributor; pyramidStars.Sort((s1, s2) => s1.Mag.CompareTo(s2.Mag)); int n = pyramidStars.Count; double maxFovInDeg = image.GetMaxFOVInArcSec() / 3600.0; distributor = new PyramidStarsDensityDistributor(pyramidStars, image, settings); distributor.DebugResolvedStarsWithAppliedExclusions = debugResolvedStarsWithAppliedExclusions; distributor.Initialize(alwaysIncludeStars); distancesByMagnitude.Clear(); starsDistanceCache.Clear(); List<ulong> resolvedDebugStarsNos = null; if (debugResolvedStarsWithAppliedExclusions != null) { // This is disabled at the moment resolvedDebugStarsNos = debugResolvedStarsWithAppliedExclusions.Values.ToList(); int pyramidStarsLocated = 0; for (int i = resolvedDebugStarsNos.Count - 1; i >= 0 ; i--) { ulong starNo = resolvedDebugStarsNos[i]; IStar star = pyramidStars.FirstOrDefault(s => s.StarNo == starNo); if (star != null) pyramidStarsLocated++; else resolvedDebugStarsNos.Remove(starNo); Trace.Assert(star != null, string.Format("Debug Star {0} not found in the pyramid stars!", starNo)); } if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) Trace.WriteLine( string.Format("DEBUG ALIGN: {0} out of {1} Debug Stars found among the pyramid stars ({2})", pyramidStarsLocated, resolvedDebugStarsNos.Count, resolvedDebugStarsNos.Count > 1 ? resolvedDebugStarsNos.Select(s => s.ToString()).Aggregate((a, b) => string.Concat(a, " ", b)) : "")); } // Start building the pairs for (int j = 0; j < n; j++) { IStar jStar = pyramidStars[j]; if (!distributor.CheckStar(jStar)) { if (resolvedDebugStarsNos != null) { if (resolvedDebugStarsNos.Contains(jStar.StarNo)) { //Trace.Assert(false, "DebugResolved star pair not added to the pyramid areas because the distributor rejected it."); } } continue; } for (int i = j + 1; i < n; i++) { IStar iStar = pyramidStars[i]; double distDeg = AngleUtility.Elongation(iStar.RADeg, iStar.DEDeg, jStar.RADeg, jStar.DEDeg); if (distDeg > maxFovInDeg) { if (resolvedDebugStarsNos != null) { if (resolvedDebugStarsNos.Contains(iStar.StarNo) && resolvedDebugStarsNos.Contains(jStar.StarNo)) { //Trace.Assert(false, "DebugResolved star pair not added to the pyramid areas because the distance is too large."); } } continue; } if (!distributor.CheckStar(iStar)) { if (resolvedDebugStarsNos != null) { if (resolvedDebugStarsNos.Contains(iStar.StarNo)) { //Trace.Assert(false, string.Format("DebugResolved star {0} not added to the pyramid areas because the distributor rejected it.", iStar.StarNo)); } } continue; } distributor.MarkStar(iStar); distributor.MarkStar(jStar); DistanceEntry entry = new DistanceEntry(iStar, jStar, distDeg * 3600); distancesByMagnitude.Add(entry); #region PerStar distance cache ulonglong id1 = new ulonglong(iStar.StarNo, jStar.StarNo); ulonglong id2 = new ulonglong(jStar.StarNo, iStar.StarNo); Dictionary<ulonglong, DistanceEntry> map; if (!starsDistanceCache.TryGetValue(iStar.StarNo, out map)) { map = new Dictionary<ulonglong, DistanceEntry>(); starsDistanceCache.Add(iStar.StarNo, map); } map.Add(id1, entry); if (!starsDistanceCache.TryGetValue(jStar.StarNo, out map)) { map = new Dictionary<ulonglong, DistanceEntry>(); starsDistanceCache.Add(jStar.StarNo, map); } map.Add(id2, entry); #endregion } } //if (resolvedDebugStarsNos != null) //{ // foreach(uint starNo in resolvedDebugStarsNos) // { // DensityArea area = distributor.m_Areas.FirstOrDefault(a => a.m_IncludedStarNos.Contains(starNo)); // if (area != null) // Trace.WriteLine(string.Format("DEBUG ALIGN: Star {0} located to area [{1:0.00}, {2:0.0}]", starNo, area.XMiddle, area.YMiddle)); // Trace.Assert(area != null); // } //} return distributor; }
public LeastSquareFittedAstrometry SolveWithLinearRegression(IAstrometrySettings settings, out LeastSquareFittedAstrometry firstFit) { double maxResidual = m_PlateConfig.GetDistanceInArcSec( m_PlateConfig.CenterXImage, m_PlateConfig.CenterYImage, m_PlateConfig.CenterXImage + settings.MaxResidualInPixels, m_PlateConfig.CenterYImage + settings.MaxResidualInPixels); if (m_Pairs.Count < CorePyramidConfig.Default.MinStarsForImprovementForThreshold) { double minResidual = m_PlateConfig.GetDistanceInArcSec( m_PlateConfig.CenterXImage, m_PlateConfig.CenterYImage, m_PlateConfig.CenterXImage + CorePyramidConfig.Default.MaxResidualThresholdForImprovementInPixels, m_PlateConfig.CenterYImage); if (maxResidual < minResidual) maxResidual = minResidual; } if (settings.Method == AstrometricMethod.AutomaticFit) return SolveWithLinearRegression(FitOrder.Cubic, settings.MinimumNumberOfStars, maxResidual, true, out firstFit); else if (settings.Method == AstrometricMethod.LinearFit) return SolveWithLinearRegression(FitOrder.Linear, settings.MinimumNumberOfStars, maxResidual, false, out firstFit); else if (settings.Method == AstrometricMethod.QuadraticFit) return SolveWithLinearRegression(FitOrder.Quadratic, settings.MinimumNumberOfStars, maxResidual, false, out firstFit); else if (settings.Method == AstrometricMethod.CubicFit) return SolveWithLinearRegression(FitOrder.Cubic, settings.MinimumNumberOfStars, maxResidual, false, out firstFit); else throw new NotImplementedException(); }
public Bitmap ResolveObjects( TangraConfig.PhotometryReductionMethod photometryReductionMethod, TangraConfig.PsfQuadrature psfQuadrature, TangraConfig.PsfFittingMethod psfFittingMethod, TangraConfig.BackgroundMethod backgroundMethod, TangraConfig.PreProcessingFilter filter, Guid magnitudeBandId, Rectangle osdRectangleToExclude, Rectangle rectToInclude, bool limitByInclusion, IAstrometrySettings astrometrySettings, ObjectResolverSettings objectResolverSettings) { m_AstrometrySettings = astrometrySettings; StarMap starMap = new StarMap( astrometrySettings.PyramidRemoveNonStellarObject, astrometrySettings.MinReferenceStarFWHM, astrometrySettings.MaxReferenceStarFWHM, astrometrySettings.MaximumPSFElongation, astrometrySettings.LimitReferenceStarDetection); starMap.FindBestMap(StarMapInternalConfig.Default, m_Image, osdRectangleToExclude, rectToInclude, limitByInclusion); float r0 = 0; m_MagnitudeFit = StarMagnitudeFit.PerformFit( m_AstrometryController, m_VideoController, m_Image.Pixelmap.BitPixCamera, m_Image.Pixelmap.MaxSignalValue, m_Astrometry.FitInfo, photometryReductionMethod, psfQuadrature, psfFittingMethod, backgroundMethod, filter, m_Stars, magnitudeBandId, 1.0f, TangraConfig.KnownCameraResponse.Undefined, null, null, null, ref r0); m_BackgroundFlux = m_MagnitudeFit.GetBackgroundIntencity(); m_BackgroundMag = m_MagnitudeFit.GetMagnitudeForIntencity(m_BackgroundFlux); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("Plate FWHM: {0}", 2 * Math.Sqrt(Math.Log(2)) * r0)); } PeakPixelResolver resolver = new PeakPixelResolver(m_Image); resolver.ResolvePeakPixels(osdRectangleToExclude, rectToInclude, limitByInclusion, objectResolverSettings.ExcludeEdgeAreaPixels, objectResolverSettings.MinDistanceBetweenPeakPixels); List <double> identifiedMagnitudes = new List <double>(); List <double> identifiedR0s = new List <double>(); m_IdentifiedObjects.Clear(); m_UidentifiedObjects.Clear(); foreach (KeyValuePair <int, int> peakPixel in resolver.PeakPixels.Keys) { int x = peakPixel.Key; int y = peakPixel.Value; bool isSaturated; double intencity = m_MagnitudeFit.GetIntencity(new ImagePixel(255, x, y), out isSaturated); double magnitude = m_MagnitudeFit.GetMagnitudeForIntencity(intencity); if (magnitude < m_MaxMagForAstrometry) { double RADeg, DEDeg; PSFFit fit; starMap.GetPSFFit(x, y, PSFFittingMethod.NonLinearFit, out fit); if (fit.IMax < 0) { continue; } if (fit.IMax < fit.I0) { continue; } if (fit.Certainty < objectResolverSettings.MinCertainty) { continue; } if (fit.FWHM < objectResolverSettings.MinFWHM) { continue; } if (fit.IMax - fit.I0 < objectResolverSettings.MinAmplitude) { continue; } m_Astrometry.GetRADEFromImageCoords(fit.XCenter, fit.YCenter, out RADeg, out DEDeg); // All stars closer than 2 arcsec to this position List <IStar> matchingStars = m_Stars.Where(s => Math.Abs(AngleUtility.Elongation(s.RADeg, s.DEDeg, RADeg, DEDeg) * 3600.0) < objectResolverSettings.MaxStarMatchMagDif).ToList(); bool identified = false; if (matchingStars.Count >= 1) { foreach (IStar star in matchingStars) { if (objectResolverSettings.MaxStarMatchMagDif >= Math.Abs(magnitude - star.Mag)) { // The star is identified. Do we care more? if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("STAR ({0}, {1}) No -> {2}; Mag -> {3} (Expected: {4}); R0 = {5}", x, y, star.StarNo, magnitude.ToString("0.00"), star.Mag.ToString("0.00"), fit.R0.ToString("0.0"))); } identifiedMagnitudes.Add(magnitude); identifiedR0s.Add(fit.R0); m_IdentifiedObjects.Add(fit, star); identified = true; break; } } } if (matchingStars.Count == 0 || !identified) { // The object is not in the star database // TODO: Test for hot pixel. Match to hot pixel profile from the brightest pixel in the area m_UidentifiedObjects.Add(fit, magnitude); } } else { // Don't bother with too faint objects } } if (m_IdentifiedObjects.Count > 0) { double mean = identifiedR0s.Average(); double variance = 0; foreach (double rr0 in identifiedR0s) { variance += (rr0 - mean) * (rr0 - mean); } variance = Math.Sqrt(variance / (m_IdentifiedObjects.Count - 1)); double minR0 = mean - variance; double maxR0 = mean + variance; identifiedMagnitudes.Sort(); double maxStarMag = identifiedMagnitudes[Math.Max(0, (int)Math.Truncate(0.9 * identifiedMagnitudes.Count))]; if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("Max Star Mag: {0}; R0 ({1}, {2})", maxStarMag.ToString("0.00"), minR0.ToString("0.0"), maxR0.ToString("0.0"))); } // NOTE: The R0 exclusion may ignore bright comets ! m_UnknownObjects = m_UidentifiedObjects .Where(p => p.Value < maxStarMag && p.Key.R0 >= minR0 && p.Key.R0 <= maxR0) .ToDictionary(p => p.Key, p => p.Value); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { foreach (PSFFit obj in m_UnknownObjects.Keys) { Trace.WriteLine(string.Format("UNK: ({0}, {1}) Mag -> {2}; R0 = {3}", obj.XCenter.ToString("0.0"), obj.YCenter.ToString("0.0"), m_UnknownObjects[obj].ToString("0.00"), obj.R0.ToString("0.0"))); } } } Bitmap bitmap = m_Image.Pixelmap.CreateDisplayBitmapDoNotDispose(); using (Graphics g = Graphics.FromImage(bitmap)) { foreach (PSFFit star in m_IdentifiedObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.GreenYellow, x - 5, y - 5, 10, 10); } foreach (PSFFit star in m_UnknownObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.Tomato, x - 8, y - 8, 16, 16); } g.Save(); } return(bitmap); }
public Bitmap ResolveObjects( TangraConfig.PhotometryReductionMethod photometryReductionMethod, TangraConfig.PsfQuadrature psfQuadrature, TangraConfig.PsfFittingMethod psfFittingMethod, TangraConfig.BackgroundMethod backgroundMethod, TangraConfig.PreProcessingFilter filter, Guid magnitudeBandId, Rectangle osdRectangleToExclude, Rectangle rectToInclude, bool limitByInclusion, IAstrometrySettings astrometrySettings, ObjectResolverSettings objectResolverSettings) { m_AstrometrySettings = astrometrySettings; StarMap starMap = new StarMap( astrometrySettings.PyramidRemoveNonStellarObject, astrometrySettings.MinReferenceStarFWHM, astrometrySettings.MaxReferenceStarFWHM, astrometrySettings.MaximumPSFElongation, astrometrySettings.LimitReferenceStarDetection); starMap.FindBestMap(StarMapInternalConfig.Default, m_Image, osdRectangleToExclude, rectToInclude, limitByInclusion); float r0 = 0; m_MagnitudeFit = StarMagnitudeFit.PerformFit( m_AstrometryController, m_VideoController, m_Image.Pixelmap.BitPixCamera, m_Image.Pixelmap.MaxSignalValue, m_Astrometry.FitInfo, photometryReductionMethod, psfQuadrature, psfFittingMethod, backgroundMethod, filter, m_Stars, magnitudeBandId, 1.0f, TangraConfig.KnownCameraResponse.Undefined, null, null, null, ref r0); m_BackgroundFlux = m_MagnitudeFit.GetBackgroundIntencity(); m_BackgroundMag = m_MagnitudeFit.GetMagnitudeForIntencity(m_BackgroundFlux); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) Trace.WriteLine(string.Format("Plate FWHM: {0}", 2 * Math.Sqrt(Math.Log(2)) * r0)); PeakPixelResolver resolver = new PeakPixelResolver(m_Image); resolver.ResolvePeakPixels(osdRectangleToExclude, rectToInclude, limitByInclusion, objectResolverSettings.ExcludeEdgeAreaPixels, objectResolverSettings.MinDistanceBetweenPeakPixels); List<double> identifiedMagnitudes = new List<double>(); List<double> identifiedR0s = new List<double>(); m_IdentifiedObjects.Clear(); m_UidentifiedObjects.Clear(); foreach(KeyValuePair<int, int> peakPixel in resolver.PeakPixels.Keys) { int x = peakPixel.Key; int y = peakPixel.Value; bool isSaturated; double intencity = m_MagnitudeFit.GetIntencity(new ImagePixel(255, x, y), out isSaturated); double magnitude = m_MagnitudeFit.GetMagnitudeForIntencity(intencity); if (magnitude < m_MaxMagForAstrometry) { double RADeg, DEDeg; PSFFit fit; starMap.GetPSFFit(x, y, PSFFittingMethod.NonLinearFit, out fit); if (fit.IMax < 0) continue; if (fit.IMax < fit.I0) continue; if (fit.Certainty < objectResolverSettings.MinCertainty) continue; if (fit.FWHM < objectResolverSettings.MinFWHM) continue; if (fit.IMax - fit.I0 < objectResolverSettings.MinAmplitude) continue; m_Astrometry.GetRADEFromImageCoords(fit.XCenter, fit.YCenter, out RADeg, out DEDeg); // All stars closer than 2 arcsec to this position List<IStar> matchingStars = m_Stars.Where(s => Math.Abs(AngleUtility.Elongation(s.RADeg, s.DEDeg, RADeg, DEDeg) * 3600.0) < objectResolverSettings.MaxStarMatchMagDif).ToList(); bool identified = false; if (matchingStars.Count >= 1) { foreach(IStar star in matchingStars) { if (objectResolverSettings.MaxStarMatchMagDif >= Math.Abs(magnitude - star.Mag)) { // The star is identified. Do we care more? if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) Trace.WriteLine(string.Format("STAR ({0}, {1}) No -> {2}; Mag -> {3} (Expected: {4}); R0 = {5}", x, y, star.StarNo, magnitude.ToString("0.00"), star.Mag.ToString("0.00"), fit.R0.ToString("0.0"))); identifiedMagnitudes.Add(magnitude); identifiedR0s.Add(fit.R0); m_IdentifiedObjects.Add(fit, star); identified = true; break; } } } if (matchingStars.Count == 0 || !identified) { // The object is not in the star database // TODO: Test for hot pixel. Match to hot pixel profile from the brightest pixel in the area m_UidentifiedObjects.Add(fit, magnitude); } } else { // Don't bother with too faint objects } } if (m_IdentifiedObjects.Count > 0) { double mean = identifiedR0s.Average(); double variance = 0; foreach (double rr0 in identifiedR0s) { variance += (rr0 - mean) * (rr0 - mean); } variance = Math.Sqrt(variance / (m_IdentifiedObjects.Count - 1)); double minR0 = mean - variance; double maxR0 = mean + variance; identifiedMagnitudes.Sort(); double maxStarMag = identifiedMagnitudes[Math.Max(0, (int)Math.Truncate(0.9 * identifiedMagnitudes.Count))]; if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) Trace.WriteLine(string.Format("Max Star Mag: {0}; R0 ({1}, {2})", maxStarMag.ToString("0.00"), minR0.ToString("0.0"), maxR0.ToString("0.0"))); // NOTE: The R0 exclusion may ignore bright comets ! m_UnknownObjects = m_UidentifiedObjects .Where(p => p.Value < maxStarMag && p.Key.R0 >= minR0 && p.Key.R0 <= maxR0) .ToDictionary(p => p.Key, p => p.Value); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { foreach (PSFFit obj in m_UnknownObjects.Keys) { Trace.WriteLine(string.Format("UNK: ({0}, {1}) Mag -> {2}; R0 = {3}", obj.XCenter.ToString("0.0"), obj.YCenter.ToString("0.0"), m_UnknownObjects[obj].ToString("0.00"), obj.R0.ToString("0.0"))); } } } Bitmap bitmap = m_Image.Pixelmap.CreateDisplayBitmapDoNotDispose(); using (Graphics g = Graphics.FromImage(bitmap)) { foreach (PSFFit star in m_IdentifiedObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.GreenYellow, x - 5, y - 5, 10, 10); } foreach (PSFFit star in m_UnknownObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.Tomato, x - 8, y - 8, 16, 16); } g.Save(); } return bitmap; }
public PyramidStarsDensityDistributor(List<IStar> stars, AstroPlate image, IAstrometrySettings settings) { m_Stars = stars; m_Image = image; m_XAreaSideDeg = image.GetDistanceInArcSec(0, image.CenterYImage, image.CenterXImage, image.CenterYImage) / 3600.0; m_YAreaSideDeg = image.GetDistanceInArcSec(image.CenterXImage, 0, image.CenterXImage, image.CenterYImage) / 3600.0; MAX_STARS_IN_AREA = settings.DistributionZoneStars; }