Beispiel #1
0
        public static AstroPlate FromReflectedObject(object reflObj)
        {
            var rv = new AstroPlate();

            rv.m_ImageWidth          = StarMap.GetPropValue <int>(reflObj, "m_ImageWidth");
            rv.m_ImageHeight         = StarMap.GetPropValue <int>(reflObj, "m_ImageHeight");
            rv.m_MatrixToImageScaleX = StarMap.GetPropValue <double>(reflObj, "m_MatrixToImageScaleX");
            rv.m_MatrixToImageScaleY = StarMap.GetPropValue <double>(reflObj, "m_MatrixToImageScaleY");
            rv.EffectiveFocalLength  = StarMap.GetPropValue <double>(reflObj, "EffectiveFocalLength");
            rv.EffectivePixelWidth   = StarMap.GetPropValue <double>(reflObj, "EffectivePixelWidth");
            rv.EffectivePixelHeight  = StarMap.GetPropValue <double>(reflObj, "EffectivePixelHeight");

            object obj = StarMap.GetPropValue <object>(reflObj, "m_Matrix");

            rv.m_Matrix = CCDMatrix.FromReflectedObject(obj);

            try
            {
                rv.m_BitPix = StarMap.GetPropValue <int>(reflObj, "BitPix");
            }
            catch
            {
                rv.m_BitPix = 8;
            }

            return(rv);
        }
Beispiel #2
0
        public void Test2_NearSouthPole()
        {
            var matrix = new CCDMatrix(8.6, 8.3, 752, 582);
            var astroPlate = new AstroPlate(matrix, 720, 576, 16);

            var userStars = new Dictionary<ImagePixel, IStar>();

            var star1 = new TestStar(670000669, 14.040622402203727, -76.691539882008868, 13.389);
            var pixel1 = new ImagePixel(111.28789147012657, 170.18336583345945);
            userStars.Add(pixel1, star1);

            var star2 = new TestStar(680000642, 13.3447869927272, -76.594950217617452, 9.932);
            var pixel2 = new ImagePixel(575.00594900921817, 446.45890095859744);
            userStars.Add(pixel2, star2);

            var star3 = new TestStar(670000641, 13.550035599758042, -76.722167259223085, 13.842);
            var pixel3 = new ImagePixel(425.86138030460097, 63.057739094752051);
            userStars.Add(pixel3, star3);

            var newAstro = new ThreeStarAstrometry(astroPlate, userStars, 2);
            Assert.IsTrue(newAstro.Success);
            Assert.AreEqual(-76.6498, newAstro.DE0Deg, 0.0001);
            Assert.AreEqual(13.6644, newAstro.RA0Deg, 0.0001);

            double ra, de;
            newAstro.GetRADEFromImageCoords(111.28789147012657, 170.18336583345945, out ra, out de);
            Assert.AreEqual(14.0406224, ra, 0.0000001);
            Assert.AreEqual(-76.6915398, de, 0.0000001);

            double x, y;
            newAstro.GetImageCoordsFromRADE(14.040622402203727, -76.691539882008868, out x, out y);
            Assert.AreEqual(111.2879, x, 0.0001);
            Assert.AreEqual(170.1833, y, 0.0001);
        }
        public DirectTransRotAstrometry(AstroPlate image, double RA0Deg, double DE0Deg, double EtaDeg, double aspect)
        {
            m_Image = image;

            EtaRadians = EtaDeg * Math.PI / 180;
            this.m_RA0Deg = RA0Deg;
            this.m_DE0Deg = DE0Deg;
            this.m_EtaDeg = EtaDeg;
            this.m_Aspect = aspect;
        }
Beispiel #4
0
        public AstroPlate Clone()
        {
            CCDMatrix  clonedMatrix = new CCDMatrix(m_Matrix.CellX, m_Matrix.CellY, m_Matrix.Width, m_Matrix.Height);
            AstroPlate clone        = new AstroPlate(clonedMatrix, m_ImageWidth, m_ImageHeight, m_BitPix);

            clone.EffectivePixelWidth  = this.EffectivePixelWidth;
            clone.EffectivePixelHeight = this.EffectivePixelHeight;
            clone.EffectiveFocalLength = this.EffectiveFocalLength;

            return(clone);
        }
        public TangentalTransRotAstrometry(TangentalTransRotAstrometry prev, AstroPlate image, double RA0Deg, double DE0Deg, double EtaDeg)
        {
            m_Image = prev.m_Image;

            EtaRadians = EtaDeg * Math.PI / 180;
            this.m_RA0Deg = RA0Deg;
            this.m_DE0Deg = DE0Deg;

            cellWidth = prev.cellWidth;
            cellHeight = prev.cellHeight;
            focalLength = image.EffectiveFocalLength; // prev.focalLength;
            m_InfoString = string.Format("Tangental [{0}; {1}; {2}]", cellWidth.ToString("0.00"), cellHeight.ToString("0.00"), focalLength.ToString("0.0"));
        }
        public LeastSquareFittedAstrometry(
			AstroPlate image,
			double RA0Deg, double DE0Deg,
			PlateConstantsFit solution)
        {
            m_Image = image;

            this.m_RA0Deg = RA0Deg;
            this.m_DE0Deg = DE0Deg;

            m_SolvedConstants = solution;
            m_Variance = solution.Variance;
            m_StdDevRAArcSec = Math.Sqrt(solution.VarianceArcSecRA);
            m_StdDevDEArcSec = Math.Sqrt(solution.VarianceArcSecDE);
        }
        public DirectTransRotAstrometry(SerializationInfo info, StreamingContext context)
        {
            EtaRadians = info.GetDouble("EtaRadians");
            m_RA0Deg = info.GetDouble("m_RA0Deg");
            m_DE0Deg = info.GetDouble("m_DE0Deg");
            m_EtaDeg = info.GetDouble("m_EtaDeg");
            m_Aspect = info.GetDouble("m_Aspect");

            byte[] data = (byte[])info.GetValue("m_Image", typeof(byte[]));

            BinaryFormatter fmt = new BinaryFormatter();
            using (MemoryStream mem = new MemoryStream(data))
            {
                m_Image = (AstroPlate)fmt.Deserialize(mem);
            }
        }
Beispiel #8
0
        public void Test1()
        {
            var matrix = new CCDMatrix(8.6, 8.3, 752, 582);
            var astroPlate = new AstroPlate(matrix, 720, 576, 8);

            var userStars = new Dictionary<ImagePixel, IStar>();

            var star1 = new TestStar(2890001240, 18.528885242458674, -32.262447583319769, 11.033);
            var pixel1 = new ImagePixel(72.0519465443632, 240.48754416283302);
            userStars.Add(pixel1, star1);

            var star2 = new TestStar(2890001234, 18.353495385568369, -32.296976944037546, 12.294);
            var pixel2 = new ImagePixel(421.79863331879409, 329.57539665223919);
            userStars.Add(pixel2, star2);

            var star3 = new TestStar(2890001229, 18.284537781225755, -32.213242615932892, 10.882);
            var pixel3 = new ImagePixel(559.51676838260289, 114.86160161500557);
            userStars.Add(pixel3, star3);

            var plateSolve = DirectTransRotAstrometry.SolveByThreeStars(astroPlate, userStars, 2);

            Assert.IsNotNull(plateSolve);
            Assert.AreEqual(1.2836, plateSolve.Aspect, 0.0001);
            Assert.AreEqual(-32.2808, plateSolve.DE0Deg, 0.0001);
            Assert.AreEqual(18.3845, plateSolve.RA0Deg, 0.0001);
            Assert.AreEqual(179.9401, plateSolve.EtaDeg, 0.0001);
            Assert.AreEqual(0.00, plateSolve.Residual, 0.01);

            var newAstro = new ThreeStarAstrometry(astroPlate, userStars, 2);
            Assert.IsTrue(newAstro.Success);

            Assert.AreEqual(-32.2808, newAstro.DE0Deg, 0.0001);
            Assert.AreEqual(18.3845, newAstro.RA0Deg, 0.0001);

            double ra, de;
            newAstro.GetRADEFromImageCoords(72.0519465443632, 240.48754416283302, out ra, out de);
            Assert.AreEqual(18.5288852, ra, 0.0000001);
            Assert.AreEqual(-32.2624475, de, 0.0000001);

            double x, y;
            newAstro.GetImageCoordsFromRADE(18.528885242458674, -32.262447583319769, out x, out y);
            Assert.AreEqual(72.0519, x, 0.0001);
            Assert.AreEqual(240.4875, y, 0.0001);
        }
        public LeastSquareFittedAstrometry(SerializationInfo info, StreamingContext context)
        {
            m_RA0Deg = info.GetDouble("m_RA0Deg");
            m_DE0Deg = info.GetDouble("m_DE0Deg");

            byte[] data = (byte[])info.GetValue("m_Image", typeof(byte[]));

            BinaryFormatter fmt = new BinaryFormatter();
            using (MemoryStream mem = new MemoryStream(data))
            {
                m_Image = (AstroPlate)fmt.Deserialize(mem);
            }

            data = (byte[])info.GetValue("m_SolvedConstants", typeof(byte[]));
            using (MemoryStream mem = new MemoryStream(data))
            {
                m_SolvedConstants = (PlateConstantsFit)fmt.Deserialize(mem);
            }
        }
Beispiel #10
0
        public AstroPlate Clone()
        {
            CCDMatrix clonedMatrix = new CCDMatrix(m_Matrix.CellX, m_Matrix.CellY, m_Matrix.Width, m_Matrix.Height);
            AstroPlate clone = new AstroPlate(clonedMatrix, m_ImageWidth, m_ImageHeight, m_BitPix);

            clone.EffectivePixelWidth = this.EffectivePixelWidth;
            clone.EffectivePixelHeight = this.EffectivePixelHeight;
            clone.EffectiveFocalLength = this.EffectiveFocalLength;

            return clone;
        }
 public DirectTransRotAstrometry(AstroPlate image, double RA0Deg, double DE0Deg, double EtaDeg)
     : this(image, RA0Deg, DE0Deg, EtaDeg, 1.0)
 {
 }
        public static DirectTransRotAstrometry SolveByThreeStars(
			AstroPlate image,
			Dictionary<PSFFit, IStar> userStarIdentification,
            int tolerance)
        {
            Dictionary<ImagePixel, IStar> transformedDict =
                userStarIdentification.ToDictionary(
                    kvp => new ImagePixel(255, kvp.Key.XCenter, kvp.Key.YCenter),
                    kvp => kvp.Value);

            return SolveByThreeStars(image, transformedDict, tolerance);
        }
        public static DirectTransRotAstrometry SolveByThreeStars(
			AstroPlate image,
			Dictionary<ImagePixel, IStar> userStarIdentification,
            int tolerance)
        {
            double SingularityMinDiffPix = 2.0;

            List<KeyValuePair<ImagePixel, IStar>> master = userStarIdentification.ToList();

            List<KeyValuePair<ImagePixel, IStar>> list = new List<KeyValuePair<ImagePixel, IStar>>();
            for (int i = 0; i < 3; i++)
            {
                list.Clear();
                if (i == 0)
                {
                    list.Add(master[0]);
                    list.Add(master[1]);
                    list.Add(master[2]);
                }
                else if (i == 1)
                {
                    list.Add(master[2]);
                    list.Add(master[0]);
                    list.Add(master[1]);
                }
                else if (i == 2)
                {
                    list.Add(master[1]);
                    list.Add(master[2]);
                    list.Add(master[0]);
                }

                double x1 = list[0].Key.XDouble;
                double y1 = list[0].Key.YDouble;
                double ra1 = list[0].Value.RADeg;
                double de1 = list[0].Value.DEDeg;

                double x2 = list[1].Key.XDouble;
                double y2 = list[1].Key.YDouble;
                double ra2 = list[1].Value.RADeg;
                double de2 = list[1].Value.DEDeg;

                double x3 = list[2].Key.XDouble;
                double y3 = list[2].Key.YDouble;
                double ra3 = list[2].Value.RADeg;
                double de3 = list[2].Value.DEDeg;

                #region Dealing with singularity issues
                if (Math.Abs(x1 - x2) < SingularityMinDiffPix)
                {
                    if (x1 < x2)
                        x2 = x1 + SingularityMinDiffPix;
                    else
                        x1 = x2 + SingularityMinDiffPix;
                }

                if (Math.Abs(x1 - x3) < SingularityMinDiffPix)
                {
                    if (x1 < x3)
                        x3 = x1 + SingularityMinDiffPix;
                    else
                        x1 = x3 + SingularityMinDiffPix;
                }

                if (Math.Abs(x2 - x3) < SingularityMinDiffPix)
                {
                    if (x2 < x3)
                        x3 = x2 + SingularityMinDiffPix;
                    else
                        x2 = x3 + SingularityMinDiffPix;
                }

                if (Math.Abs(y1 - y2) < SingularityMinDiffPix)
                {
                    if (y1 < y2)
                        y2 = y1 + SingularityMinDiffPix;
                    else
                        y1 = y2 + SingularityMinDiffPix;
                }
                if (Math.Abs(y1 - y3) < SingularityMinDiffPix)
                {
                    if (y1 < y3)
                        y3 = y1 + SingularityMinDiffPix;
                    else
                        y1 = y3 + SingularityMinDiffPix;
                }
                if (Math.Abs(y2 - y3) < SingularityMinDiffPix)
                {
                    if (y2 < y3)
                        y3 = y2 + SingularityMinDiffPix;
                    else
                        y2 = y3 + SingularityMinDiffPix;
                }
                #endregion

                double YY = 1000.0 * 3600 / (206265 * image.EffectivePixelHeight);
                double XX = 1000.0 * 3600 / (206265 * image.EffectivePixelWidth);

                double f_cose = ((y1 - y2) * (ra1 - ra3) - (y1 - y3) * (ra1 - ra2)) / (YY * ((de1 - de2) * (ra1 - ra3) - (de1 - de3) * (ra1 - ra2)));
                double f_sine = (de1 - de2) * f_cose / (ra1 - ra2) - (y1 - y2) / (YY * (ra1 - ra2));

                double eta1rad = Math.Atan(f_sine / f_cose);
                double eta2rad = Math.PI + eta1rad;

                double foc_len1 = Math.Abs(f_sine / Math.Sin(eta1rad));
                double foc_len2 = Math.Abs(f_sine / Math.Sin(eta2rad));

                double aspect1 = (foc_len1 * XX * Math.Cos(eta1rad) * (ra1 - ra2 + (de1 - de2) * Math.Tan(eta1rad))) / (x1 - x2);
                double DE01 = de1 - Math.Sin(eta1rad) * Math.Cos(eta1rad) * (aspect1 * (x1 - image.CenterXImage) / (foc_len1 * XX * Math.Cos(eta1rad)) + (y1 - image.CenterYImage) / (foc_len1 * YY * Math.Sin(eta1rad)));
                double RA01 = ra1 - ((de1 - DE01) * Math.Cos(eta1rad) - (y1 - image.CenterYImage) / (foc_len1 * YY)) / Math.Sin(eta1rad);

                double aspect2 = (foc_len2 * XX * Math.Cos(eta2rad) * (ra1 - ra2 + (de1 - de2) * Math.Tan(eta2rad))) / (x1 - x2);
                double DE02 = de1 - Math.Sin(eta2rad) * Math.Cos(eta2rad) * (aspect2 * (x1 - image.CenterXImage) / (foc_len2 * XX * Math.Cos(eta2rad)) + (y1 - image.CenterYImage) / (foc_len2 * YY * Math.Sin(eta2rad)));
                double RA02 = ra1 - ((de1 - DE02) * Math.Cos(eta2rad) - (y1 - image.CenterYImage) / (foc_len2 * YY)) / Math.Sin(eta2rad);

                AstroPlate plate1 = image.Clone();
                plate1.EffectiveFocalLength = foc_len1;
                DirectTransRotAstrometry solution1 = new DirectTransRotAstrometry(plate1, RA01, DE01, eta1rad * 180.0 / Math.PI, aspect1);

                AstroPlate plate2 = image.Clone();
                plate2.EffectiveFocalLength = foc_len2;
                DirectTransRotAstrometry solution2 = new DirectTransRotAstrometry(plate2, RA02, DE02, eta2rad * 180.0 / Math.PI, aspect2);

                double xx1, yy1, xx2, yy2, xx3, yy3;
                solution1.GetImageCoordsFromRADE(ra1, de1, out xx1, out yy1);
                solution1.GetImageCoordsFromRADE(ra2, de2, out xx2, out yy2);
                solution1.GetImageCoordsFromRADE(ra3, de3, out xx3, out yy3);
                solution1.Residual = Math.Sqrt(
                    (x1 - xx1) * (x1 - xx1) + (y1 - yy1) * (y1 - yy1) +
                    (x2 - xx2) * (x2 - xx2) + (y2 - yy2) * (y2 - yy2) +
                    (x3 - xx3) * (x3 - xx3) + (y3 - yy3) * (y3 - yy3));

                solution2.GetImageCoordsFromRADE(ra1, de1, out xx1, out yy1);
                solution2.GetImageCoordsFromRADE(ra2, de2, out xx2, out yy2);
                solution2.GetImageCoordsFromRADE(ra3, de3, out xx3, out yy3);
                solution2.Residual = Math.Sqrt(
                    (x1 - xx1) * (x1 - xx1) + (y1 - yy1) * (y1 - yy1) +
                    (x2 - xx2) * (x2 - xx2) + (y2 - yy2) * (y2 - yy2) +
                    (x3 - xx3) * (x3 - xx3) + (y3 - yy3) * (y3 - yy3));

                double maxResidual = CorePyramidConfig.Default.MaxThreeIdentifiedStarsFitResidual;
                if (tolerance == 1) maxResidual *= 0.75;
                else if (tolerance == 3) maxResidual *= 2;
                else if (tolerance == 4) maxResidual *= 3;

                if (solution1.Residual < solution2.Residual)
                {
                    if (solution1.Residual < maxResidual && aspect1 > 0)
                        return solution1;
                }
                else
                {
                    if (solution2.Residual < maxResidual && aspect2 > 0)
                        return solution2;
                }
            }

            return null;
        }
        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 frmConfigureAstrometricFit(VideoController videoController, AstroPlate image)
        {
            m_VideoController = videoController;
            m_Image = image;

            InitializeComponent();

            rbKnownCenter.Checked = TangraConfig.Settings.PlateSolve.StarIDSettings.Method == 0;

            #if ASTROMETRY_DEBUG
            Trace.Assert(TangraConfig.Settings.PlateSolve.SelectedScopeRecorderConfig != null);
            #endif

            if (!string.IsNullOrEmpty(TangraConfig.Settings.LastUsed.AstrRAHours) &&
                !string.IsNullOrEmpty(TangraConfig.Settings.LastUsed.AstrDEDeg))
            {
                cbxRA.Text = TangraConfig.Settings.LastUsed.AstrRAHours;
                cbxDE.Text = TangraConfig.Settings.LastUsed.AstrDEDeg;
            }

            if (!double.IsNaN(TangraConfig.Settings.LastUsed.AstrErrFoVs))
                SetNUDValue(nudError, (decimal)TangraConfig.Settings.LastUsed.AstrErrFoVs);

            int lastSearchTypeIdx = TangraConfig.Settings.LastUsed.AstrSearchTypeIndex;
            switch (lastSearchTypeIdx)
            {
                case 0:
                    rbKnownObject.Checked = true;
                    break;

                default:
                    rbKnownCenter.Checked = true;
                    break;
            }

            Context.FoundObject = null;

            utcTime.OnDateTimeChanged += new EventHandler<DateTimeChangeEventArgs>(ucTime_OnDateTimeChanged);

            if (TangraConfig.Settings.LastUsed.LastAstrometryUTCDate.Date.Year == 1)
                TangraConfig.Settings.LastUsed.LastAstrometryUTCDate = DateTime.Now;

            DateTime? timeStamp = videoController.GetCurrentFrameTime();
            if (timeStamp != null && timeStamp != DateTime.MinValue)
            {
                if (timeStamp.Value.Year == 1)
                {
                    // OCR-ed timestamp that doesn't contain a year
                    utcTime.DateTimeUtc = TangraConfig.Settings.LastUsed.LastAstrometryUTCDate.Date.AddDays(timeStamp.Value.TimeOfDay.TotalDays);
                    lblOCRTimeWarning.Visible = true;
                }
                else
                    utcTime.DateTimeUtc = timeStamp.Value;
            }
            else
                utcTime.DateTimeUtc = TangraConfig.Settings.LastUsed.LastAstrometryUTCDate;
            DisplayEnterTimePage();

            UpdateErrorInDeg();

            m_MaxRefValue = TangraConfig.Settings.PlateSolve.SelectedScopeRecorderConfig.LimitingMagnitudes[TangraConfig.Settings.PlateSolve.SelectedCameraModel];
            nudFaintestMag.Value = (decimal)Math.Round(m_MaxRefValue);

            pnlSelectedLimitMagnitude.Enabled = false;
            rbAutomaticLimitMagnitude.Checked = true;
        }
Beispiel #16
0
 public PlateConstantsSolver(AstroPlate plateConfig)
 {
     m_PlateConfig = plateConfig;
 }
Beispiel #17
0
        public static AstroPlate FromReflectedObject(object reflObj)
        {
            var rv = new AstroPlate();

            rv.m_ImageWidth = StarMap.GetPropValue<int>(reflObj, "m_ImageWidth");
            rv.m_ImageHeight = StarMap.GetPropValue<int>(reflObj, "m_ImageHeight");
            rv.m_MatrixToImageScaleX = StarMap.GetPropValue<double>(reflObj, "m_MatrixToImageScaleX");
            rv.m_MatrixToImageScaleY = StarMap.GetPropValue<double>(reflObj, "m_MatrixToImageScaleY");
            rv.EffectiveFocalLength = StarMap.GetPropValue<double>(reflObj, "EffectiveFocalLength");
            rv.EffectivePixelWidth = StarMap.GetPropValue<double>(reflObj, "EffectivePixelWidth");
            rv.EffectivePixelHeight = StarMap.GetPropValue<double>(reflObj, "EffectivePixelHeight");

            object obj = StarMap.GetPropValue<object>(reflObj, "m_Matrix");
            rv.m_Matrix = CCDMatrix.FromReflectedObject(obj);

            try
            {
                rv.m_BitPix = StarMap.GetPropValue<int>(reflObj, "BitPix");
            }
            catch
            {
                rv.m_BitPix = 8;
            }

            return rv;
        }
Beispiel #18
0
        public static ThreeStarAstrometry SolveByThreeStars(
            AstroPlate image,
            Dictionary<PSFFit, IStar> userStarIdentification,
            int tolerance)
        {
            Dictionary<ImagePixel, IStar> transformedDict =
                userStarIdentification.ToDictionary(
                    kvp => new ImagePixel(255, kvp.Key.XCenter, kvp.Key.YCenter),
                    kvp => kvp.Value);

            var solution = new ThreeStarAstrometry(image, transformedDict, tolerance);
            if (solution.Success)
                return solution;
            else
                return null;
        }
Beispiel #19
0
        protected virtual void ReinitializePlateConstants()
        {
            m_Image = m_AstrometryController.GetCurrentAstroPlate();
            m_Image.EffectiveFocalLength = m_FLength;

            if (m_SolvedPlate is LeastSquareFittedAstrometry)
                m_SolvedPlate = new LeastSquareFittedAstrometry(m_Image, m_RADegCenter, m_DEDegCenter, null /*m_SolvePlateConts*/);
            else if (m_SolvedPlate is TangentalTransRotAstrometry)
                m_SolvedPlate = new TangentalTransRotAstrometry(m_SolvedPlate as TangentalTransRotAstrometry, m_Image, m_RADegCenter, m_DEDegCenter, m_Eta);
            else
            {
                m_SolvedPlate = new DirectTransRotAstrometry(m_Image, m_RADegCenter, m_DEDegCenter, m_Eta, m_Aspect);
            }
        }
Beispiel #20
0
        public ThreeStarAstrometry(AstroPlate image, Dictionary<ImagePixel, IStar> userStarIdentification, int tolerance)
        {
            if (userStarIdentification.Count != 3)
                throw new InvalidOperationException();

            Image = image;

            double a0 = userStarIdentification.Values.Average(x => x.RADeg) * DEG_TO_RAD;
            double d0 = userStarIdentification.Values.Average(x => x.DEDeg) * DEG_TO_RAD;
            double corr = double.MaxValue;
            int attempts = 0;

            do
            {
                SafeMatrix AX = new SafeMatrix(3, 3);
                SafeMatrix X = new SafeMatrix(3, 1);
                SafeMatrix AY = new SafeMatrix(3, 3);
                SafeMatrix Y = new SafeMatrix(3, 1);

                int i = 0;
                foreach (var pixel in userStarIdentification.Keys)
                {
                    IStar star = userStarIdentification[pixel];
                    double a = star.RADeg * DEG_TO_RAD;
                    double d = star.DEDeg * DEG_TO_RAD;

                    AX[i, 0] = pixel.XDouble;
                    AX[i, 1] = pixel.YDouble;
                    AX[i, 2] = 1;
                    AY[i, 0] = pixel.XDouble;
                    AY[i, 1] = pixel.YDouble;
                    AY[i, 2] = 1;

                    X[i, 0] = Math.Cos(d) * Math.Sin(a - a0) / (Math.Cos(d0) * Math.Cos(d) * Math.Cos(a - a0) + Math.Sin(d0) * Math.Sin(d));
                    Y[i, 0] = (Math.Cos(d0) * Math.Sin(d) - Math.Cos(d) * Math.Sin(d0) * Math.Cos(a - a0)) / (Math.Sin(d0) * Math.Sin(d) + Math.Cos(d0) * Math.Cos(d) * Math.Cos(a - a0));

                    i++;
                }

                SafeMatrix a_T = AX.Transpose();
                SafeMatrix aa = a_T * AX;
                SafeMatrix aa_inv = aa.Inverse();
                SafeMatrix bx = (aa_inv * a_T) * X;

                m_A = bx[0, 0];
                m_B = bx[1, 0];
                m_C = bx[2, 0];

                a_T = AY.Transpose();
                aa = a_T * AY;
                aa_inv = aa.Inverse();
                bx = (aa_inv * a_T) * Y;

                m_D = bx[0, 0];
                m_E = bx[1, 0];
                m_F = bx[2, 0];

                m_A0Rad = a0;
                m_D0Rad = d0;

                double ra_c, de_c;
                GetRADEFromImageCoords(Image.CenterXImage, Image.CenterYImage, out ra_c, out de_c);

                corr = AngleUtility.Elongation(ra_c, de_c, a0 * RAD_TO_DEG, d0 * RAD_TO_DEG) * 3600;
                a0 = ra_c * DEG_TO_RAD;
                d0 = de_c * DEG_TO_RAD;
                attempts++;
            }
            while (corr > tolerance && attempts < MAX_ATTEMPTS);

            Success = corr <= tolerance;
        }
        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;
        }
Beispiel #22
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;
		}
Beispiel #23
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));
		}
Beispiel #24
0
        public AstroPlate GetCurrentAstroPlate()
        {
            CCDMatrix matrix;

            if (AstrometryContext.Current.VideoCamera == null)
            {
                // This is used for the case where no configuration has been loaded.
                matrix = new CCDMatrix(1, 1, TangraContext.Current.FrameWidth, TangraContext.Current.FrameHeight);
            }
            else
                matrix = new CCDMatrix(
                    AstrometryContext.Current.VideoCamera.CCDMetrics.CellWidth,
                    AstrometryContext.Current.VideoCamera.CCDMetrics.CellHeight,
                    AstrometryContext.Current.VideoCamera.CCDMetrics.MatrixWidth,
                    AstrometryContext.Current.VideoCamera.CCDMetrics.MatrixHeight);

            AstroPlate image = new AstroPlate(matrix, TangraContext.Current.FrameWidth, TangraContext.Current.FrameHeight, m_VideoController.VideoBitPix);

            if (AstrometryContext.Current.PlateConstants != null)
            {
                image.EffectivePixelWidth = AstrometryContext.Current.PlateConstants.EffectivePixelWidth;
                image.EffectivePixelHeight = AstrometryContext.Current.PlateConstants.EffectivePixelHeight;
                image.EffectiveFocalLength = AstrometryContext.Current.PlateConstants.EffectiveFocalLength;
            }

            return image;
        }
Beispiel #25
0
        public ThreeStarFit(
			AstroPlate image,
			StarPair pair1,
			StarPair pair2,
			StarPair pair3)
        {
            m_Image = image;

            // X1 = a*x1 + b*y1 + c
            // Y1 = d*x1 + e*y1 + f
            // X2 = a*x2 + b*y2 + c
            // Y2 = d*x2 + e*y2 + f
            // X3 = a*x3 + b*y3 + c
            // Y3 = d*x3 + e*y3 + f

            // NOTE: First do a SimpleRaDec fit to get the RA0/DE0

            double DX12 = pair1.RADeg - pair2.RADeg;
            double DX23 = pair2.RADeg - pair3.RADeg;
            double DY12 = pair1.DEDeg - pair2.DEDeg;
            double DY23 = pair2.DEDeg - pair3.DEDeg;
            double dx12 = pair1.XImage - pair2.XImage;
            double dx23 = pair2.XImage - pair3.XImage;
            double dy12 = pair1.YImage - pair2.YImage;
            double dy23 = pair2.YImage - pair3.YImage;

            // Singularity
            if (DX12 * DX23 * DY12 * DY23 * dx12 * dx23 * dy12 * dy23 == 0)
            {
                m_IsSingularity = true;
                return;
            }

            m_A = (DX12 * dy23 - DX23 * dy12) / (dx12 * dy23 - dx23 * dy12);
            m_B = (DX12 - m_A * dx12) / dy12;
            m_C = pair1.RADeg - m_A * pair1.XImage - m_B * pair1.YImage;
            m_D = (DY12 * dy23 - DY23 * dy12) / (dx12 * dy23 - dx23 * dy12);
            m_E = (DY12 - m_D * dx12) / dy12;
            m_F = pair1.DEDeg - m_D * pair1.XImage - m_E * pair1.YImage;

            m_RA0Deg = m_A * m_Image.CenterXImage + m_B * m_Image.CenterYImage + m_C;
            m_DE0Deg = m_D * m_Image.CenterXImage + m_E * m_Image.CenterYImage + m_F;

            // NOTE: Then do the Tangental solution

            TangentPlane.CelestialToTangent(pair1.RADeg, pair1.DEDeg, m_RA0Deg, m_DE0Deg, out pair1.XTangent, out pair1.YTangent);
            TangentPlane.CelestialToTangent(pair2.RADeg, pair2.DEDeg, m_RA0Deg, m_DE0Deg, out pair2.XTangent, out pair2.YTangent);
            TangentPlane.CelestialToTangent(pair3.RADeg, pair3.DEDeg, m_RA0Deg, m_DE0Deg, out pair3.XTangent, out pair3.YTangent);

            DX12 = pair1.XTangent - pair2.XTangent;
            DX23 = pair2.XTangent - pair3.XTangent;
            DY12 = pair1.YTangent - pair2.YTangent;
            DY23 = pair2.YTangent - pair3.YTangent;

            m_A = (DX12 * dy23 - DX23 * dy12) / (dx12 * dy23 - dx23 * dy12);
            m_B = (DX12 - m_A * dx12) / dy12;
            m_C = pair1.XTangent - m_A * pair1.XImage - m_B * pair1.YImage;
            m_D = (DY12 * dy23 - DY23 * dy12) / (dx12 * dy23 - dx23 * dy12);
            m_E = (DY12 - m_D * dx12) / dy12;
            m_F = pair1.YTangent - m_D * pair1.XImage - m_E * pair1.YImage;

            m_A1 = m_E / (m_E * m_A - m_B * m_D);
            m_B1 = -m_B / (m_E * m_A - m_B * m_D);
            m_C1 = (m_B * m_F - m_C * m_E) / (m_E * m_A - m_B * m_D);
            m_D1 = m_D / (m_B * m_D - m_A * m_E);
            m_E1 = -m_A / (m_B * m_D - m_A * m_E);
            m_F1 = (m_A * m_F - m_C * m_D) / (m_B * m_D - m_A * m_E);

            m_IsSolved = true;
        }