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); }
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; }
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); } }
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); } }
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; }
public PlateConstantsSolver(AstroPlate plateConfig) { m_PlateConfig = plateConfig; }
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; }
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; }
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); } }
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; }
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 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 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; }
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; }