File: SeedSequencer.cpp

package info (click to toggle)
snap-aligner 2.0.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,652 kB
  • sloc: cpp: 41,051; ansic: 5,239; python: 227; makefile: 85; sh: 28
file content (109 lines) | stat: -rw-r--r-- 2,867 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*++

Module Name:

    SeedSequencer.cpp

Abstract:

    Code for determining the order of seeds in a read.

Authors:

    Bill Bolosky, August, 2013

Environment:

    User mode service.

Revision History:

    
--*/

#include "stdafx.h"
#include "SeedSequencer.h"

static SeedSequencer *Sequencers[LargestSeedSize + 1];

void InitializeSeedSequencers()
{
    for (unsigned i = 1; i <= LargestSeedSize; i++) {
        Sequencers[i] = new SeedSequencer(i);
    }
}

SeedSequencer::SeedSequencer(unsigned i_seedSize) : seedSize(i_seedSize)
{
    offsets = new unsigned[seedSize];
    for (unsigned i = 0; i < seedSize; i++) {
        offsets[i] = 0;
    }

    if (seedSize == 1) return;  // Not that seed size 1 makes any sense or is in any way supported.  But it's in the array, so we generate it.

    struct WorkItem {
        unsigned lowerBound;
        unsigned upperBound;
        WorkItem    *next;
    };

    unsigned nFilledOffsets = 1;
    WorkItem *workItems = new WorkItem;
    WorkItem *tail = NULL;
    workItems->next = NULL;
    workItems->lowerBound = 1;
    workItems->upperBound = seedSize - 1;

    while (NULL != workItems) {
        WorkItem *itemToProcess = workItems;
        workItems = itemToProcess->next;
        if (NULL == workItems) {
            tail = NULL;
        }

        unsigned selectedLocation = (itemToProcess->lowerBound + itemToProcess->upperBound) / 2;
        _ASSERT(offsets[selectedLocation] == 0);
        offsets[selectedLocation] = nFilledOffsets;
        nFilledOffsets++;

        //
        // Add the upper half to the tail.  It will be the larger of the two if they're not equal, since / 2 rounds down.
        //
        if (itemToProcess->upperBound > selectedLocation) {
            WorkItem *upperItem = new WorkItem;
            upperItem->next = NULL;
            upperItem->upperBound = itemToProcess->upperBound;
            upperItem->lowerBound = selectedLocation + 1;

            //
            // Add it to the tail.
            //
            if (NULL != tail) {
                tail->next = upperItem;
                tail = upperItem;
            } else {
                _ASSERT(workItems == NULL);
                workItems = tail = upperItem;
            }
        }

        if (itemToProcess->lowerBound < selectedLocation) {
            _ASSERT(workItems != NULL); // We must have already added an upper half.
            itemToProcess->upperBound = selectedLocation - 1;
            itemToProcess->next = NULL;
            tail->next = itemToProcess;
            tail = itemToProcess;
        } else {
            delete itemToProcess;
        }
    }

    _ASSERT(nFilledOffsets == seedSize);
}

unsigned GetWrappedNextSeedToTest(unsigned seedLen, unsigned wrapCount) 
{
    _ASSERT(seedLen <= LargestSeedSize);
    return Sequencers[seedLen]->GetWrappedNextSeedToTest(wrapCount);
}