I have found an alternative solution that has been excellent for this paralog mapping issue, so I thought I'd post what I had worked on:
Question 1+2
I was wondering if there is a different approach to mapping I could take that would output all alignments for a read, and then specifically only multi-mapped reads?
Using blasr, pacbio specified some options in their github docs for long, nearly identical reads:
blasr input.bam /path/to/reference.fa --hitpolicy all --bam --out alignments.bam --minMatch 8 --maxMatch 15 --nproc 4
The link to the docs as to why this is useful is here, although I did tweak the parameters to smaller seed sizes to create more anchors to the reference, which produced more secondary alignments. This is effective because this will output up to 10 secondary alignments per read, which I saw quite frequently for my region of interest.
After this, sorting was accomplished using Picard SortSam, with the following flags:
java -jar picard.jar SortSam INPUT=${SAMPLE} OUTPUT=./sorted/${SAMPLE}\
SORT_ORDER=coordinate VALIDATION_STRINGENCY=LENIENT\
CREATE_INDEX=true MAX_RECORDS_IN_RAM=100000
The blasr files have much more information than normal sams produced by aligners like minimap2 and bwa mem, so the MAX_RECORDS_IN_RAM=100000 as opposed to 500000 helps to ensure less frequent job failures (this was done on a cluster).
Next, I parsed out the region of interest:
samtools view -h input.bam "chrX:1000-2000" > extracted.bam # this is fake
Parse out mapq=0 reads:
awk '$5==0' extracted.bam > mapq0.txt
Get read names to grep for later:
awk '{print $1}' mapq0.txt > read_names_mapq0.txt
Search for all reads with readname from the original bam to get mapping positions:
samtools view infile.bam | grep -f read_names_mapq0.txt > all_reads_mapq0_mapq_high.txt
Keep only columns: 1) read_name, 2) Sam Flag, 3) Chr, 4) Pos, 5) MapQ:
awk '{print $1,$2,$3,$4,$5}' OFS='\t' all_reads_mapq0_mapq_high.txt > mapq_read_info.txt
Then I wrote a simple python script to sort by read name, count the number of times a read shows up, and see all the positions it maps to. An example of the output:
Read_Name Flag Chr Pos MAPQ
read1/10158955/ccs 272 19 3395674 0
read1/10158955/ccs 0 16 217682 254
read1/10158955/ccs 272 12 64990527 0
read1/10158955/ccs 256 16 222913 0
read1/10158955/ccs 272 19 21328060 0
read1/10158955/ccs 256 19 3224052 0
read1/10158955/ccs 272 17 34878621 0
read1/10158955/ccs 272 16 84204312 0
read1/10158955/ccs 256 1 244788680 0
read1/10158955/ccs 272 2 222951342 0
read2/10223868/ccs 16 16 217057 254
read2/10223868/ccs 256 20 3078724 0
read2/10223868/ccs 272 6 133521134 0
read2/10223868/ccs 256 7 152515722 0
read2/10223868/ccs 256 21 45258117 0
read2/10223868/ccs 256 1 249160685 0
read2/10223868/ccs 272 16 223631 0
read3/10551872/ccs 272 GL000220.1 144982 0
read3/10551872/ccs 256 18 72831954 0
...
read_counts output:
Read_Name Flag Chr Pos MAPQ
read1/10158955/ccs 10 10 10 10
read2/10223868/ccs 7 7 7 7
read3/10551872/ccs 9 9 9 9
The numbers in each column correspond to the number of supplementary reads seen.
A brief explanation of sam flags which I feel is relevant for unpaired reads:
Flag=0: read was mapped to + strand
Flag=16: read was mapped to - strand
Flag=256: read was mapped to + as secondary alignment
Flag=272: read was mapped to - as secondary alignment