public void GetAndLinkAllClassificationBlocksWithEcFinalization()
        {
            var geminiOptions       = new GeminiOptions();
            var chrom               = "chr1";
            var tracker             = new ConcurrentDictionary <string, int>();
            var categoryLookup      = new ConcurrentDictionary <PairClassification, int>();
            var mockWriterSource    = new Mock <IWriterSource>();
            var actionBlockProvider = new PairResultActionBlockFactoryProvider(mockWriterSource.Object, false, false,
                                                                               "chr1", 1, 1, false, 500, tracker, categoryLookup);
            var chrReference   = new ChrReference();
            var realignFactory = new BamRealignmentFactory(geminiOptions, new RealignmentAssessmentOptions(),
                                                           new StitcherOptions(), new RealignmentOptions(), "outdir");
            var gemFactory        = new GeminiFactory(geminiOptions, new IndelFilteringOptions());
            var dataSourceFactory = new Mock <IGeminiDataSourceFactory>();
            var dataOutputFactory = new Mock <IGeminiDataOutputFactory>();
            ConcurrentDictionary <string, IndelEvidence> masterIndelLOokup    = new ConcurrentDictionary <string, IndelEvidence>();
            ConcurrentDictionary <HashableIndel, int[]>  masterOutcomesLookup = new ConcurrentDictionary <HashableIndel, int[]>();
            ConcurrentDictionary <HashableIndel, int>    masterFinalIndels    = new ConcurrentDictionary <HashableIndel, int>();
            var binEvidenceFactory = new BinEvidenceFactory(geminiOptions, new GeminiSampleOptions());
            var catsForRealign     = new List <PairClassification>();

            var aggRegionProcessor = new AggregateRegionProcessor(chrReference,
                                                                  new Dictionary <int, string>()
            {
                { 1, "chr1" }
            },
                                                                  realignFactory, geminiOptions, gemFactory, chrom, dataSourceFactory.Object, new RealignmentOptions(),
                                                                  masterIndelLOokup, masterOutcomesLookup, masterFinalIndels,
                                                                  catsForRealign, tracker);

            var provider = new ClassificationBlockProvider(geminiOptions, chrom, tracker, categoryLookup,
                                                           actionBlockProvider, aggRegionProcessor, false, new PairResultBatchBlockFactory(10), binEvidenceFactory,
                                                           catsForRealign, 1);


            var  sourceBlock = new Mock <ISourceBlock <PairResult> >();
            bool consumed;

            sourceBlock.Setup(x => x.ConsumeMessage(It.IsAny <DataflowMessageHeader>(),
                                                    It.IsAny <ITargetBlock <PairResult> >(), out consumed)).Returns(new PairResult());
            ConcurrentDictionary <int, EdgeState> edgeStates   = new ConcurrentDictionary <int, EdgeState>();
            ConcurrentDictionary <int, Task>      edgeToWaitOn = new ConcurrentDictionary <int, Task>();

            provider.GetAndLinkAllClassificationBlocksWithEcFinalization(sourceBlock.Object, 1000, 2000, edgeStates,
                                                                         edgeToWaitOn, 0, false);
        }
        public void GetAggregateRegionResults()
        {
            var          geminiOptions = new GeminiOptions();
            ChrReference chrReference  = null;
            var          refIdMapping  = new Dictionary <int, string>()
            {
                { 1, "chr1" }
            };
            var bamRealignmentFactory = new BamRealignmentFactory(new GeminiOptions(),
                                                                  new RealignmentAssessmentOptions(), new StitcherOptions(), new RealignmentOptions(), "out");

            var geminiFactory         = new GeminiFactory(geminiOptions, new IndelFilteringOptions());
            var dataSourceFactoryMock = new Mock <IGeminiDataSourceFactory>();
            var chromIndelSource      = new Mock <IChromosomeIndelSource>();

            //var indel = new KeyValuePair<HashableIndel, GenomeSnippet>();
            chromIndelSource
            .Setup(x => x.GetRelevantIndels(It.IsAny <int>(), It.IsAny <List <PreIndel> >(),
                                            It.IsAny <List <HashableIndel> >(), It.IsAny <List <PreIndel> >(), It.IsAny <List <PreIndel> >())).Returns(new List <KeyValuePair <HashableIndel, GenomeSnippet> >()
            {
                //indel
            });
            dataSourceFactoryMock
            .Setup(x => x.GetChromosomeIndelSource(It.IsAny <List <HashableIndel> >(),
                                                   It.IsAny <IGenomeSnippetSource>())).Returns(chromIndelSource.Object);
            var dataSourceFactory        = dataSourceFactoryMock.Object;
            var masterIndelLookup        = new ConcurrentDictionary <string, IndelEvidence>();
            var masterOutcomesLookup     = new ConcurrentDictionary <HashableIndel, int[]>();
            var masterFinalIndels        = new ConcurrentDictionary <HashableIndel, int>();
            var categoriesForRealignment = new List <PairClassification>();
            var progressTracker          = new ConcurrentDictionary <string, int>();

            var processor = new AggregateRegionProcessor(chrReference, refIdMapping, bamRealignmentFactory,
                                                         geminiOptions, geminiFactory, "chr1", dataSourceFactory, new RealignmentOptions()
            {
                CategoriesForSnowballing = new List <PairClassification>()
                {
                    PairClassification.Disagree
                }
            },
                                                         masterIndelLookup, masterOutcomesLookup, masterFinalIndels, categoriesForRealignment, progressTracker);

            var indelLookup     = new ConcurrentDictionary <string, IndelEvidence>();
            var binEvidence     = new BinEvidence(1, true, 20, false, 500, 1000);
            var edgeBinEvidence = new BinEvidence(1, true, 20, false, 500, 1000);
            var edgeState       = new EdgeState()
            {
                Name                 = "0-1000",
                EdgeAlignments       = new Dictionary <PairClassification, List <PairResult> >(),
                BinEvidence          = edgeBinEvidence,
                EdgeIndels           = new List <HashableIndel>(),
                EffectiveMinPosition = 0
            };

            var pairResultLookup =
                new ConcurrentDictionary <PairClassification, List <PairResult> >();

            pairResultLookup.TryAdd(PairClassification.Disagree, new List <PairResult>()
            {
                TestHelpers.GetPairResult(10000),
                TestHelpers.GetPairResult(10001),
                TestHelpers.GetPairResult(10002),
                TestHelpers.GetPairResult(19995)
            });
            pairResultLookup.TryAdd(PairClassification.SingleMismatchStitched, new List <PairResult>()
            {
                TestHelpers.GetPairResult(19995),
                TestHelpers.GetPairResult(19995)
            });

            // Borderline case: the max position in the pair is >= EffectiveMaxPosition - 5000, even if one of the reads in the pair is not
            var effectiveMax    = 19999;
            var r2BorderlinePos = effectiveMax - 5000 + 1;
            var offset          = 1;
            var r1BorderlinePos = r2BorderlinePos - offset;

            pairResultLookup.TryAdd(PairClassification.UnstitchForwardMessy, new List <PairResult>()
            {
                TestHelpers.GetPairResult(r1BorderlinePos, offset), // One is just over border
                TestHelpers.GetPairResult(r1BorderlinePos, 0),      // Both are within safe range
            });

            var regionData = new RegionDataForAggregation()
            {
                BinEvidence          = binEvidence,
                EdgeState            = edgeState,
                EffectiveMaxPosition = effectiveMax,
                EffectiveMinPosition = 10000,
                PairResultLookup     = pairResultLookup
            };
            var regionResults = processor.GetAggregateRegionResults(indelLookup,
                                                                    10000, 20000, false, regionData);

            // New edge state should have the correct items carrying over
            Assert.Equal("10000-20000", regionResults.EdgeState.Name);
            Assert.Equal(14999, regionResults.EdgeState.EffectiveMinPosition);
            Assert.Equal(4, regionResults.AlignmentsReadyToBeFlushed.Count); // The four that are solidly in-bounds should be flushable immediately

            var edgeAlignmentsLookup = regionResults.EdgeState.EdgeAlignments;

            Assert.Equal(1, edgeAlignmentsLookup[PairClassification.Disagree].Count);
            Assert.Equal(2, edgeAlignmentsLookup[PairClassification.SingleMismatchStitched].Count);
            Assert.Equal(1, edgeAlignmentsLookup[PairClassification.UnstitchForwardMessy].Count);
        }