コード例 #1
0
 public PlateCalibration(
     CalibrationContext context,
     IAstrometrySettings astrometrySettings,
     IAstrometryController astrometryController)
 {
     m_Context              = context;
     m_AstrometrySettings   = astrometrySettings;
     m_AstrometryController = astrometryController;
 }
コード例 #2
0
ファイル: PlateCalibration.cs プロジェクト: hpavlov/tangra3
        public PlateCalibration(
			CalibrationContext context,
			IAstrometrySettings astrometrySettings,
			IAstrometryController astrometryController)
        {
            m_Context = context;
            m_AstrometrySettings = astrometrySettings;
            m_AstrometryController = astrometryController;
        }
コード例 #3
0
        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;
        }
コード例 #4
0
        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;
            }
        }
コード例 #5
0
        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;
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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();
            }
        }
コード例 #8
0
        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);
        }
コード例 #9
0
		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));
		}
コード例 #10
0
        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;
		}
コード例 #11
0
        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();
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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;
        }
コード例 #14
0
        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;
        }