dfcc30cdb7e4d1afe1ea106162e294791eb64e76 chmalee Mon Jun 29 16:54:03 2020 -0700 Fix 'trio' ordering bug when there is only one parent and we are drawing in child,parent order, refs #25813 diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c index e2d02f6..f495b74 100644 --- src/hg/hgTracks/vcfTrack.c +++ src/hg/hgTracks/vcfTrack.c @@ -1728,53 +1728,69 @@ } static void fillOutHapOrder(unsigned int *hapOrder, unsigned int hapCount, struct hapDistanceMatrixCell *c1, struct hapDistanceMatrixCell *c2, char **sampleDrawOrder) /* Assign indices to hapOrder in the order we should draw the alleles. Allows for the second parent * cell to be NULL */ { if (c1 == NULL) errAbort("Error: fillOutHapOrder passed NULL parent"); int numSamplesToDraw = hapCount / 2; char *childSampleName = c1->otherId; int childIx = stringArrayIx(childSampleName, sampleDrawOrder, numSamplesToDraw); int i; for (i = 0; i < numSamplesToDraw; i++) { char *thisSample = sampleDrawOrder[i]; - struct hapDistanceMatrixCell *thisCell = c2 != NULL && sameString(c2->sampleId,thisSample) ? c2 : c1; short hapIx = 2*i; if (i != childIx) // fill out the parent indices, which may be above or below the child { + struct hapDistanceMatrixCell *thisCell = c2 != NULL && sameString(c2->sampleId,thisSample) ? c2 : c1; if (i < childIx) { hapOrder[hapIx] = toggleInt(thisCell->alleleIx); hapOrder[hapIx+1] = thisCell->alleleIx; } else // below the child { hapOrder[hapIx] = thisCell->alleleIx; hapOrder[hapIx+1] = toggleInt(thisCell->alleleIx); } } else // fill out the child indices { + if (i == 0) + { + if (c2) + hapOrder[hapIx] = c2->otherAlleleIx; + else + hapOrder[hapIx] = toggleInt(c1->otherAlleleIx); + hapOrder[hapIx+1] = c1->otherAlleleIx; + } + else if (i == 1) + { hapOrder[hapIx] = c1->otherAlleleIx; if (c2) hapOrder[hapIx+1] = c2->otherAlleleIx; else hapOrder[hapIx+1] = toggleInt(c1->otherAlleleIx); } + else + { + hapOrder[hapIx] = c2->otherAlleleIx; + hapOrder[hapIx+1] = c1->otherAlleleIx; + } + } } } static void maybeRollBackCell(struct hapDistanceMatrixCell *c1, struct hapDistanceMatrixCell *c2, struct hapDistanceMatrixCell *c1Copy, struct hapDistanceMatrixCell *c2Copy) /* At this point c1->otherAlleleIx != c2->otherAlleleIx, however, it may be the case that c2 has a * better scoring match to c1->otherAlleleIx, so try to find it and reset the values */ { struct hapDistanceMatrixCell *tmp = c2; while (tmp->otherAlleleIx != c1->otherAlleleIx) tmp = tmp->next; if (tmp->dist < c1->dist) { *c2 = *tmp; *c1 = *c1Copy; @@ -1976,51 +1992,57 @@ } #define VCFPHASED_UNPHASED_COLOR MG_RED static int getChildAlleleColor(struct track *track, struct vcfRecord *rec, int childHapIx, int alleleIx, int nameIx, int gtHapCount, unsigned int *gtHapOrder, char *sampleOrder[]) /* Return the color we should use for this variant, depending on whether the allele * of the child matches what the parent transmitted or if there was some kind of * 'mendelian inconsistency' */ { // if there are no parents to draw then no concept of transmitted vs unstransmitted if (gtHapCount <= 2) return MG_BLACK; -int parIx = 0; +int parIx = alleleIx; +int numSamples = gtHapCount / 2; +boolean isEven = (alleleIx % 2) == 0; +const int adjacentLineSet = 1; +// how many haplotype "lines" away is the second parent if we are drawing in either +// parent1,parent2,child or child,parent1,parent2 order: +const int otherLineSet = 4; if (nameIx == 0) { - if (alleleIx % 2 == 0) - parIx = alleleIx + 2; - else - parIx = alleleIx + 3; + if (!isEven) + parIx = alleleIx + adjacentLineSet; + else if (numSamples > 2) + parIx = alleleIx + otherLineSet; } else if (nameIx == 1) { - if (alleleIx % 2 == 0) - parIx = alleleIx - 1; - else - parIx = alleleIx + 1; + if (isEven) + parIx = alleleIx - adjacentLineSet; + else if (numSamples > 2) // don't compare the allele the child to a missing parent + parIx = alleleIx + adjacentLineSet; } else { - if (alleleIx % 2 == 0) - parIx = alleleIx - 3; + if (isEven) + parIx = alleleIx - adjacentLineSet; else - parIx = alleleIx - 2; + parIx = alleleIx - otherLineSet; } struct vcfGenotype *parentGt = &(rec->genotypes[gtHapOrder[parIx] >> 1]); if (parentGt->isPhased || (parentGt->hapIxA == 1 && parentGt->hapIxB == 1)) { int parentAlleleIx = gtHapOrder[parIx] & 1 ? parentGt->hapIxB : parentGt->hapIxA; if (rec->alleles[childHapIx] != rec->alleles[parentAlleleIx]) // if they disagree mark as red return MG_RED; else return MG_BLACK; } return MG_BLACK; } void vcfPhasedDrawOneRecord(struct track *track, struct hvGfx *hvg, struct vcfRecord *rec, void *item, unsigned int *gtHapOrder, int gtHapCount, int xOff, int yOffsets[],