public List <string> QueryWhyNot(string RA_Dec, double ArcSecLook) { ArcSecLook *= Math.PI / 180 / 3600; EquatorialPoint eqp = Umbrella2.Pipeline.ExtraIO.EquatorialPointStringFormatter.ParseFromMPCString(RA_Dec); List <string> r = new List <string>(); foreach (var kvp in RemovalPoints) { if ((kvp.Key ^ eqp) < ArcSecLook) { r.Add(kvp.Value); } } if (r.Count == 0) { foreach (var d in AllDetections) { if ((d.Barycenter ^ eqp) < ArcSecLook) { r.Add("Post-filtering (recovery)"); } } } return(r); }
/// <summary> /// Preloads stars into the search structures. /// </summary> /// <param name="Detections">Stars.</param> public void LoadStars(List <Star> Detections) { if (DetectionPool != null) { throw new NotSupportedException("Cannot modify the detection pool after it is generated"); } PoolList.AddRange(Detections); foreach (Star md in Detections) { EquatorialPoint ep = md.EqCenter; if (ep.Dec < Topmost) { Topmost = ep.Dec; } if (ep.Dec > Lowermost) { Lowermost = ep.Dec; } if (ep.RA < Leftmost) { Leftmost = ep.RA; } if (ep.RA > Rightmost) { Rightmost = ep.RA; } if (md.PixRadius > MaxRadius) { MaxRadius = md.PixRadius; } } }
/// <summary> /// Preloads detections into the search structures. /// </summary> /// <param name="Detections">Detected sources.</param> public void LoadDetections(List <ImageDetection> Detections) { if (DetectionPool != null) { throw new NotSupportedException("Cannot modify the detection pool after it is generated"); } PoolList.AddRange(Detections); foreach (ImageDetection md in Detections) { EquatorialPoint ep = md.Barycenter.EP; if (ep.Dec < Topmost) { Topmost = ep.Dec; } if (ep.Dec > Lowermost) { Lowermost = ep.Dec; } if (ep.RA < Leftmost) { Leftmost = ep.RA; } if (ep.RA > Rightmost) { Rightmost = ep.RA; } } }
/// <summary> /// Removes fixed stars from a list of detections. /// </summary> /// <returns>Reduced detections.</returns> /// <param name="Input">Raw detections.</param> public List <ImageDetection> Reduce(List <ImageDetection> Input) { List <ImageDetection> N = new List <ImageDetection>(); double PR = PairingRadius * Math.PI / 180 / 3600; foreach (ImageDetection imd in Input) { EquatorialPoint p = imd.Barycenter.EP; double XPR = PR + MaxRadius * imd.ParentImage.Transform.GetEstimatedWCSChainDerivative(); var P = DetectionPool.Query(p.RA, p.Dec, XPR); List <Star> spP = new List <Star>(); foreach (Star s in P) { double SR = s.PixRadius * imd.ParentImage.Transform.GetEstimatedWCSChainDerivative(); if (SR + PR > (s.EqCenter ^ p)) { spP.Add(s); } } if (spP.Count == 0) { N.Add(imd); } } return(N); }
/// <summary> /// Formats point to string. /// </summary> /// <param name="Point">Point to apply to.</param> /// <param name="OutputFormat">String output format.</param> /// <returns>A formatted string containing the coordinates of the input point.</returns> public static string FormatToString(this EquatorialPoint Point, Format OutputFormat) { switch (OutputFormat) { case Format.MPC: return(RASexa(Point.RA) + " " + DecSexa(Point.Dec)); case Format.MPC_RA: return(RASexa(Point.RA)); case Format.MPC_Dec: return(DecSexa(Point.Dec)); case Format.MPC_Tab: return(RASexa(Point.RA) + "\t" + DecSexa(Point.Dec)); case Format.RadSpace: return(Point.RA.ToString() + " " + Point.Dec.ToString()); case Format.RadExplicit: return("RA=" + Point.RA.ToString() + " " + "Dec=" + Point.Dec.ToString()); default: throw new ArgumentOutOfRangeException(nameof(OutputFormat)); } }
/// <summary> /// Preloads detections into the search structures. /// </summary> /// <param name="Detections">Detected sources.</param> public void LoadDetections(List <ImageDetection> Detections) { if (DetectionPool != null) { throw new NotSupportedException("Cannot modify the detection pool after it is generated"); } PoolList.AddRange(Detections); foreach (ImageDetection md in Detections) { EquatorialPoint ep = md.Barycenter.EP; if (ep.Dec < Topmost) { Topmost = ep.Dec; } if (ep.Dec > Lowermost) { Lowermost = ep.Dec; } if (ep.RA < Leftmost) { Leftmost = ep.RA; } if (ep.RA > Rightmost) { Rightmost = ep.RA; } if (!ObsTimes.Any((x) => Math.Abs((md.Time.Time - x).TotalSeconds) < .1)) { ObsTimes.Add(md.Time.Time); } } }
/// <summary> /// Recovers the tracklet on a given set of images (typically pipeline input ones). /// </summary> /// <returns><c>true</c>, if tracklet was recovered, <c>false</c> otherwise.</returns> /// <param name="tvr"><see cref="TrackletVelocityRegression"/> from which the positions are computed.</param> /// <param name="InputImages">Images on which to perform the recovery.</param> /// <param name="Recovered">Recovered tracklet.</param> public bool RecoverTracklet(TrackletVelocityRegression tvr, IEnumerable <Image> InputImages, out Tracklet Recovered) { List <ImageDetection> Detections = new List <ImageDetection>(); foreach (Image img in InputImages) { /* Compute location */ ObservationTime obTime = img.GetProperty <ObservationTime>(); double Secs = (obTime.Time - tvr.ZeroTime).TotalSeconds; EquatorialPoint eqp = new EquatorialPoint() { RA = tvr.P_TR.Slope * Secs + tvr.P_TR.Intercept, Dec = tvr.P_TD.Slope * Secs + tvr.P_TD.Intercept }; Position p = new Position(eqp, img.Transform.GetPixelPoint(eqp)); /* Perform recovery */ if (RecoverDetection(p, img, RecoverRadius, InputImages, out ImageDetection RecD)) { Detections.Add(RecD); } } if (Detections.Count >= MinDetections) { Recovered = StandardTrackletFactory.CreateTracklet(Detections.ToArray()); return(true); } else { Recovered = null; return(false); } }
/// <summary> /// Retrieves a list of reference stars around a given position. /// </summary> /// <param name="Center">Location around which to search.</param> /// <param name="Radius">Radius (in radians) of the search cone.</param> /// <param name="LowMagLimit">Lowest star magnitude to include in results.</param> /// <returns>A list of StarInfo containing the data of the reference stars.</returns> public static List <StarInfo> GetVizieRObjects(EquatorialPoint Center, double Radius, double LowMagLimit) { double RadiusArcMin = Radius * 180 * 60 / Math.PI; string URL = VizieRURL + Center.FormatToString(EquatorialPointStringFormatter.Format.MPC) + "&-c.r=" + RadiusArcMin.ToString("0.00"); string Data = ""; using (WebClient client = new WebClient()) try { client.Proxy = null; Data = client.DownloadString(URL); } catch (WebException) { return(new List <StarInfo>()); } string[] lines = Data.Split('\n'); int i; List <string[]> objsString = new List <string[]>(); /* Skip to beginning of table */ for (i = 0; i < lines.Length; i++) { if (lines[i].StartsWith("----")) { break; } } /* Read each line and split values (table is TSV) */ for (i++; i < lines.Length; i++) { objsString.Add(lines[i].Split('\t')); } List <StarInfo> sti = new List <StarInfo>(objsString.Count); /* Foreach entry */ foreach (string[] sk in objsString) { /* Check if it matches the 14-entry format recognized */ if (sk.Length != 14) { continue; } /* The next 3 should be in order: */ sk[1] = sk[1].Trim(); /* RA */ sk[2] = sk[2].Trim(); /* Dec */ sk[12] = sk[12].Trim(); /* R2mag */ if (string.IsNullOrEmpty(sk[1]) | string.IsNullOrEmpty(sk[2]) | string.IsNullOrEmpty(sk[12])) { continue; } StarInfo sif = new StarInfo(); double RA = double.Parse(sk[1]) * Math.PI / 180; double Dec = double.Parse(sk[2]) * Math.PI / 180; EquatorialPoint EqP = new EquatorialPoint() { RA = RA, Dec = Dec }; sif.Coordinate = EqP; sif.Magnitude = double.Parse(sk[12]); sti.Add(sif); } return(sti.Where((x) => x.Magnitude < LowMagLimit).ToList()); }
/// <summary> /// Generates an URL for the non-standard interface to SkyBoT. /// </summary> /// <returns>The URL to be used with <see cref="GetObjects(string, DateTime, out List{SkybotObject})"/>.</returns> /// <param name="Location">Location around which to search.</param> /// <param name="Radius">Search radius.</param> /// <param name="Time">The time at which to search for objects.</param> /// <param name="ObsCode">Observatory code.</param> public static string GenerateNSUrl(EquatorialPoint Location, double Radius, DateTime Time, string ObsCode) { double JulianDate = (Time - new DateTime(1970, 1, 1, 0, 0, 0)).TotalDays + 2440587.5; string Params = string.Format(NSParameters, JulianDate, (Location.RA * 180 / Math.PI), (Location.Dec * 180 / Math.PI), (Radius * 180 / Math.PI), ObsCode); return(NSInterface + Params); }
public void TryPairDot(ImageDetection a, ImageDetection b) { if (a.FetchProperty <PairingProperties>().IsPaired || b.FetchProperty <PairingProperties>().IsPaired) { return; } TimeSpan DeltaTime = b.Time.Time - a.Time.Time; var Line = b.Barycenter.EP - a.Barycenter.EP; double PairEstimatedDistance = ~Line; if (PairEstimatedDistance > MaxVDD * DeltaTime.TotalMinutes) { return; } if (PairEstimatedDistance < MinVDD * DeltaTime.TotalMinutes) { return; } double PairEstimatedDistanceError = 2 * (a.FetchProperty <ObjectSize>().PixelEllipse.SemiaxisMajor + b.FetchProperty <ObjectSize>().PixelEllipse.SemiaxisMajor); PairEstimatedDistanceError *= a.ParentImage.Transform.GetEstimatedWCSChainDerivative(); double PairEstimatedVelocity = PairEstimatedDistance / DeltaTime.TotalSeconds; double PairEstimatedVelocityError = PairEstimatedDistanceError / DeltaTime.TotalSeconds; List <List <ImageDetection> > DetectedInPool = new List <List <ImageDetection> >(); List <ImageDetection[]> DIPAr = new List <ImageDetection[]>(); foreach (DateTime dt in ObsTimes) { TimeSpan tsp = dt - b.Time.Time; double EstDistance = PairEstimatedVelocity * tsp.TotalSeconds; double EstDistError = Math.Abs(PairEstimatedVelocityError * tsp.TotalSeconds) + PairEstimatedDistanceError; EquatorialPoint EstimatedPoint = Line + EstDistance; var DetectionsList = DetectionPool.Query(EstimatedPoint.RA, EstimatedPoint.Dec, EstDistError); DetectionsList.RemoveAll((x) => ((x.Barycenter.EP ^ EstimatedPoint) > EstDistError) || (x.Time.Time != dt) || !x.FetchProperty <PairingProperties>().IsDotDetection); //DetectedInPool.Add(DetectionsList); DIPAr.Add(DetectionsList.ToArray()); } int i, c = 0; for (i = 0; i < DIPAr.Count; i++) { if (DIPAr[i].Length != 0) { c++; } } if (c >= 3) { CandidatePairings.Add(DIPAr.ToArray()); foreach (ImageDetection[] mdl in DIPAr) { foreach (ImageDetection m in mdl) { m.FetchProperty <PairingProperties>().IsPaired = true; } } } }
/// <summary> /// Generates an URL for the Simple Cone Search interface, to be used with <see cref="GetObjects(string, DateTime, out List{SkybotObject})"/>. /// </summary> /// <returns>The URL to be used with <see cref="GetObjects(string, DateTime, out List{SkybotObject})"/>.</returns> /// <param name="Location">Location around which to search.</param> /// <param name="Radius">Search radius.</param> /// <param name="Time">The time at which to search for objects.</param> public static string GenerateSCSUrl(EquatorialPoint Location, double Radius, DateTime Time) { string url = SkybotURL; double JulianDate = (Time - new DateTime(1970, 1, 1, 0, 0, 0)).TotalDays + 2440587.5; url += JulianDate.ToString() + "&RA=" + (Location.RA * 180 / Math.PI).ToString() + "&DEC=" + (Location.Dec * 180 / Math.PI).ToString(); url += "&SR=" + (Radius * 180 / Math.PI).ToString() + "&VERB=1"; return(url); }
public SkybotObject(string Name, string Position, DateTime Time, int?PermDesignation, string Class, double magV, double ErrPos) { this.Name = Name; this.Position = EquatorialPointStringFormatter.ParseFromMPCString(Position); this.TimeCoordinate = Time; this.PermanentDesignation = PermDesignation; this.Class = Class; this.VisualMagnitude = magV; this.PositionUncertainty = ErrPos; }
/// <summary> /// Performs a median filter between multiple data sets. /// </summary> /// <param name="Inputs">Input data.</param> /// <param name="Output">Output data.</param> /// <param name="InputPositions">Input alignments.</param> /// <param name="OutputPosition">Output alignment.</param> /// <param name="empty">Dummy argument.</param> static void MultiImageMedianFilter(double[][,] Inputs, double[,] Output, SchedCore.ImageSegmentPosition[] InputPositions, SchedCore.ImageSegmentPosition OutputPosition, object empty) { PixelPoint[] InputAlignments = InputPositions.Select((x) => x.Alignment).ToArray(); PixelPoint OutputAlignment = OutputPosition.Alignment; IWCSProjection[] InputImagesTransforms = InputPositions.Select((x) => x.WCS).ToArray(); IWCSProjection OutputImageTransform = OutputPosition.WCS; int OW = Output.GetLength(1); int OH = Output.GetLength(0); int i, j, k, c; double[] MedValues = new double[Inputs.Length]; PixelPoint pxp = new PixelPoint(); for (i = 0; i < OH; i++) { for (j = 0; j < OW; j++) { pxp.X = j + OutputAlignment.X; pxp.Y = i + OutputAlignment.Y; EquatorialPoint eqp = OutputImageTransform.GetEquatorialPoint(pxp); c = 0; for (k = 0; k < Inputs.Length; k++) { PixelPoint pyp = InputImagesTransforms[k].GetPixelPoint(eqp); pyp.X = Math.Round(pyp.X - InputAlignments[k].X); pyp.Y = Math.Round(pyp.Y - InputAlignments[k].Y); if (pyp.X < 0 || pyp.X >= Inputs[k].GetLength(1)) { continue; } if (pyp.Y < 0 || pyp.Y >= Inputs[k].GetLength(0)) { continue; } double dex = Inputs[k][(int)pyp.Y, (int)pyp.X]; MedValues[c] = dex; c++; } if (c == 0) { continue; } Array.Sort(MedValues); if (c % 2 == 1) { Output[i, j] = MedValues[c / 2]; } else { Output[i, j] = MedValues[c / 2 - 1]; } } } }
public override ProjectionPoint GetProjectionPoint(EquatorialPoint Point) { double CC = Sin(Point.Dec) * Sin(Dec) + Cos(Point.Dec) * Cos(Dec) * Cos(Point.RA - RA); double Xn = Cos(Point.Dec) * Sin(Point.RA - RA) / CC; double Yn = (Cos(Dec) * Sin(Point.Dec) - Sin(Dec) * Cos(Point.Dec) * Cos(Point.RA - RA)) / CC; return(new ProjectionPoint() { X = Xn, Y = Yn }); }
/// <summary> /// Returns the spherical distance between 2 points on the sphere. /// </summary> public static double GetDistance(EquatorialPoint A, EquatorialPoint B) { double DeltaPhi = A.Dec - B.Dec; double DeltaLambda = A.RA - B.RA; double HvPhi = Sin(DeltaPhi / 2); double HvLbd = Sin(DeltaLambda / 2); double HaverRoot = HvPhi * HvPhi + Cos(A.Dec) * Cos(B.Dec) * HvLbd * HvLbd; double Distance = 2 * Asin(Sqrt(HaverRoot)); return(Distance); }
/// <summary>Attempts to find a tracklet given 2 image detections (from separate images).</summary> void AnalyzePair(ImageDetection a, ImageDetection b) { /* Figure out line vector */ double SepSec = (b.Time.Time - a.Time.Time).TotalSeconds; LinearRegression.LinearRegressionParameters RAT = LinearRegression.ComputeLinearRegression(new double[] { 0, SepSec }, new double[] { a.Barycenter.EP.RA, b.Barycenter.EP.RA }); LinearRegression.LinearRegressionParameters DecT = LinearRegression.ComputeLinearRegression(new double[] { 0, SepSec }, new double[] { a.Barycenter.EP.Dec, b.Barycenter.EP.Dec }); /* Search for objects */ List <ImageDetection[]> Dects = new List <ImageDetection[]>(); foreach (DateTime dt in ObsTimes) { /* Compute estimated position */ TimeSpan tsp = dt - a.Time.Time; double tspSeconds = tsp.TotalSeconds; EquatorialPoint eqp = new EquatorialPoint() { RA = RAT.Intercept + RAT.Slope * tspSeconds, Dec = DecT.Intercept + DecT.Slope * tspSeconds }; /* Limit is given by a triangle with the maximum residuals */ List <ImageDetection> ImDL = FindSourcesAround(a, b, dt, eqp, SearchExtraSmall); if (ImDL.Count == 0) { ImDL = FindSourcesAround(a, b, dt, eqp, SearchExtraBig); } Dects.Add(ImDL.ToArray()); } /* If it can be found on at least 3 images, consider it a detection */ int i, c = 0; for (i = 0; i < Dects.Count; i++) { if (Dects[i].Length != 0) { c++; } } if (c >= 3) { CandidatePairings.Add(Dects.ToArray()); foreach (ImageDetection[] mdl in Dects) { foreach (ImageDetection m in mdl) { m.FetchOrCreate <PairingProperties>().IsPaired = true; } } } }
public override EquatorialPoint[] GetEquatorialPoints(ProjectionPoint[] Points) { EquatorialPoint[] EqP = new EquatorialPoint[Points.Length]; for (int i = 0; i < Points.Length; i++) { double X = Points[i].X; double Y = Points[i].Y; double Rho = Sqrt(X * X + Y * Y + ADDC); double C = Atan(Rho); EqP[i].RA = RA + Atan2(X, Cos(Dec) - Y * Sin(Dec)); EqP[i].Dec = Asin((Y * Cos(Dec) + Sin(Dec)) * Cos(C)); } return(EqP); }
/// <summary> /// Generates the great circle through the 2 given points. /// </summary> /// <param name="A">The positive direction of the great circle.</param> /// <param name="B">The origin of the great circle.</param> public GreatLine(EquatorialPoint A, EquatorialPoint B) { double sA = Cos(A.Dec), sB = Cos(B.Dec); this.A = new Vector3D() { X = sA * Cos(A.RA), Y = sA * Sin(A.RA), Z = Sin(A.Dec) }; this.B = new Vector3D() { X = sB * Cos(B.RA), Y = sB * Sin(B.RA), Z = Sin(B.Dec) }; AlphaAngle = GetDistance(A, B); }
/// <summary> /// Calibrate the zero point of the specified image. /// </summary> /// <returns>The Zero Point magnitude.</returns> /// <param name="Img">Image to calibrate.</param> /// <param name="Args">Calibration parameters.</param> /// <returns>The Zero Point magnitude.</returns> public static double CalibrateImage(Image Img, CalibrationArgs Args) { DotDetector StarDetector = new DotDetector() { HighThresholdMultiplier = Args.StarHighThreshold, LowThresholdMultiplier = Args.StarLowThreshold, MinPix = 15, NonrepresentativeThreshold = Args.NonRepThreshold }; StarDetector.Parameters.Xstep = 0; StarDetector.Parameters.Ystep = 200; var StList = StarDetector.DetectRaw(Img); var LocalStars = StList.Where((x) => x.Flux > Args.MinFlux & x.Flux < Args.MaxFlux).Where((x) => !x.PixelValues.Any((y) => y > Args.ClippingPoint)). Select((x) => new Star() { EqCenter = Img.Transform.GetEquatorialPoint(x.Barycenter), Flux = x.Flux, PixCenter = x.Barycenter }).ToList(); PixelPoint PixC = new PixelPoint() { X = Img.Width / 2, Y = Img.Height / 2 }; PixelPoint DiagF = new PixelPoint() { X = Img.Width, Y = Img.Height }; double Diag = Img.Transform.GetEquatorialPoint(new PixelPoint() { X = 0, Y = 0 }) ^ Img.Transform.GetEquatorialPoint(DiagF); EquatorialPoint EqCenter = Img.Transform.GetEquatorialPoint(PixC); List <StarInfo> RemoteStars = GetVizieRObjects(EqCenter, Diag / 2, Args.MaxVizierMag); for (int i = 0; i < RemoteStars.Count; i++) { for (int j = i + 1; j < RemoteStars.Count; j++) { if ((RemoteStars[i].Coordinate ^ RemoteStars[j].Coordinate) < Arc1Sec * Args.PositionError * DoubleStarRatio) { RemoteStars.RemoveAt(j); RemoteStars.RemoveAt(i); i--; break; } } } return(Calibrate(RemoteStars, LocalStars, Args.PositionError)); }
/// <summary> /// Computes the second minimum value of multiple images. /// </summary> /// <param name="Inputs">Input data.</param> /// <param name="Output">Output data.</param> /// <param name="InputPositions">Input alignments.</param> /// <param name="OutputPosition">Output alignment.</param> /// <param name="empty">Dummy argument.</param> static void SeMinFilter(double[][,] Inputs, double[,] Output, SchedCore.ImageSegmentPosition[] InputPositions, SchedCore.ImageSegmentPosition OutputPosition, object empty) { PixelPoint[] InputAlignments = InputPositions.Select((x) => x.Alignment).ToArray(); PixelPoint OutputAlignment = OutputPosition.Alignment; IWCSProjection[] InputImagesTransforms = InputPositions.Select((x) => x.WCS).ToArray(); IWCSProjection OutputImageTransform = OutputPosition.WCS; int OW = Output.GetLength(1); int OH = Output.GetLength(0); int i, j, k; PixelPoint pxp = new PixelPoint(); for (i = 0; i < OH; i++) { for (j = 0; j < OW; j++) { double Min = double.MaxValue, Min2 = double.MaxValue; pxp.X = j + OutputAlignment.X; pxp.Y = i + OutputAlignment.Y; EquatorialPoint eqp = OutputImageTransform.GetEquatorialPoint(pxp); for (k = 0; k < Inputs.Length; k++) { PixelPoint pyp = InputImagesTransforms[k].GetPixelPoint(eqp); pyp.X = Math.Round(pyp.X - InputAlignments[k].X); pyp.Y = Math.Round(pyp.Y - InputAlignments[k].Y); if (pyp.X < 0 || pyp.X >= Inputs[k].GetLength(1)) { continue; } if (pyp.Y < 0 || pyp.Y >= Inputs[k].GetLength(0)) { continue; } double dex = Inputs[k][(int)pyp.Y, (int)pyp.X]; if (dex < Min) { Min2 = Min; Min = dex; continue; } if (dex < Min2) { Min2 = dex; } } Output[i, j] = Min2; } } }
public static List <SkybotObject> GetObjects(EquatorialPoint Location, double Radius, DateTime Time) { /* Prepares the query */ string url = GenerateSCSUrl(Location, Radius, Time); string result = string.Empty; /* Tries querying the SkyBoT server, returining nothing if it fails. */ try { result = (new WebClient()).DownloadString(url); } catch { return(new List <SkybotObject>()); } /* Parsing Skybot output: specific selection of vot:TABLEDATA and namespace cleanup */ int sel1 = result.IndexOf("<vot:TABLEDATA>", StringComparison.InvariantCulture); if (sel1 == -1) { return(new List <SkybotObject>()); } string data = result.Substring(sel1); int sel2 = data.IndexOf("</vot:TABLEDATA>", StringComparison.InvariantCulture); data = data.Substring(0, sel2 + 16); data = data.Replace("vot:", ""); /* Parsing xml output */ XDocument xdoc = XDocument.Parse(data); List <SkybotObject> objs = new List <SkybotObject>(); XElement key = xdoc.Elements().ToArray()[0]; foreach (XElement xe in key.Elements()) { var z = xe.Elements().ToArray(); string permdes = z[0].Value; string name = z[1].Value; string ra = z[2].Value; string dec = z[3].Value; string cls = z[4].Value; int? pd = int.TryParse(permdes, out int pdi) ? (int?)pdi : null; SkybotObject oj = new SkybotObject(name, ra + " " + dec, Time, pd, cls, 0, 0); objs.Add(oj); } return(objs); }
/// <summary> /// Attempts to recover a detection on a given image, comparing with the entire set of exposures. /// </summary> /// <returns><c>true</c>, if detection was recovered, <c>false</c> otherwise.</returns> /// <param name="DetPos">Position of the detection to recover.</param> /// <param name="Img">Image on which to recover.</param> /// <param name="Radius">Maximum radius of the detection.</param> /// <param name="InputImages">Input images.</param> /// <param name="Recovered">Recovered detection.</param> public bool RecoverDetection(Position DetPos, Image Img, double Radius, IEnumerable <Image> InputImages, out ImageDetection Recovered) { Recovered = null; DotDetector.DotDetection dd = Recover(DetPos.PP, Radius, Img); if (dd.Pixels.Count < MinPix) { return(false); } int NoiseCnt = 0; int FixedCnt = 0; foreach (Image img in InputImages) { /* Noise scanner -- same position in pixel coordinates */ DotDetector.DotDetection detN = Recover(dd.Barycenter, Radius, img); PixelPoint npp = img.Transform.GetPixelPoint(Img.Transform.GetEquatorialPoint(dd.Barycenter)); /* Star scanner -- same position in equatorial coordinates */ DotDetector.DotDetection detF = Recover(npp, Radius, img); if (detN.Pixels.Count > NoisePixelThreshold * dd.Pixels.Count) { NoiseCnt++; } if (detF.Flux > StarFluxThreshold * dd.Flux) { EquatorialPoint org = DetPos.EP; EquatorialPoint nw = img.Transform.GetEquatorialPoint(detF.Barycenter); if ((org ^ nw) < MinMoveArcSec) { FixedCnt++; } } } if (NoiseCnt > CrossMatchRemove) { return(false); } if (FixedCnt > CrossMatchRemove) { return(false); } Recovered = StandardDetectionFactory.CreateDetection(Img, dd.Pixels, dd.PixelValues); return(true); }
/// <summary> /// Parses a MPC string into an EquatorialPoint. /// </summary> /// <param name="Point">MPC-style coordinate string.</param> /// <returns>EquatorialPoint with specified coordinates.</returns> public static EquatorialPoint ParseFromMPCString(string Point) { EquatorialPoint eqp = new EquatorialPoint(); string[] Components = Point.Split(' ', ':'); if (Components.Length != 6) { throw new FormatException(); } eqp.RA = Math.PI * ((double.Parse(Components[2]) / 60 + double.Parse(Components[1])) / 60 + double.Parse(Components[0])) / 12; if (Components[3][0] != '-') { eqp.Dec = Math.PI * ((double.Parse(Components[5]) / 60 + double.Parse(Components[4])) / 60 + double.Parse(Components[3])) / 180; } else { eqp.Dec = Math.PI * (double.Parse(Components[3]) - (double.Parse(Components[5]) / 60 + double.Parse(Components[4])) / 60) / 180; } return(eqp); }
/// <summary> /// Masks the input image with a given mask. Masked pixels are set to -1 standard deviation. /// </summary> /// <param name="Input">Input image data.</param> /// <param name="Output">Output image data.</param> /// <param name="InputPosition">Input data position.</param> /// <param name="OutputPosition">Output data position.</param> /// <param name="Properties">Mask data.</param> static void MaskImage(double[,] Input, double[,] Output, ImageSegmentPosition InputPosition, ImageSegmentPosition OutputPosition, MaskProperties Properties) { int Width = Output.GetLength(1); int Height = Output.GetLength(0); int i, j; PixelPoint pxp = new PixelPoint(); for (i = 0; i < Height; i++) { for (j = 0; j < Width; j++) { pxp.X = j + OutputPosition.Alignment.X; pxp.Y = i + OutputPosition.Alignment.Y; EquatorialPoint ep = OutputPosition.WCS.GetEquatorialPoint(pxp); PixelPoint mpt = Properties.MaskTransform.GetPixelPoint(ep); mpt.X = Math.Round(mpt.X); mpt.Y = Math.Round(mpt.Y); if (mpt.X < 0 || mpt.X >= Properties.MaskData[0].Length) { continue; } if (mpt.Y < 0 || mpt.Y >= Properties.MaskData.Length) { continue; } PixelPoint ipt = InputPosition.WCS.GetPixelPoint(ep); ipt.X = Math.Round(ipt.X - InputPosition.Alignment.X); ipt.Y = Math.Round(ipt.Y - InputPosition.Alignment.Y); if (Properties.MaskData[(int)mpt.Y][(int)mpt.X]) { Output[i, j] = -Properties.StDev; } else { Output[i, j] = Input[(int)ipt.Y, (int)ipt.X] - Properties.Mean; } } } }
/// <summary> /// Provides great circle navigation. /// </summary> /// <param name="A">Endpoint.</param> /// <param name="B">Startpoint.</param> /// <param name="Distance">Distance to navigate.</param> /// <returns>The point Distance away from B on the great circle defined by A and B.</returns> public static EquatorialPoint GetGreatCircleWaypoint(EquatorialPoint A, EquatorialPoint B, double Distance) { double sA = Cos(A.Dec), sB = Cos(B.Dec); Vector3D vA = new Vector3D() { X = sA * Cos(A.RA), Y = sA * Sin(A.RA), Z = Sin(A.Dec) }; Vector3D vB = new Vector3D() { X = sB * Cos(B.RA), Y = sB * Sin(B.RA), Z = Sin(B.Dec) }; double Alpha = GetDistance(A, B); double mA = -Sin(Distance) / Sin(Alpha); double mB = Sin(Distance + Alpha) / Sin(Alpha); Vector3D vCs = mA * vA + mB * vB; double RA = Atan2(vCs.Y, vCs.X); double Dec = Atan2(vCs.Z, Sqrt(vCs.X * vCs.X + vCs.Y * vCs.Y)); return(new EquatorialPoint() { RA = RA, Dec = Dec }); }
/// <summary>Creates the property.</summary> public SkyBotImageData(Image Image) : base(Image) { PixelPoint CPP = new PixelPoint() { X = Image.Width / 2, Y = Image.Height / 2 }; PixelPoint Corner1 = new PixelPoint() { X = 0, Y = 0 }; PixelPoint Corner2 = new PixelPoint() { X = Image.Width, Y = Image.Height }; ImageCenter = Image.Transform.GetEquatorialPoint(CPP); Radius = Image.Transform.GetEquatorialPoint(Corner1) ^ Image.Transform.GetEquatorialPoint(Corner2); Radius *= 0.55; ShotTime = Image.GetProperty <ObservationTime>().Time; Exposure = Image.GetProperty <ObservationTime>().Exposure; AssociatedImage = Image; }
public List <string> QueryWhyNot(EquatorialPoint Point, double ArcSecLook) { ArcSecLook *= Math.PI / 180 / 3600; List <string> r = new List <string>(); foreach (var kvp in RemovalPoints) { if ((kvp.Key ^ Point) < ArcSecLook) { r.Add(kvp.Value); } } if (r.Count == 0) { foreach (var d in AllDetections) { if ((d.Barycenter ^ Point) < ArcSecLook) { r.Add("Post-filtering (recovery)"); } } } return(r); }
static EquatorialPoint ComputeBoundingDisk(IEnumerable <Tracklet> Tracklets, out double Radius) { double RAmin = 100, RAmax = -100, DecMin = 100, DecMax = -100; foreach (Tracklet tk in Tracklets) { foreach (ImageDetection imd in tk.Detections) { EquatorialPoint q = imd.Barycenter.EP; if (q.RA < RAmin) { RAmin = q.RA; } if (q.RA > RAmax) { RAmax = q.RA; } if (q.Dec < DecMin) { DecMin = q.RA; } if (q.Dec > DecMax) { DecMax = q.RA; } } } double CenterRA = (RAmax + RAmin) / 2, CenterDec = (DecMax + DecMin) / 2; double DeltRA2 = (RAmax - RAmin) / 2, DeltDec2 = (DecMax - DecMin) / 2; Radius = RadiusMultiplier * Math.Sqrt(CenterRA * CenterRA + CenterDec * CenterDec); return(new EquatorialPoint() { RA = CenterRA, Dec = CenterDec }); }
public PixelPoint GetPixelPoint(EquatorialPoint Point) { return(LinearTransform.GetPixelPoint(ProjectionTransform.GetProjectionPoint(Point))); }
public abstract ProjectionPoint GetProjectionPoint(EquatorialPoint Point);