Skip to content

Commit 49ef7fd

Browse files
committed
AI coded rolling average
1 parent b283541 commit 49ef7fd

File tree

1 file changed

+67
-20
lines changed

1 file changed

+67
-20
lines changed

plugins/gccontent/src/GCContentAdapter/GCContentAdapter.ts

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,31 @@ export default class GCContentAdapter extends BaseFeatureDataAdapter {
6161
)
6262
const residues = feats[0]?.get('seq') || ''
6363

64-
let start = performance.now()
6564
await updateStatus('Calculating GC', statusCallback, () => {
65+
// Initialize the first window
66+
let nc = 0
67+
let ng = 0
68+
let len = 0
69+
let start = performance.now()
70+
71+
// Calculate initial window
72+
const startIdx = halfWindowSize
73+
for (
74+
let j = startIdx - halfWindowSize;
75+
j < startIdx + halfWindowSize;
76+
j++
77+
) {
78+
const letter = residues[j]
79+
if (letter === 'c' || letter === 'C') {
80+
nc++
81+
} else if (letter === 'g' || letter === 'G') {
82+
ng++
83+
}
84+
if (letter !== 'N') {
85+
len++
86+
}
87+
}
88+
6689
for (
6790
let i = halfWindowSize;
6891
i < residues.length - halfWindowSize;
@@ -72,22 +95,52 @@ export default class GCContentAdapter extends BaseFeatureDataAdapter {
7295
checkStopToken(stopToken)
7396
start = performance.now()
7497
}
75-
const r = isWindowSizeOneBp
76-
? residues[i]
77-
: residues.slice(i - halfWindowSize, i + halfWindowSize)
78-
let nc = 0
79-
let ng = 0
80-
let len = 0
81-
for (const letter of r) {
82-
if (letter === 'c' || letter === 'C') {
83-
nc++
84-
} else if (letter === 'g' || letter === 'G') {
85-
ng++
98+
99+
// For windowSize === 1, just get the single character
100+
if (isWindowSizeOneBp) {
101+
const letter = residues[i]
102+
nc = letter === 'c' || letter === 'C' ? 1 : 0
103+
ng = letter === 'g' || letter === 'G' ? 1 : 0
104+
len = letter !== 'N' ? 1 : 0
105+
} else if (i > halfWindowSize) {
106+
// Rolling window: remove characters that are no longer in window
107+
// and add new characters that entered the window
108+
const prevStart = i - windowDelta - halfWindowSize
109+
const prevEnd = i - windowDelta + halfWindowSize
110+
const currStart = i - halfWindowSize
111+
const currEnd = i + halfWindowSize
112+
113+
// Remove old characters
114+
for (let j = prevStart; j < Math.min(prevEnd, currStart); j++) {
115+
if (j >= 0 && j < residues.length) {
116+
const letter = residues[j]
117+
if (letter === 'c' || letter === 'C') {
118+
nc--
119+
} else if (letter === 'g' || letter === 'G') {
120+
ng--
121+
}
122+
if (letter !== 'N') {
123+
len--
124+
}
125+
}
86126
}
87-
if (letter !== 'N') {
88-
len++
127+
128+
// Add new characters
129+
for (let j = Math.max(prevEnd, currStart); j < currEnd; j++) {
130+
if (j >= 0 && j < residues.length) {
131+
const letter = residues[j]
132+
if (letter === 'c' || letter === 'C') {
133+
nc++
134+
} else if (letter === 'g' || letter === 'G') {
135+
ng++
136+
}
137+
if (letter !== 'N') {
138+
len++
139+
}
140+
}
89141
}
90142
}
143+
91144
const pos = qs
92145
const score =
93146
this.gcMode === 'content'
@@ -111,10 +164,4 @@ export default class GCContentAdapter extends BaseFeatureDataAdapter {
111164
observer.complete()
112165
})
113166
}
114-
115-
/**
116-
* called to provide a hint that data tied to a certain region
117-
* will not be needed for the foreseeable future and can be purged
118-
* from caches, etc
119-
*/
120167
}

0 commit comments

Comments
 (0)