private int WriteAnomalies(
            SourceMatchLists sourceMatchLists)
        {
            var anomalies = sourceMatchLists.Filter(Filter);
            var lines     = StringizePositions(anomalies);
            var path      = String.Format(OutputPath, "-anomalies.txt");

            File.WriteAllLines(path, lines);

            var text = WriteRegions(anomalies.PrimaryMatchedSources, Color1);

            path = String.Format(OutputPath, "-anomalies-wise.reg");
            File.WriteAllText(path, text);

            text = WriteRegions(anomalies.SecondaryMatchedSources, Color2);
            path = String.Format(OutputPath, "-anomalies-spitzer.reg");
            File.WriteAllText(path, text);

            return(Status);

            bool Filter(ISource primary, ISource secondary)
            {
                if (IsInRadius(primary, secondary, 5))
                {
                    return(false);
                }

                var snrSource = primary as ISnrSource;

                return(snrSource.SignalToNoise >= 20);
            }
        }
        public int Run()
        {
            if (ReadSourceLists() != 0)
            {
                return(Status);
            }

            if (FilterSourceLists() != 0)
            {
                return(Status);
            }

            var filteredMatchLists = new SourceMatchLists(
                Filtered,
                Spitzer,
                SearchRadius,
                Verbose);

            var unfilteredMatchLists = new SourceMatchLists(
                Unfiltered,
                Spitzer,
                SearchRadius,
                Verbose);

            var filteredCompleteness = GetFractionDictionary(
                filteredMatchLists.SecondaryMatchedSources,
                Spitzer);

            var unfilteredCompleteness = GetFractionDictionary(
                unfilteredMatchLists.SecondaryMatchedSources,
                Spitzer);

            var filteredReliability = GetFractionDictionary(
                filteredMatchLists.PrimaryMatchedSources,
                Filtered);

            var unfilteredReliability = GetFractionDictionary(
                unfilteredMatchLists.PrimaryMatchedSources,
                Unfiltered);

            File.WriteAllText(
                "filtered-completeness.txt",
                GetCompletenessTable(filteredCompleteness));

            File.WriteAllText(
                "unfiltered-completeness.txt",
                GetCompletenessTable(unfilteredCompleteness));

            File.WriteAllText(
                "filtered-reliability.txt",
                GetCompletenessTable(filteredReliability));

            File.WriteAllText(
                "unfiltered-reliability.txt",
                GetCompletenessTable(unfilteredReliability));

            return(Status);
        }
        private string[] StringizePositions(
            SourceMatchLists matches)
        {
            var lines = new string[matches.MatchCount + 1];

            lines[0] = "WISE ID\tWISE RA\tWISE Dec\tSpit. ID\tW1 Mag\t[3.6] Mag\tWISE SNR";
            if (Multithreaded)
            {
                Parallel.For(0, matches.MatchCount, WriteLine);
            }
            else
            {
                for (var i = 0; i < matches.MatchCount; i++)
                {
                    WriteLine(i);
                }
            }

            return(lines);

            void WriteLine(int index)
            {
                var source = matches.PrimaryMatchedSources[index];
                var wise   = source as MdexSource;
                var spit   = source as SpitzerSource;

                var wiseID    = wise.Id;
                var wiseRa    = wise.RA.Degrees;
                var wiseDec   = wise.Dec.Degrees;
                var spitId    = spit.Id;
                var wiseW1Mag = (double)wise[wise.Names["w1mag"]];
                var spitMag   = spit.Magnitude1;
                var wiseSnr   = wise.SignalToNoise;

                var sb = new StringBuilder();

                sb.Append(wiseID.ToString("000000"));
                sb.Append('\t');
                sb.Append(wiseRa.ToString("000.00000"));
                sb.Append('\t');
                sb.Append(wiseDec.ToString("000.00000"));
                sb.Append('\t');
                sb.Append(spitId.ToString("000000"));
                sb.Append('\t');
                sb.Append(wiseW1Mag.ToString("000.00000"));
                sb.Append('\t');
                sb.Append(spitMag.ToString("000.00000"));
                sb.Append('\t');
                sb.Append(wiseSnr.ToString("00.0000"));

                lines[index + 1] = sb.ToString();
            }
        }
        private int FilterBounds()
        {
            if (Verbose)
            {
                Console.WriteLine();
                Console.WriteLine("Calculating intersection of regions");
            }

            var bounds1 = SourceMatchLists.GetBounds(Filtered);
            var bounds2 = SourceMatchLists.GetBounds(Spitzer);

            var minRa = Angle.FromRadians(
                Max(bounds1.minRa.Radians, bounds2.minRa.Radians));

            var maxRa = Angle.FromRadians(
                Min(bounds1.maxRa.Radians, bounds2.maxRa.Radians));

            var minDec = Angle.FromRadians(
                Max(bounds1.minDec.Radians, bounds2.minDec.Radians));

            var maxDec = Angle.FromRadians(
                Min(bounds1.maxDec.Radians, bounds2.maxDec.Radians));

            if (Verbose)
            {
                Console.WriteLine("Min RA={0}", minRa);
                Console.WriteLine("Max RA={0}", maxRa);
                Console.WriteLine("Min Dec={0}", minDec);
                Console.WriteLine("Max Dec={0}", maxDec);

                Console.WriteLine();
                Console.WriteLine(
                    "Filtering source lists to bounded region.");
            }

            Filtered   = Filtered.Filter(InBounds);
            Unfiltered = Unfiltered.Filter(InBounds);
            Spitzer    = Spitzer.Filter(InBounds);

            return(Status);

            bool InBounds(ISource source)
            {
                return
                    (source.RA >= minRa &&
                     source.RA <= maxRa &&
                     source.Dec >= minDec &&
                     source.Dec <= maxDec);
            }
        }
        public int CompareFilteredAndUnfiltered()
        {
            if (ReadSourceLists() != 0)
            {
                return(Status);
            }

            if (FilterSourceLists() != 0)
            {
                return(Status);
            }

            var filtered = new SourceMatchLists(
                Filtered,
                Spitzer,
                SearchRadius,
                Verbose);

            var unfiltered = new SourceMatchLists(
                Unfiltered,
                Spitzer,
                SearchRadius,
                Verbose);

            var matchFiltered   = filtered.PrimaryMatchedSources;
            var matchUnfiltered = unfiltered.PrimaryMatchedSources;

            var mixed = new SourceMatchLists(
                matchFiltered,
                matchUnfiltered,
                SearchRadius * 4,
                Verbose);

            var lines = StringizePositions(filtered);

            File.WriteAllLines("filtered.txt", lines);

            lines = StringizePositions(unfiltered);
            File.WriteAllLines("unfiltered.txt", lines);

            return(Status);
        }
        private IReadOnlyDictionary <double, double> GetReliabilityBins(
            SourceMatchLists search,
            double startSnr,
            double endSnr,
            double width)
        {
            var primaryMatched   = search.PrimaryMatchedSources;
            var primaryUnmatched = search.PrimaryUnmatchedSources;

            var matched   = primaryMatched.CreateBins(startSnr, width);
            var unmatched = primaryUnmatched.CreateBins(startSnr, width);

            var bins = new Dictionary <double, double>();

            for (var snr = startSnr; snr <= endSnr; snr += width)
            {
                var matchedCount   = GetSize(matched);
                var unmatchedCount = GetSize(unmatched);
                var total          = matchedCount + unmatchedCount;
                var reliability    = (double)matchedCount / total;
                if (Double.IsNaN(reliability))
                {
                    reliability = -1;
                }

                bins.Add(snr, reliability);

                int GetSize(IReadOnlyDictionary <double, IReadOnlyCollection <ISource> > dictionary)
                {
                    if (dictionary.TryGetValue(snr, out var list))
                    {
                        return(list.Count);
                    }

                    return(0);
                }
            }

            return(bins);
        }