public bool Filter(Tracklet Input) { double EqVelR = MinEqVel * Math.PI / 38880000; if (Input.Velocity.SphericalVelocity < EqVelR) { return(false); } double SqS = 0; foreach (ImageDetection imd1 in Input.Detections) { foreach (ImageDetection imd2 in Input.Detections) { if (imd1 != imd2) { double dX = imd1.Barycenter.PP.X - imd2.Barycenter.PP.X; double dY = imd1.Barycenter.PP.Y - imd2.Barycenter.PP.Y; SqS += dX * dX + dY * dY; } } } if (SqS < MinPixDistance * MinPixDistance * Input.Detections.Length * (Input.Detections.Length - 1)) { return(false); } return(true); }
/// <summary> /// Tries pairing a tracklet (if it contains a detection in the time range of the image). /// </summary> /// <param name="t">Tracklet.</param> /// <param name="Separation">Maximum distance to consider, in arcseconds.</param> public void TryPair(Tracklet t, double Separation) { Separation *= Math.PI / 180 / 3600; if (!t.TryFetchProperty(out ObjectIdentity obid)) { obid = new ObjectIdentity(); } bool NamesPresent = false; foreach (ImageDetection imd in t.Detections) { if (Math.Abs((imd.Time.Time - ShotTime).TotalSeconds) < Exposure.TotalSeconds) { List <SkybotObject> Objects = ObjTree.Query(imd.Barycenter.EP.RA, imd.Barycenter.EP.Dec, Separation); foreach (SkybotObject so in Objects) { obid.AddName(so.Name, so.PermanentDesignation, so.Position ^ imd.Barycenter.EP); Unpaired.Remove(so); NamesPresent = true; } } } if (NamesPresent) { t.SetResetProperty(obid); } }
void addToTracklets(ref sl.Objects objects) { ulong current_timestamp = objects.timestamp; for (int i = 0; i < objects.numObject; i++) { sl.ObjectData obj = objects.objectData[i]; int id = obj.id; if ((obj.objectTrackingState != sl.OBJECT_TRACKING_STATE.OK) || float.IsInfinity(obj.position.X)) { continue; } bool new_object = true; foreach (Tracklet track in tracklets) { if (track.id == id && track.is_alive) { new_object = false; track.addDetectedPoint(obj, current_timestamp, smoothing_window_size); } } // In case this object does not belong to existing tracks if (new_object) { Tracklet new_track = new Tracklet(obj, obj.label, current_timestamp); tracklets.Add(new_track); } } }
/// <summary> /// Function for looking up the names of objects. /// </summary> /// <param name="ArcLengthSec">Lookup radius.</param> private void SkyBotLookupNames(double ArcLengthSec) { lock (m_tracklets) { foreach (IO.Image img in OriginalImageCube) { SkyBotImageData skid = img.GetProperty <SkyBotImageData>(); foreach (Tracklet tk in CurrentTracklets) { skid.TryPair(tk, ArcLengthSec); } } for (int i = 0; i < m_tracklets.Count; i++) { for (int j = 0; j < m_tracklets[i].Count; j++) { Tracklet tk = m_tracklets[i][j]; ObjectIdentity objid; if (!tk.TryFetchProperty(out objid)) { objid = new ObjectIdentity(); } objid.ComputeNamescoreWithDefault(tk, null, ReportFieldName, CCDNumbers[i], j); tk.SetResetProperty(objid); } } } this.Invoke((Action)RefreshTrackletList); }
/// <summary> /// Computes <see cref="NameScore"/> and attempts to set <see cref="Name"/>. /// Uses the provided <paramref name="Default"/> name as the lowest priority option. /// Can compute <paramref name="Default"/> from <paramref name="FieldName"/>, <paramref name="ObjNum"/> and optionally <paramref name="CCD"/>. /// If no <paramref name="Default"/> is given and it cannot be computed, skips using a default name. /// </summary> /// <remarks> /// If no <paramref name="CCD"/> value is given, generates object names as FieldName + ObjectNumber base 10 (3 digits). /// If <paramref name="CCD"/> is non-null, then generates name as FieldName + CCD base-62 (1 digit) + ObjectNumber (packed). /// </remarks> /// <param name="t">Tracklet to be named.</param> /// <param name="Default">Default name. If null, it is generated from the next parameters. Otherwise, the other parameters can be null.</param> /// <param name="FieldName">Field name. Must be 4 characters long.</param> /// <param name="CCD">CCD Number. If present, uses the MPC 0-9, A-Z, a-z packing for both the CCD and the object number.</param> /// <param name="ObjNum">Object number.</param> public void ComputeNamescoreWithDefault(Tracklet t, string Default = null, string FieldName = null, int?CCD = null, int?ObjNum = null) { if (Default == null & FieldName != null & ObjNum.HasValue && FieldName.Length == 4) { if (CCD.HasValue) { try { Default = FieldName + GetB62Char(CCD.Value) + GetObjNumber(ObjNum.Value); } catch { Default = null; } } else { Default = FieldName + ObjNum.Value.ToString("000"); } } if (Default != null) { NameScore.Add(Default, NScore + 1); ObjIDs[Default] = null; } ComputeNamescore(t); if (Name == Default) { PackedPD = Default; } }
double ComputePearsonR(Tracklet Input) { if (Input.VelReg.R_TR * Input.VelReg.R_TR < TimeRsquared) { return(0); } if (Input.VelReg.R_TD * Input.VelReg.R_TD < TimeRsquared) { return(0); } List <EquatorialPoint> Points = new List <EquatorialPoint>(); double MeanR = 0; int count = 0; bool IsDot = false; /* Computes the PearsonR for each source and takes the mean */ foreach (ImageDetection md in Input.Detections) { if (md != null) { if (md.TryFetchProperty(out ObjectPoints op)) { var EqP = op.EquatorialPoints; Points.AddRange(EqP); var mlinr = Misc.LinearRegression.ComputeLinearRegression(EqP.Select((x) => x.RA).ToArray(), EqP.Select((x) => x.Dec).ToArray()); MeanR += Math.Abs(mlinr.PearsonR); count++; if (md.TryFetchProperty(out PairingProperties PairProp)) { if (PairProp.IsDotDetection) { IsDot = true; } } } else { IsDot = true; count++; Points.Add(md.Barycenter.EP); } } } MeanR /= count; /* If not line-like but not a dot detection, drop */ if (!IsDot && MeanR < IndividualRsquared) { return(0); } var LRP = Misc.LinearRegression.ComputeLinearRegression(Points.Select((x) => x.RA).ToArray(), Points.Select((x) => x.Dec).ToArray()); double RR = Math.Abs(LRP.PearsonR); if (IsDot) { RR += (1 - Math.Abs(MeanR)) / Input.Velocity.ArcSecMin; } return(RR); }
public bool Filter(Tracklet Input) { double MxER = MaxError * Math.PI / 180 / 3600; double SS = Input.VelReg.S_TD + Input.VelReg.S_TR; if (SS > MxER * MxER) { return(false); } return(true); }
void ViewObjectProperties() { Tracklet tk = CurrentTracklets[SelectedTracklet]; PropertyViewer pw = new PropertyViewer("Tracklet", tk); pw.AddProperties("Tracklet", tk.VelReg, tk.Velocity); foreach (var det in tk.Detections) { pw.AddObject("Detection at " + det.Time.Time, det); } pw.ShowProperties(); pw.Show(); }
private void PairSkyBot(List <Tracklet> Tracklets, double ArcLengthSec, string ReportFieldName, int CCDNumber, FitsImage[] ImageSet, Step.StepPipeline Pipeline) { foreach (Image img in ImageSet) { SkyBotImageData skid = img.GetProperty <SkyBotImageData>(); //skid.RetrieveObjects(ObservatoryCode); foreach (Tracklet tk in Tracklets) { skid.TryPair(tk, ArcLengthSec); } var unp = skid.GetUnpaired(); if (unp.Count != 0) { Logger("SkyBoT: Unpaired objects left: "); foreach (var o in unp) { string SkData = "SkyBoT: " + ExtraIO.EquatorialPointStringFormatter.FormatToString(o, ExtraIO.EquatorialPointStringFormatter.Format.MPC); PixelPoint pp = img.Transform.GetPixelPoint(o); SkData += ";" + pp.ToString(); Logger(SkData); var Reasons = Pipeline.QueryWhyNot(o, 5); string LRs = "Reasons: "; foreach (string x in Reasons) { LRs += x + ";"; } if (Reasons.Count == 0) { Logger("Not found in removal log, so not detected."); } else { Logger(LRs); } } } } for (int i = 0; i < Tracklets.Count; i++) { Tracklet tk = Tracklets[i]; if (!tk.TryFetchProperty(out ObjectIdentity objid)) { objid = new ObjectIdentity(); } objid.ComputeNamescoreWithDefault(tk, null, ReportFieldName, CCDNumber, i); tk.SetResetProperty(objid); } }
void detectUnchangedTrack(ulong current_timestamp) { for (int track_index = 0; track_index < tracklets.Count; ++track_index) { Tracklet track = tracklets[track_index]; if (track.last_detected_timestamp < current_timestamp && track.last_detected_timestamp > 0) { // If track missed more than N frames, delete it if (current_timestamp - track.last_detected_timestamp >= history_duration) { track.is_alive = false; continue; } } } }
/// <summary> /// Finds the (if there is any) name of the object. /// </summary> /// <param name="t">Tracklet to process.</param> /// <param name="NamesTree">QuadTree of SkyBoT objects.</param> /// <param name="Separation">Maximum distance between SkyBoT object and detection at which they are considered the same object. Value in radians.</param> static void PairTracklet(Tracklet t, QuadTree <SkybotObject> NamesTree, double Separation) { foreach (ImageDetection m in t.Detections) { if (m != null) { List <SkybotObject> Objects = NamesTree.Query(m.Barycenter.EP.RA, m.Barycenter.EP.Dec, Separation); List <SkybotObject> Selected = Objects.Where((x) => x.TimeCoordinate == m.Time.Time && (x.Position ^ m.Barycenter.EP) < Separation).ToList(); if (Selected.Count == 1) { m.SetResetProperty(new ObjectIdentity() { Name = Objects[0].Name }); } } } }
/// <summary>Computes <see cref="NameScore"/> and attempts to set <see cref="Name"/>.</summary> public void ComputeNamescore(Tracklet t) { string XName = null; double CScore = -1; foreach (var kvp in Distances) { double Mean = kvp.Value / Counts[kvp.Key]; double XScore = Math.Pow(2, Counts[kvp.Key] * 0.5) / (Arc1Sec + Mean); double MaxScore = Math.Pow(2, 0.5 * t.Detections.Count((x) => x != null)) / Arc1Sec; double Score = 100 * XScore / MaxScore; if (Score > 1) { NameScore.Add(kvp.Key, (int)Score); } } foreach (var kvp in NameScore) { if (kvp.Value > CScore) { CScore = kvp.Value; XName = kvp.Key; } } if (CScore > NScore) { Name = XName; MPN = ObjIDs[Name]; if (MPN.HasValue) { PackMPN(); } if (ProvisionalDesignationMatcher.IsMatch(Name)) { PackedPD = PackPD(Name); } } }
public bool Filter(Tracklet Input) { double R = ComputePearsonR(Input); return(R * R > LineRsquared); }
/// <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); } }