Beispiel #1
0
        /// <summary>
        /// Parses a Source Extractor catalog file.
        /// </summary>
        /// <returns>The detections in the catalog.</returns>
        /// <param name="Lines">Catalog file lines.</param>
        /// <param name="AssociatedImage">Image to which the catalog is associated to.</param>
        public static List <ImageDetection> ParseSEFile(IEnumerable <string> Lines, FitsImage AssociatedImage)
        {
            List <string>            ColList = new List <string>();
            Dictionary <string, int> Columns = new Dictionary <string, int>();
            List <ObsEntry>          Entries = new List <ObsEntry>();

            foreach (string Line in Lines)
            {
                if (Line[0] == '#')
                {
                    string[] Hdata = Line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                    if (Hdata[0] != "#")
                    {
                        throw new FormatException("Cannot understand SE file");
                    }
                    int    CNum  = int.Parse(Hdata[1]) - 1;
                    string CName = Hdata[2];
                    ColList.Add(CName);
                    Columns.Add(CName, CNum);
                }
                else
                {
                    string[] Ldata = Line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                    ObsEntry Entry = new ObsEntry();
                    Entry.Flux        = Parse(Columns, Ldata, "FLUX_AUTO");
                    Entry.Mag         = Parse(Columns, Ldata, "MAG_AUTO");
                    Entry.X           = Parse(Columns, Ldata, "X_IMAGE").Value;
                    Entry.Y           = Parse(Columns, Ldata, "Y_IMAGE").Value;
                    Entry.RA          = Parse(Columns, Ldata, "ALPHA_J2000").Value;
                    Entry.Dec         = Parse(Columns, Ldata, "DELTA_J2000").Value;
                    Entry.FWHM        = Parse(Columns, Ldata, "FWHM_IMAGE");
                    Entry.Ellipticity = Parse(Columns, Ldata, "ELLIPTICITY");
                    Entry.A           = Parse(Columns, Ldata, "A_IMAGE");
                    Entry.B           = Parse(Columns, Ldata, "B_IMAGE");
                    Entry.Flags       = (int)Parse(Columns, Ldata, "FLAGS");

                    if (!Entry.Flags.HasValue || Entry.Flags.Value < 4)
                    {
                        Entries.Add(Entry);
                    }
                }
            }
            List <ImageDetection> Detections = Entries.Select((x) => Transform(x, AssociatedImage)).ToList();

            return(Detections);
        }
Beispiel #2
0
        private void DetectionDebugMap(string RunDir, int i, List <ImageDetection> LocalDetectionList, FitsImage DetectionSource)
        {
            FICHV        Header   = DetectionSource.CopyHeader().ChangeBitPix(16);
            MMapFitsFile DeOutput = MMapFitsFile.OpenWriteFile(RunDir + "DOutMap" + i.ToString() + ".fits", Header.Header);
            FitsImage    DeOutIm  = new FitsImage(DeOutput);
            var          DeData   = DeOutIm.LockData(new System.Drawing.Rectangle(0, 0, (int)DetectionSource.Width, (int)DetectionSource.Height), false, false);


            foreach (ImageDetection xi in LocalDetectionList)
            {
                int kat = 200 + LocalDetectionList.IndexOf(xi);
                if (xi.TryFetchProperty(out ObjectPoints pts))
                {
                    foreach (var pt in pts.PixelPoints)
                    {
                        try { DeData.Data[(int)pt.Y, (int)pt.X] = kat; }
                        catch { break; }
                    }
                }
            }
            DeOutIm.ExitLock(DeData);
            Logger("Exported detections map");
        }
        public void RunPipeline <T>(PositionDependentMap <T> Map, string Name, int Number, ref FitsImage Pipeline, T Argument, AlgorithmRunParameters Parameters)
        {
            bool Value = EnsureImage(Name, Number, out FitsImage Result);

            if (!Value)
            {
                Map.Run(Argument, Pipeline, Result, Parameters);
            }

            Result.GetProperty <ImageSource>().AddToSet(Pipeline, Name);
            Pipeline = Result;
            LogHookImage(!Value, Name, Number);
        }
        public List <ImageDetection> RunDetector(Func <FitsImage, List <ImageDetection> > Detector, FitsImage Image, string DetectorName, DetectionAlgorithm Algo)
        {
            var Detections = Detector(Image);

            if (Detections.Count > MaxDetections)
            {
                LogMessage(DetectorName, "Too many detections. Check detector settings.");
                return(new List <ImageDetection>());
            }
            foreach (var d in Detections)
            {
                if (d.TryFetchProperty(out PairingProperties pp))
                {
                    pp.Algorithm = Algo;
                }
                else
                {
                    d.AppendProperty(new PairingProperties()
                    {
                        Algorithm = Algo
                    });
                }
            }

            AllDetections.AddRange(Detections);
            AllDetectionCenters.AddRange(Detections.Select((x) => x.Barycenter.EP));
            LogHookDetection(DetectorName, Detections.Count);
            return(Detections);
        }
Beispiel #5
0
        static ImageDetection Transform(ObsEntry Entry, FitsImage AssociatedImage)
        {
            EquatorialPoint eqp = new EquatorialPoint()
            {
                RA = Entry.RA / 180 * Math.PI, Dec = Entry.Dec / 180 * Math.PI
            };
            PixelPoint pp = new PixelPoint()
            {
                X = Entry.X, Y = Entry.Y
            };
            Position       p   = new Position(eqp, pp);
            ImageDetection det = new ImageDetection(p, AssociatedImage.GetProperty <ObservationTime>(), AssociatedImage);

            bool       Ellipse = false;
            ObjectSize sz      = new ObjectSize();

            if (Entry.A.HasValue && Entry.B.HasValue)
            {
                sz.PixelEllipse = new SourceEllipse()
                {
                    SemiaxisMajor = Entry.A.Value, SemiaxisMinor = Entry.B.Value
                };
                Ellipse = true;
            }
            else if (Entry.FWHM.HasValue && Entry.Ellipticity.HasValue)
            {
                sz.PixelEllipse = new SourceEllipse()
                {
                    SemiaxisMajor = Entry.FWHM.Value / Math.Sqrt(1 - Entry.Ellipticity.Value),
                    SemiaxisMinor = Entry.FWHM.Value * Math.Sqrt(1 - Entry.Ellipticity.Value),
                };
                Ellipse = true;
            }
            if (Ellipse)
            {
                if (Entry.EllipseTheta.HasValue)
                {
                    sz.PixelEllipse.SemiaxisMajorAngle = Entry.EllipseTheta.Value / 180 * Math.PI;
                }
                det.AppendProperty(sz);
            }

            PairingProperties pprop = new PairingProperties()
            {
                IsDotDetection = Ellipse && (sz.PixelEllipse.SemiaxisMajor < 2 * sz.PixelEllipse.SemiaxisMinor),
                IsPaired       = false,
                PearsonR       = 0,
                StarPolluted   = false,
                Algorithm      = DetectionAlgorithm.SourceExtractor
            };

            det.AppendProperty(pprop);
            if (Entry.Flux.HasValue)
            {
                ObjectPhotometry oph = new ObjectPhotometry()
                {
                    Flux = Entry.Flux.Value, Magnitude = Entry.Mag.Value
                };
                det.AppendProperty(oph);
            }

            return(det);
        }
        public List <Tracklet> AnalyzeCCD(PipelineArguments Args)
        {
            Logger("Setting up pipeline");
            /* Deal with incorrect SWARP flux scaling */
            SWarpScaling.ApplyTransform = CorrectSWARP;

            string RunDir = Args.RunDir;

            if (!Directory.Exists(RunDir))
            {
                Directory.CreateDirectory(RunDir);
            }

            /* Read input images and preprocess for poisson noise */
            int ImageCount = Args.Inputs.Length;

            FitsImage[] FirstProcess = new FitsImage[ImageCount];
            double[]    PFW          = PipelineHelperFunctions.LinearizedPoissonKernel(PoissonRadius);

            Step.StepPipeline sp = new Step.StepPipeline(StandardBITPIX, RunDir, Args.Inputs.Length, MaxDetections);
            sp.LogHookImage     = LogImage;
            sp.LogHookDetection = LogDet;
            sp.LogMessage       = LogMessage;

            bool HasBadpix = Args.Badpixel != null;

            Logger("Begining to run the pipeline");
            var zpTask = System.Threading.Tasks.Task <Dictionary <IO.Image, double> > .Factory.StartNew(() => CalibrateZP(Args.Inputs));

            var skTask = System.Threading.Tasks.Task <bool> .Factory.StartNew(() => PrecacheSkyBot(Args.Inputs));

            BitArray[] map = PipelineHelperFunctions.ExtractBadpixel(Args.Badpixel, Logger);

            for (int i = 0; i < ImageCount; i++)
            {
                FitsImage Pipeline = Args.Inputs[i];
                Pipeline.GetProperty <ImageSource>().AddToSet(Pipeline, "Original");
                sp.SetModel(i, Pipeline, new List <IO.ImageProperties>()
                {
                    Pipeline.GetProperty <ObservationTime>()
                });

                if (!UseCoreFilter)
                {
                    sp.RunPipeline(RestrictedMean.RestrictedMeanFilter, "Poisson", i, ref Pipeline, PFW, RestrictedMean.Parameters(PoissonRadius));
                }
                else if (HasBadpix)
                {
                    sp.RunPipeline(CoreFilter.Filter, "Poisson", i, ref Pipeline, new CoreFilter.CoreFilterParameters(PFW, map), CoreFilter.Parameters(PoissonRadius));
                }
                else
                {
                    throw new ArgumentException("Must specify Badpixel files if trying to run with CoreFilter");
                }

                if (Operations.HasFlag(EnabledOperations.Normalization))
                {
                    if (!sp.EnsureImage("Normalized", i, out FitsImage Normalized))
                    {
                        Point4Distance p4d = new Point4Distance(Pipeline, Normalized, NormalizationMeshSize);
                        Logger("Generated Normalized image " + i);
                    }
                    else
                    {
                        Logger("Found Normalized image " + i);
                    }
                    Normalized.GetProperty <ImageSource>().AddToSet(Args.Inputs[i], "Normalized");
                    Pipeline = Normalized;
                }
                FirstProcess[i] = Pipeline;
            }

            /* Create the central median */
            string CentralPath = Path.Combine(RunDir, "Central.fits");

            if (!sp.EnsureCentralImage("Central", out FitsImage Central))
            {
                HardMedians.MultiImageMedian.Run(null, FirstProcess, Central, HardMedians.MultiImageMedianParameters);
                Logger("Generated Central image");
            }
            else
            {
                Logger("Found Central image");
            }

            Logger("Computed the multi-image median");

            /* Prepare the mask, slow object detector, trail detector, weights for second median filtering, etc. */
            ImageStatistics CentralStats = new ImageStatistics(Central);

            if (Args.Clipped)
            {
                CentralStats = new ImageStatistics(Central, CentralStats.ZeroLevel, 2 * CentralStats.StDev);
            }
            StarData StarList = new StarData();

            ComputeDetectorData(Central, CentralStats, StarList, out MaskByMedian.MaskProperties MaskProp, out DotDetector SlowDetector,
                                out LongTrailDetector.LongTrailData LTD);
            if (Args.Clipped)
            {
                SlowDetector.HighThresholdMultiplier *= 2;
                SlowDetector.LowThresholdMultiplier  *= 2;
            }

            DetectionReducer dr = new DetectionReducer()
            {
                PairingRadius = 0.7
            };

            if (Operations.HasFlag(EnabledOperations.SourceExtractor))
            {
                try
                {
                    dr.LoadStars(StarList.FixedStarList);
                }
                catch (Exception ex) { throw new ArgumentException("Could not read detections from SE catalog.", ex); }
                dr.GeneratePool();
            }


            Logger("Set up detectors");

            List <ImageDetection> FullDetectionsList = new List <ImageDetection>();

            double[] FMW2 = PipelineHelperFunctions.LinearizedMedianKernel();
            LTLimit  ltl  = new LTLimit()
            {
                MinPix = TrailMinPix
            };
            RipFilter rf = new RipFilter()
            {
                SigmaTop = 30
            };

            Logger("Ready for final image processing and detection");

            for (int i = 0; i < ImageCount; i++)
            {
                List <ImageDetection> LocalDetectionList = new List <ImageDetection>();

                FitsImage DetectionSource = FirstProcess[i];

                if (Operations.HasFlag(EnabledOperations.Masking))
                {
                    sp.RunPipeline(MaskByMedian.Masker, "Masked", i, ref DetectionSource, MaskProp, MaskByMedian.Parameters);
                }

                if (Operations.HasFlag(EnabledOperations.SecondMedian))
                {
                    sp.RunPipeline(HardMedians.WeightedMedian, "Second Median", i, ref DetectionSource, FMW2, HardMedians.WeightedMedianParameters(SecMedRadius));
                }

                ImageStatistics SecMedStat = new ImageStatistics(DetectionSource);

                if (Operations.HasFlag(EnabledOperations.LongTrailDetector))
                {
                    var Dets = sp.RunDetector((FitsImage img) =>
                    {
                        LongTrailDetector.PrepareAlgorithmForImage(img, SecMedStat, ref LTD);
                        LongTrailDetector.Algorithm.Run(LTD, DetectionSource, LongTrailDetector.Parameters);
                        return(LTD.Results);
                    }, DetectionSource, "Trail", DetectionAlgorithm.Trail);
                    LocalDetectionList.AddRange(Dets);
                }

                if (Operations.HasFlag(EnabledOperations.BlobDetector))
                {
                    var Dets = sp.RunDetector(SlowDetector.Detect, DetectionSource, "Blob", DetectionAlgorithm.Blob);
                    LocalDetectionList.AddRange(Dets);
                }

                if (Operations.HasFlag(EnabledOperations.SourceExtractor))
                {
                    var dts = sp.RunDetector((arg) =>
                    {
                        List <ImageDetection> Dets = ExtraIO.SourceExtractor.ParseSEFile(Args.CatalogData[i], Args.Inputs[i]);
                        Dets   = Dets.Where((x) => x.FetchProperty <ObjectPhotometry>().Flux > 300).ToList();
                        var ND = dr.Reduce(Dets);
                        return(ND);
                    }, DetectionSource, "SE", DetectionAlgorithm.SourceExtractor);
                    LocalDetectionList.AddRange(dts);
                }

                if (Operations.HasFlag(EnabledOperations.OutputDetectionMap))
                {
                    DetectionDebugMap(RunDir, i, LocalDetectionList, DetectionSource);
                }

                rf.ImgMean  = SecMedStat.ZeroLevel;
                rf.ImgSigma = SecMedStat.StDev;
                var NLDL = sp.RunFilters(LocalDetectionList, "LocalToGlobal", ltl, rf);
                Logger("Total " + NLDL.Count + " detections.");
                FullDetectionsList.AddRange(NLDL);
            }
            Logger("Filtering and pairing detections...");

            LinearityThresholdFilter LTF = new LinearityThresholdFilter()
            {
                MaxLineThickness = MaxLineThickness
            };
            List <ImageDetection> FilteredDetections = sp.RunFilters(FullDetectionsList, "MainFilter", LTF);

            StarList.MarkStarCrossed(FilteredDetections, StarCrossRadiusM, StarCrossMinFlux);
            if (Args.CCDBadzone != null)
            {
                FilteredDetections = sp.RunFilters(FilteredDetections, "Badzone", Args.CCDBadzone);
            }

            Logger("Before PrePair " + FilteredDetections.Count);
            PrePair.MatchDetections(FilteredDetections, MaxPairmatchDistance, MixMatch, SameArcSep);

            Logger("Left with " + FilteredDetections.Count + " detections");
            LinePoolSimple lps = new LinePoolSimple()
            {
                MaxLinErrorArcSec = MaxResidual, SearchExtraSmall = SmallExtraSearchRadius, SearchExtraBig = BigExtraSearchRadius
            };

            lps.LoadDetections(FilteredDetections);

            lps.GeneratePool();
            var Pairings = lps.FindTracklets();

            sp.NotePairings(FilteredDetections, Pairings);

            Logger("Found " + Pairings.Count + " raw tracklets");

            LinearityTest lintest = new LinearityTest();
            StaticFilter  stf     = new StaticFilter();
            TotalError    te      = new TotalError();
            var           TK2List = sp.RunFilters(Pairings, "Tracklet Filtering", stf, te);

            Logger("After filtering: " + TK2List.Count + " candidate objects found");

            sp.LogDetections(Path.Combine(RunDir, "detlog.txt"));

            Dictionary <IO.Image, double> ZP = zpTask.Result;

            skTask.Wait();

            var Recovered = RecoverTracklets(TK2List, Args.Inputs, Path.Combine(RunDir, "reclog.txt"), ZP);

            TrackletsDeduplication.Deduplicate(Recovered, 1.0);

            Logger("Recovered " + Recovered.Count + " candidate objects");

            PairSkyBot(Recovered, SkyBoTDistance, Args.FieldName, Args.CCDNumber, Args.Inputs, sp);

            return(Recovered);
        }