Skip to content

Commit 92c8a2d

Browse files
authored
Merge pull request #11 from as2110/main
update parasail syntax for clarity
2 parents e2ba4e3 + de9a799 commit 92c8a2d

2 files changed

Lines changed: 42 additions & 29 deletions

File tree

src/split_fastqcats/python/fastq_splitter_by_index.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def smith_waterman_search(self, sequence: str, record_id: str, errors: Union[int
120120

121121
# Perform Parasail alignment
122122
alignment = parasail.sw_trace_striped_16(
123-
window, pattern,
123+
pattern, window,
124124
self.open_gap_score, # Gap opening penalty
125125
self.extend_gap_score, # Gap extension penalty
126126
scoring_matrix
@@ -129,42 +129,44 @@ def smith_waterman_search(self, sequence: str, record_id: str, errors: Union[int
129129

130130
# **Check if alignment score is valid**
131131
if alignment is None or alignment.score is None:
132-
print(alignment)
132+
#print(alignment)
133133
continue # Skip this pattern if alignment failed
134134

135135

136136
# Ensure start position is valid
137-
start_position = max(0, alignment.end_query - pattern_length + 1 + start)
138-
end_position = min(len(sequence), start_position + pattern_length)
137+
aligned_ref = alignment.traceback.ref
138+
aligned_ref_length = len(aligned_ref.replace("-", ""))
139+
start_position = max(0, alignment.end_ref - aligned_ref_length + 1 + start)
140+
end_position = min(len(sequence), start + alignment.end_ref + 1)
139141

140142

141143
# Create a unique identifier for each match
142-
match_key = (pattern, start_position)
143-
144+
#match_key = (pattern, start_position)
145+
match_key = (pattern, start_position, end_position, aligned_ref_length, alignment.score)
144146
# Avoid adding duplicates
145147
if match_key in seen_matches:
146148
continue # Skip duplicates
147149

148150
# Otherwise, add to results
149-
seen_matches.add(match_key)
151+
#seen_matches.add(match_key)
150152

151153
# Allow a maximum of `max_mismatches` mismatches (including gaps)
152154
if alignment.score >= min_score_threshold:
153155

154156
# Extract actual alignment details
155-
aligned_query = alignment.traceback.query
156-
aligned_pattern = alignment.traceback.ref
157+
aligned_ref = alignment.traceback.ref
158+
aligned_pattern = alignment.traceback.query
157159

158160
# Count mismatches and gaps
159161
#counts mismatches and gaps together
160-
mismatches = sum(1 for a, b in zip(aligned_query, aligned_pattern) if a != b)
162+
mismatches = sum(1 for a, b in zip(aligned_ref, aligned_pattern) if a != b)
161163

162164
#counts mismatch and gaps separately
163-
#mismatches = sum(1 for q, p in zip(aligned_query, aligned_pattern) if q != p and q != '-' and p != '-')
164-
gaps = aligned_query.count('-') + aligned_pattern.count('-')
165+
#mismatches = sum(1 for q, p in zip(aligned_ref, aligned_pattern) if q != p and q != '-' and p != '-')
166+
gaps = aligned_ref.count('-') + aligned_pattern.count('-')
165167

166168
if mismatches <= max_mismatches:
167-
#print(f"DEBUG: Record={record_id}, Pattern={pattern}, Start={start_position}, Mismatches={mismatches}, Score={alignment.score}")
169+
seen_matches.add(match_key)
168170
log_message(f"Record={record_id}, Pattern={pattern}, Start={start_position+start}, Mismatches={mismatches}, Score={alignment.score}", logging.DEBUG)
169171

170172
best_matches.append({

src/split_fastqcats/python/fastq_splitter_by_primer.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
##Edits to Adam and Beth's main 'fastq_splitter_editted.py' script
2-
# - Reverse complement polyT sequences
1+
##Edits to Adam and Beth's main 'fastq_splitter_editted.py' script
2+
# - Reverse complement polyT sequences
33
# - Remove UMI based QC processing - UMI can be dealt with by the tallytrin count pipeline
44
# - Filters reads without polyA
55
# . Error tolerance - -e parameter set number of mismatches/error tolerance - 0.3-0.4 seems to be a reasonable sensitivty for current test reads
@@ -141,7 +141,7 @@ def smith_waterman_search(self, sequence: str, read_name: str, primer: str, erro
141141

142142
# Perform Parasail alignment
143143
alignment = parasail.sw_trace_striped_16(
144-
window, search_primer,
144+
search_primer, window,
145145
self.open_gap_score, # Gap opening penalty
146146
self.extend_gap_score, # Gap extension penalty
147147
scoring_matrix
@@ -153,35 +153,40 @@ def smith_waterman_search(self, sequence: str, read_name: str, primer: str, erro
153153
continue # Skip this pattern if alignment failed
154154

155155
# Ensure start position is valid
156-
start_position = max(0, alignment.end_query - pattern_length + 1 + start)
157-
end_position = min(len(sequence), start_position + pattern_length)
156+
aligned_ref = alignment.traceback.ref
157+
aligned_ref_length = len(aligned_ref.replace("-", ""))
158+
start_position = max(0, alignment.end_ref - aligned_ref_length + 1 + start)
159+
end_position = min(len(sequence), start + alignment.end_ref + 1)
158160

159161
# Create a unique identifier for each match
160-
match_key = (search_primer, start_position)
162+
match_key = (search_primer, start_position, end_position, aligned_ref_length, alignment.score)
161163

162164
# Avoid adding duplicates
163165
if match_key in seen_matches:
164166
continue # Skip duplicates
165167

166-
# Otherwise, add to results
167-
seen_matches.add(match_key)
168+
# Otherwise, add to results - moving this to add only hits that pass threshold
169+
#seen_matches.add(match_key)
168170

169171
if alignment.score >= min_score_threshold:
170172
# Extract actual alignment details
171-
aligned_query = alignment.traceback.query
172-
aligned_pattern = alignment.traceback.ref
173+
aligned_ref = alignment.traceback.ref
174+
aligned_pattern = alignment.traceback.query
173175

174176
# Count mismatches and gaps
175177

176178
#counts mismatches and gaps together
177-
mismatches = sum(1 for a, b in zip(aligned_query, aligned_pattern) if a != b)
179+
mismatches = sum(1 for a, b in zip(aligned_ref, aligned_pattern) if a != b)
178180

179-
#counts mismatch and gaps separately
180-
#mismatches = sum(1 for q, p in zip(aligned_query, aligned_pattern) if q != p and q != '-' and p != '-')
181-
gaps = aligned_query.count('-') + aligned_pattern.count('-')
181+
#counts mismatch and gaps separately - can be uncommented if wanting to report separately
182+
#mismatches = sum(1 for q, p in zip(aligned_ref, aligned_pattern) if q != p and q != '-' and p != '-')
183+
gaps = aligned_ref.count('-') + aligned_pattern.count('-')
182184

183-
185+
# note - max_mismatches here is mismatches + gaps together.
184186
if mismatches <= max_mismatches:
187+
# Add match positions to seen matches to avoid duplication in future searches
188+
seen_matches.add(match_key)
189+
# Take match params for next step
185190
matches.append({
186191
'start': start_position,
187192
'end': end_position,
@@ -460,7 +465,13 @@ def parallel_split_reads(self, input_file: str, processed_output: str, lowqual_o
460465
bin_output: Output path for binned reads
461466
stats_output: Output path for statistics
462467
"""
463-
468+
stats = {
469+
'total_sequences': 0,
470+
'total_segments': 0,
471+
'processed': 0,
472+
'lowqual': 0,
473+
'binned': 0
474+
}
464475
stats = {
465476
'total_reads': 0,
466477
'processed_reads': 0,

0 commit comments

Comments
 (0)